






from typing import List

from tokenizers import NormalizedString, PreTokenizedString, normalizers

class 					snake_case_							:







   """simple docstring"""



   def __init__(    self:	Any   ,       snake_case__:	List[str]	)  ->		None:


       """simple docstring"""



       _lowercase     =	vocab
       _lowercase     =	normalizers.BertNormalizer(
           clean_text=snake_case__   ,       handle_chinese_chars=snake_case__   ,       strip_accents=snake_case__   ,       lowercase=snake_case__   ,       )
       try:
           import rjieba
       except ImportError:
           raise ImportError(
               'You need to install rjieba to use RoFormerTokenizer. '
               'See https://pypi.org/project/rjieba/ for installation.'	)
       _lowercase     =	rjieba

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[Any]   ,       snake_case__:	int   ,       snake_case__:	NormalizedString	)  ->		List[NormalizedString]:


       """simple docstring"""



       _lowercase     =	[]

       # this code slice normalized_string is too slow (6s) but test_alignement_methods can pass
       for token, start, end in self.jieba.tokenize(str(snake_case__	)   ,       hmm=snake_case__	):
           if token in self.vocab:
               splits.append(normalized_string[start:end]	)
           else:
               _lowercase     =	self.normalizers.normalize_str(snake_case__	).split()
               for token in token_list:
                   if token:
                       _lowercase     =	start + len(snake_case__	)
                       splits.append(normalized_string[start:end]	)
                       _lowercase     =	end

        # this code test_alignement_methods can't pass but fast (300ms)
        # for token in self.jieba.cut(str(normalized_string), False):
        #     if token in self.vocab:
        #         splits.append(NormalizedString(token))
        #     else:
        #         token_list = self.normalizers.normalize_str(token).split()
        #         for token in token_list:
        #             if token:
        #                 splits.append(NormalizedString(token))

       return splits

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[int]   ,       snake_case__:	PreTokenizedString	)  ->		Dict:


       """simple docstring"""



       pretok.split(self.jieba_split	)








from __future__ import annotations
def        UpperCAmelCase      (   _lowercase      ):


    '''simple docstring'''



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


    '''simple docstring'''



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


    '''simple docstring'''



    global graph, reversed_graph, scc, component, visit, stack
    for i in range(_lowercase      ):
        dfs(_lowercase      )
    _lowercase     =	[False] * n
    for i in stack[::-1]:
        if visit[i]:
            continue
        _lowercase     =	[]
        dfsa(_lowercase      )
        scc.append(_lowercase      )
    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())
