
import os
from functools import partial
from glob import glob

import faiss
from datasets import Features, Sequence, Value, concatenate_datasets, load_dataset, load_from_disk

from transformers import DPRContextEncoder, DPRContextEncoderTokenizerFast






def     lowerCamelCase__				(   a						,						a=1_00						,						a=" " ) ->  Dict:
   _A:    Tuple						     =			text.split(a )
   return [character.join(text[i : i + n] ).strip() for i in range(0						,						len(a )						,						a )]






def     lowerCamelCase__				(   a ) ->  Optional[int]:
   _A     ,    _A:    int						     =			[], []
   for title, text in zip(documents['''title''']						,						documents['''text'''] ):
      if text is not None:
         for passage in split_text(a ):
            titles.append(title if title is not None else '''''' )
            texts.append(a )
   return {"title": titles, "text": texts}






def     lowerCamelCase__				(   a						,						a						,						a						,						a						,						a						,						a ) ->  List[str]:
   _A:    Any						     =			load_dataset(
       '''csv'''						,						data_files=[csv_path]						,						split='''train'''						,						delimiter='''\t'''						,						column_names=['''title''', '''text'''] )
   _A:    Dict						     =			kb_dataset.map(
       a						,						batched=a						,						num_proc=1 )  # if you want you can load already splitted csv.
   _A:    Any						     =			[kb_dataset.shard(a						,						a						,						contiguous=a ) for i in range(a )]
   _A:    Tuple						     =			kb_list[process_num]

   _A:    Optional[Any]						     =			'''data_''' + str(a )
   _A:    int						     =			os.path.join(a						,						a )

   _A:    Dict						     =			DPRContextEncoderTokenizerFast.from_pretrained('''facebook/dpr-ctx_encoder-multiset-base''' )
   _A:    Optional[Any]						     =			ctx_encoder.to(device=a )

   def embed(
       a						,						a						,						a						,						a ) -> dict:
      _A:    List[Any]						     =			ctx_tokenizer(
          documents['''title''']						,						documents['''text''']						,						truncation=a						,						padding='''longest'''						,						return_tensors='''pt''' )['''input_ids''']
      _A:    List[str]						     =			ctx_encoder(input_ids.to(device=a )						,						return_dict=a ).pooler_output
      return {"embeddings": embeddings.detach().cpu().numpy()}

   _A:    List[Any]						     =			Features(
       {'''text''': Value('''string''' ), '''title''': Value('''string''' ), '''embeddings''': Sequence(Value('''float32''' ) )} )  # optional, save as float32 instead of float64 to save space

   _A:    List[str]						     =			data_shrad.map(
       partial(a						,						ctx_encoder=a						,						ctx_tokenizer=a						,						device=a )						,						batched=a						,						batch_size=16						,						features=a						,						)
   dataset.save_to_disk(a )






def     lowerCamelCase__				(   a						,						a ) ->  List[Any]:
   _A:    List[Any]						     =			[]

   for shard_address in glob(str(a ) + '''/*/''' ):
      data_shard_list.append(load_from_disk(a ) )

   _A:    Tuple						     =			concatenate_datasets(a )
   faiss.omp_set_num_threads(96 )

   _A:    List[str]						     =			faiss.IndexHNSWFlat(7_68						,						1_28						,						faiss.METRIC_INNER_PRODUCT )
   concat.add_faiss_index('''embeddings'''						,						custom_index=a )
   concat.get_index('''embeddings''' ).save(
       a )  # since we load the index in to memory,we can directly update the index in the disk





from __future__ import annotations






def     lowerCamelCase__				(   a ) ->  Union[str, Any]:
   global graph, reversed_graph, scc, component, visit, stack
   if visit[u]:
      return
   _A:    Optional[Any]						     =			True
   for v in graph[u]:
      dfs(a )
   stack.append(a )






def     lowerCamelCase__				(   a ) ->  List[Any]:
   global graph, reversed_graph, scc, component, visit, stack
   if visit[u]:
      return
   _A:    str						     =			True
   component.append(a )
   for v in reversed_graph[u]:
      dfsa(a )






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


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

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

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



