






from __future__ import annotations






def    UpperCamelCase__  (   UpperCAmelCase     )     ->		Any:







							"""simple docstring"""





							global graph, reversed_graph, scc, component, visit, stack
							if visit[u]:
														return
							_a  :    Union[str, Any]			=						True
							for v in graph[u]:
														dfs(UpperCAmelCase     )
							stack.append(UpperCAmelCase     )






def    UpperCamelCase__  (   UpperCAmelCase     )     ->		List[Any]:







							"""simple docstring"""





							global graph, reversed_graph, scc, component, visit, stack
							if visit[u]:
														return
							_a  :    List[Any]			=						True
							component.append(UpperCAmelCase     )
							for v in reversed_graph[u]:
														dfsa(UpperCAmelCase     )






def    UpperCamelCase__  (   )     ->		Tuple:







							"""simple docstring"""





							global graph, reversed_graph, scc, component, visit, stack
							for i in range(UpperCAmelCase     ):
														dfs(UpperCAmelCase     )
							_a  :    Optional[Any]			=						[False] * n
							for i in stack[::-1]:
														if visit[i]:
																					continue
														_a  :    int			=						[]
														dfsa(UpperCAmelCase     )
														scc.append(UpperCAmelCase     )
							return scc


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

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

						__lowerCamelCase						= []
						__lowerCamelCase						= [False] * n
						__lowerCamelCase						= []
						__lowerCamelCase						= []
						print(kosaraju())







def    UpperCamelCase__  (   UpperCAmelCase     )     ->		tuple[int, int]:







							"""simple docstring"""





							if len(UpperCAmelCase     ) == 1:
														return a[0], a[0]
							else:
														# split A into half.
														_a  :    Union[str, Any]			=						a[: len(UpperCAmelCase     ) // 2]
														_a  :    Optional[Any]			=						a[len(UpperCAmelCase     ) // 2 :]

														# 2 sub problems, 1/2 of original size.
														_a		,					_a  :    Union[str, Any]			=						max_difference(UpperCAmelCase     )
														_a		,					_a  :    List[Any]			=						max_difference(UpperCAmelCase     )

														# get min of first and max of second
														# linear time
														_a  :    Union[str, Any]			=						min(UpperCAmelCase     )
														_a  :    Any			=						max(UpperCAmelCase     )

														# 3 cases, either (small1, big1),
														# (min_first, max_second), (small2, big2)
														# constant comparisons
														if biga - smalla > max_second - min_first and biga - smalla > biga - smalla:
																					return smalla, biga
														elif biga - smalla > max_second - min_first:
																					return smalla, biga
														else:
																					return min_first, max_second


if __name__ == "__main__":
						import doctest

						doctest.testmod()