

"""simple docstring"""






from __future__ import annotations
def       UpperCamelCase					(			_lowerCAmelCase     :						List[str] )				->			int:
	global graph, reversed_graph, scc, component, visit, stack
	if visit[u]:
		return
	_UpperCAmelCase    :							str									=					True
	for v in graph[u]:
		dfs(_lowerCAmelCase )
	stack.append(_lowerCAmelCase )
def       UpperCamelCase					(			_lowerCAmelCase     :						List[Any] )				->			List[str]:
	global graph, reversed_graph, scc, component, visit, stack
	if visit[u]:
		return
	_UpperCAmelCase    :							str									=					True
	component.append(_lowerCAmelCase )
	for v in reversed_graph[u]:
		dfsa(_lowerCAmelCase )
def       UpperCamelCase					(			)				->			Dict:
	global graph, reversed_graph, scc, component, visit, stack
	for i in range(_lowerCAmelCase ):
		dfs(_lowerCAmelCase )
	_UpperCAmelCase    :							int									=					[False] * n
	for i in stack[::-1]:
		if visit[i]:
			continue
		_UpperCAmelCase    :							Union[str, Any]									=					[]
		dfsa(_lowerCAmelCase )
		scc.append(_lowerCAmelCase )
	return scc


if __name__ == "__main__":
						# n - no of nodes, m - no of edges
						lowerCamelCase__				:  int													=  list(map(int, input().strip().split()))

						lowerCamelCase__				:  list[list[int]]													=  [[] for _ in range(n)]  # graph
						lowerCamelCase__				:  list[list[int]]													=  [[] for i in range(n)]  # reversed graph
						# input graph data (edges)
						for _ in range(m):
												lowerCamelCase__				:  int													=  list(map(int, input().strip().split()))
												graph[u].append(v)
												reversed_graph[v].append(u)

						lowerCamelCase__				:  list[int]													=  []
						lowerCamelCase__				:  list[bool]													=  [False] * n
						lowerCamelCase__				:  list[int]													=  []
						lowerCamelCase__				:  list[int]													=  []
						print(kosaraju())



"""simple docstring"""






from __future__ import annotations
def       UpperCamelCase					(			_lowerCAmelCase     :						list,  _lowerCAmelCase     :						list )				->			list:
	_UpperCAmelCase    :							List[Any]									=					[None] * (len(_lowerCAmelCase ) + len(_lowerCAmelCase ))

	_UpperCAmelCase    :							Union[str, Any]									=					0  # pointer to current index for left Half
	_UpperCAmelCase    :							str									=					0  # pointer to current index for the right Half
	_UpperCAmelCase    :							Optional[int]									=					0  # pointer to current index for the sorted array Half

	while pointera < len(_lowerCAmelCase ) and pointera < len(_lowerCAmelCase ):
		if left_half[pointera] < right_half[pointera]:
			_UpperCAmelCase    :							Tuple									=					left_half[pointera]
			pointera += 1
			index += 1
		else:
			_UpperCAmelCase    :							int									=					right_half[pointera]
			pointera += 1
			index += 1
	while pointera < len(_lowerCAmelCase ):
		_UpperCAmelCase    :							Tuple									=					left_half[pointera]
		pointera += 1
		index += 1

	while pointera < len(_lowerCAmelCase ):
		_UpperCAmelCase    :							Union[str, Any]									=					right_half[pointera]
		pointera += 1
		index += 1

	return sorted_array
def       UpperCamelCase					(			_lowerCAmelCase     :						list )				->			list:
	if len(_lowerCAmelCase ) <= 1:
		return array
	# the actual formula to calculate the middle element = left + (right - left) // 2
	# this avoids integer overflow in case of large N
	_UpperCAmelCase    :							Any									=					0 + (len(_lowerCAmelCase ) - 0) // 2

	# Split the array into halves till the array length becomes equal to One
	# merge the arrays of single length returned by mergeSort function and
	# pass them into the merge arrays function which merges the array
	_UpperCAmelCase    :							Optional[Any]									=					array[:middle]
	_UpperCAmelCase    :							Optional[int]									=					array[middle:]

	return merge(merge_sort(_lowerCAmelCase ),  merge_sort(_lowerCAmelCase ) )


if __name__ == "__main__":
						import doctest

						doctest.testmod()





