




from __future__ import annotations

from queue import Queue



def 							_A   (						lowerCAmelCase_     :					int   ,				lowerCAmelCase_     :					int			):
     """simple docstring"""

     a ^= b
     b ^= a
     a ^= b
     return a, b



def 							_A   (						lowerCAmelCase_     :					int   ,				lowerCAmelCase_     :					list[list[int]]			):
     """simple docstring"""

     lowerCAmelCase__		= 1
     while (1 << j) < max_node:
          for i in range(1   ,				max_node + 1			):
               lowerCAmelCase__		= parent[j - 1][parent[j - 1][i]]
          j += 1
     return parent



def 							_A   (						lowerCAmelCase_     :					int   ,				lowerCAmelCase_     :					int   ,				lowerCAmelCase_     :					list[int]   ,				lowerCAmelCase_     :					list[list[int]]			):
     """simple docstring"""

     if level[u] < level[v]:
          lowerCAmelCase__	,		lowerCAmelCase__		= swap(lowerCAmelCase_   ,				lowerCAmelCase_			)
     # making depth of u same as depth of v
     for i in range(18   ,				-1   ,				-1			):
          if level[u] - (1 << i) >= level[v]:
               lowerCAmelCase__		= parent[i][u]
    # at the same depth if u==v that mean lca is found
     if u == v:
          return u
     # moving both nodes upwards till lca in found
     for i in range(18   ,				-1   ,				-1			):
          if parent[i][u] not in [0, parent[i][v]]:
               lowerCAmelCase__	,		lowerCAmelCase__		= parent[i][u], parent[i][v]
    # returning longest common ancestor of u,v
     return parent[0][u]



def 							_A   (						lowerCAmelCase_     :					list[int]   ,				lowerCAmelCase_     :					list[list[int]]   ,				lowerCAmelCase_     :					int   ,				lowerCAmelCase_     :					dict[int, list[int]]   ,				lowerCAmelCase_     :					int = 1   ,				):
     """simple docstring"""

     lowerCAmelCase__		= 0
     lowerCAmelCase__		= Queue(maxsize=lowerCAmelCase_			)
     q.put(lowerCAmelCase_			)
     while q.qsize() != 0:
          lowerCAmelCase__		= q.get()
          for v in graph[u]:
               if level[v] == -1:
                    lowerCAmelCase__		= level[u] + 1
                    q.put(lowerCAmelCase_			)
                    lowerCAmelCase__		= u
     return level, parent



def 							_A   (						):
     """simple docstring"""

     lowerCAmelCase__		= 13
     # initializing with 0
     lowerCAmelCase__		= [[0 for _ in range(max_node + 10			)] for _ in range(20			)]
     # initializing with -1 which means every node is unvisited
     lowerCAmelCase__		= [-1 for _ in range(max_node + 10			)]
     lowerCAmelCase__		= {
         1: [2, 3, 4],
         2: [5],
         3: [6, 7],
         4: [8],
         5: [9, 10],
         6: [11],
         7: [],
         8: [12, 13],
         9: [],
         10: [],
         11: [],
         12: [],
         13: [],
     }
     lowerCAmelCase__	,		lowerCAmelCase__		= breadth_first_search(lowerCAmelCase_   ,				lowerCAmelCase_   ,				lowerCAmelCase_   ,				lowerCAmelCase_   ,				1			)
     lowerCAmelCase__		= create_sparse(lowerCAmelCase_   ,				lowerCAmelCase_			)
     print("LCA of node 1 and 3 is: "   ,				lowest_common_ancestor(1   ,				3   ,				lowerCAmelCase_   ,				lowerCAmelCase_			)			)
     print("LCA of node 5 and 6 is: "   ,				lowest_common_ancestor(5   ,				6   ,				lowerCAmelCase_   ,				lowerCAmelCase_			)			)
     print("LCA of node 7 and 11 is: "   ,				lowest_common_ancestor(7   ,				11   ,				lowerCAmelCase_   ,				lowerCAmelCase_			)			)
     print("LCA of node 6 and 7 is: "   ,				lowest_common_ancestor(6   ,				7   ,				lowerCAmelCase_   ,				lowerCAmelCase_			)			)
     print("LCA of node 4 and 12 is: "   ,				lowest_common_ancestor(4   ,				12   ,				lowerCAmelCase_   ,				lowerCAmelCase_			)			)
     print("LCA of node 8 and 8 is: "   ,				lowest_common_ancestor(8   ,				8   ,				lowerCAmelCase_   ,				lowerCAmelCase_			)			)


if __name__ == "__main__":
     main()


"""simple docstring"""

from __future__ import annotations




def 			lowercase__  (    lowerCAmelCase :    Dict       )       ->					Optional[int]:






    """simple docstring"""




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




def 			lowercase__  (    lowerCAmelCase :    Optional[int]       )       ->					int:






    """simple docstring"""




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




def 			lowercase__  (    )       ->					List[str]:






    """simple docstring"""




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


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

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

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



