'''simple docstring'''




from __future__ import annotations

import random
from collections.abc import Iterable
from typing import Any, Generic, TypeVar

_lowercase		:					str													=		TypeVar("T", bound=bool)





class        __magic_name__		(       Generic[T]):







			def __init__(      self							:    Union[str, Any]							,     lowercase_							:    T       ):
										lowercase_   :     T									=			value
										lowercase_   :     RandomizedHeapNode[T] | None									=			None
										lowercase_   :     RandomizedHeapNode[T] | None									=			None







			@property
			def       SCREAMING_SNAKE_CASE_	(      self							:    Any       ):
										return self._value







			@staticmethod
			def       SCREAMING_SNAKE_CASE_	(      lowercase_							:    RandomizedHeapNode[T] | None							,     lowercase_							:    RandomizedHeapNode[T] | None       ):
										if not roota:
																	return roota

										if not roota:
																	return roota

										if roota.value > roota.value:
																	lowercase_		,		lowercase_   :     List[str]									=			roota, roota

										if random.choice([True, False]       ):
																	lowercase_		,		lowercase_   :     str									=			roota.right, roota.left

										lowercase_   :     str									=			RandomizedHeapNode.merge(roota.left							,     lowercase_       )

										return roota





class        __magic_name__		(       Generic[T]):







			def __init__(      self							:    int							,     lowercase_							:    Iterable[T] | None = ()       ):
										lowercase_   :     RandomizedHeapNode[T] | None									=			None

										if data:
																	for item in data:
																								self.insert(lowercase_       )







			def       SCREAMING_SNAKE_CASE_	(      self							:    str							,     lowercase_							:    T       ):
										lowercase_   :     str									=			RandomizedHeapNode.merge(self._root							,     RandomizedHeapNode(lowercase_       )       )







			def       SCREAMING_SNAKE_CASE_	(      self							:    Optional[Any]       ):
										lowercase_   :     Any									=			self.top()

										if self._root is None:
																	return None

										lowercase_   :     Dict									=			RandomizedHeapNode.merge(self._root.left							,     self._root.right       )

										return result







			def       SCREAMING_SNAKE_CASE_	(      self							:    List[str]       ):
										if not self._root:
																	raise IndexError("""Can't get top element for the empty heap."""       )
										return self._root.value







			def       SCREAMING_SNAKE_CASE_	(      self							:    int       ):
										lowercase_   :     int									=			None







			def       SCREAMING_SNAKE_CASE_	(      self							:    List[Any]       ):
										lowercase_   :     Tuple									=			[]
										while self:
																	result.append(self.pop()       )

										return result







			def __bool__(      self							:    str       ):
										return self._root is not None


if __name__ == "__main__":
						import doctest

						doctest.testmod()






'''simple docstring'''




from __future__ import annotations




def 				lowerCamelCase      ( UpperCAmelCase__			:   str					)     -> Any:
							global graph, reversed_graph, scc, component, visit, stack
							if visit[u]:
														return
							lowercase_   :     int									=			True
							for v in graph[u]:
														dfs(UpperCAmelCase__					)
							stack.append(UpperCAmelCase__					)




def 				lowerCamelCase      ( UpperCAmelCase__			:   int					)     -> str:
							global graph, reversed_graph, scc, component, visit, stack
							if visit[u]:
														return
							lowercase_   :     Tuple									=			True
							component.append(UpperCAmelCase__					)
							for v in reversed_graph[u]:
														dfsa(UpperCAmelCase__					)




def 				lowerCamelCase      ( )     -> int:
							global graph, reversed_graph, scc, component, visit, stack
							for i in range(UpperCAmelCase__					):
														dfs(UpperCAmelCase__					)
							lowercase_   :     Optional[int]									=			[False] * n
							for i in stack[::-1]:
														if visit[i]:
																					continue
														lowercase_   :     Union[str, Any]									=			[]
														dfsa(UpperCAmelCase__					)
														scc.append(UpperCAmelCase__					)
							return scc


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

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

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





