





import json
import os
import re
import unicodedata
from typing import Optional, Tuple

from ...tokenization_utils import PreTrainedTokenizer, _is_control, _is_punctuation, _is_whitespace
from ...utils import logging


UpperCAmelCase						:       Union[str, Any]        =					logging.get_logger(__name__)

UpperCAmelCase						:       List[Any]        =					{
    '''vocab_file''': '''vocab.json''',
    '''merges_file''': '''merges.txt''',
}

UpperCAmelCase						:       Optional[int]        =					{
    '''vocab_file''': {'''openai-gpt''': '''https://huggingface.co/openai-gpt/resolve/main/vocab.json'''},
    '''merges_file''': {'''openai-gpt''': '''https://huggingface.co/openai-gpt/resolve/main/merges.txt'''},
}

UpperCAmelCase						:       Tuple        =					{
    '''openai-gpt''': 5_12,
}







def 			_SCREAMING_SNAKE_CASE    (       a  )				->				Tuple:
					__A     :						Optional[int]          =    text.strip()
					if not text:
										return []
					__A     :						Any          =    text.split()
					return tokens





class 						_A( snake_case__       ):


				"""simple docstring"""


				def __init__(      self					, _A=True					, _A=None					, _A=True					, _A=None					, _A=True					, ):
									if never_split is None:
														__A     :						Any          =    []
									__A     :						List[Any]          =    do_lower_case
									__A     :						Optional[int]          =    set(_A					)
									__A     :						Tuple          =    tokenize_chinese_chars
									__A     :						List[Any]          =    strip_accents
									__A     :						Dict          =    do_split_on_punc



				def  UpperCAmelCase_		(      self					, _A					, _A=None					):
									__A     :						Union[str, Any]          =    self.never_split.union(set(_A					)					) if never_split else self.never_split
									__A     :						Any          =    self._clean_text(_A					)

									# This was added on November 1st, 2018 for the multilingual and Chinese
									# models. This is also applied to the English models now, but it doesn't
									# matter since the English models were not trained on any Chinese data
									# and generally don't have any Chinese data in them (there are Chinese
									# characters in the vocabulary because Wikipedia does have some Chinese
									# words in the English Wikipedia.).
									if self.tokenize_chinese_chars:
														__A     :						Any          =    self._tokenize_chinese_chars(_A					)
									# prevents treating the same character with different unicode codepoints as different characters
									__A     :						List[str]          =    unicodedata.normalize('NFC'					, _A					)
									__A     :						Any          =    whitespace_tokenize(_A					)
									__A     :						Dict          =    []
									for token in orig_tokens:
														if token not in never_split:
																			if self.do_lower_case:
																								__A     :						List[Any]          =    token.lower()
																								if self.strip_accents is not False:
																													__A     :						List[str]          =    self._run_strip_accents(_A					)
																			elif self.strip_accents:
																								__A     :						Union[str, Any]          =    self._run_strip_accents(_A					)
														split_tokens.extend(self._run_split_on_punc(_A					, _A					)					)

									__A     :						List[str]          =    whitespace_tokenize(' '.join(_A					)					)
									return output_tokens



				def  UpperCAmelCase_		(      self					, _A					):
									__A     :						List[Any]          =    unicodedata.normalize('NFD'					, _A					)
									__A     :						Tuple          =    []
									for char in text:
														__A     :						str          =    unicodedata.category(_A					)
														if cat == "Mn":
																			continue
														output.append(_A					)
									return "".join(_A					)



				def  UpperCAmelCase_		(      self					, _A					, _A=None					):
									if not self.do_split_on_punc or (never_split is not None and text in never_split):
														return [text]
									__A     :						Any          =    list(_A					)
									__A     :						Union[str, Any]          =    0
									__A     :						Union[str, Any]          =    True
									__A     :						Dict          =    []
									while i < len(_A					):
														__A     :						Union[str, Any]          =    chars[i]
														if _is_punctuation(_A					):
																			output.append([char]					)
																			__A     :						Union[str, Any]          =    True
														else:
																			if start_new_word:
																								output.append([]					)
																			__A     :						Dict          =    False
																			output[-1].append(_A					)
														i += 1

									return ["".join(_A					) for x in output]



				def  UpperCAmelCase_		(      self					, _A					):
									__A     :						Optional[int]          =    []
									for char in text:
														__A     :						Union[str, Any]          =    ord(_A					)
														if self._is_chinese_char(_A					):
																			output.append(' '					)
																			output.append(_A					)
																			output.append(' '					)
														else:
																			output.append(_A					)
									return "".join(_A					)



				def  UpperCAmelCase_		(      self					, _A					):
									# This defines a "chinese character" as anything in the CJK Unicode block:
									#   https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
									#
									# Note that the CJK Unicode block is NOT all Japanese and Korean characters,
									# despite its name. The modern Korean Hangul alphabet is a different block,
									# as is Japanese Hiragana and Katakana. Those alphabets are used to write
									# space-separated words, so they are not treated specially and handled
									# like the all of the other languages.
									if (
									    (cp >= 0X4_E00 and cp <= 0X9_FFF)
									    or (cp >= 0X3_400 and cp <= 0X4_DBF)  #
									    or (cp >= 0X20_000 and cp <= 0X2A_6DF)  #
									    or (cp >= 0X2A_700 and cp <= 0X2B_73F)  #
									    or (cp >= 0X2B_740 and cp <= 0X2B_81F)  #
									    or (cp >= 0X2B_820 and cp <= 0X2C_EAF)  #
									    or (cp >= 0XF_900 and cp <= 0XF_AFF)
									    or (cp >= 0X2F_800 and cp <= 0X2F_A1F)  #
									):  #
														return True

									return False





				def  UpperCAmelCase_		(      self					, _A					):
									__A     :						Dict          =    []
									for char in text:
														__A     :						Tuple          =    ord(_A					)
														if cp == 0 or cp == 0XF_FFD or _is_control(_A					):
																			continue
														if _is_whitespace(_A					):
																			output.append(' '					)
														else:
																			output.append(_A					)
									return "".join(_A					)







def 			_SCREAMING_SNAKE_CASE    (       a  )				->				int:
					__A     :						List[str]          =    set()
					__A     :						Optional[int]          =    word[0]
					for char in word[1:]:
										pairs.add((prev_char, char)  )
										__A     :						Union[str, Any]          =    char
					return pairs







def 			_SCREAMING_SNAKE_CASE    (       a  )				->				List[Any]:
					__A     :						int          =    text.replace('—' ,						'-'  )
					__A     :						Union[str, Any]          =    text.replace('–' ,						'-'  )
					__A     :						str          =    text.replace('―' ,						'-'  )
					__A     :						int          =    text.replace('…' ,						'...'  )
					__A     :						Optional[int]          =    text.replace('´' ,						'\''  )
					__A     :						Dict          =    re.sub(r'(-+|~+|!+|"+|;+|\?+|\++|,+|\)+|\(+|\\+|\/+|\*+|\[+|\]+|}+|{+|\|+|_+)' ,						r' \1 ' ,						a  )
					__A     :						Optional[int]          =    re.sub(r'\s*\n\s*' ,						' \n ' ,						a  )
					__A     :						List[Any]          =    re.sub(r'[^\S\n]+' ,						' ' ,						a  )
					return text.strip()





class 						_A( snake_case__       ):


				"""simple docstring"""


				UpperCamelCase   :  int    =     VOCAB_FILES_NAMES
				UpperCamelCase   :  Union[str, Any]    =     PRETRAINED_VOCAB_FILES_MAP
				UpperCamelCase   :  Any    =     PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
				UpperCamelCase   :  Dict    =     ['''input_ids''', '''attention_mask''']



				def __init__(      self					, _A					, _A					, _A="<unk>"					, **_A					):
									super().__init__(unk_token=_A					, **_A					)

									try:
														import ftfy
														from spacy.lang.en import English

														__A     :						List[str]          =    English()
														__A     :						Tuple          =    _nlp.tokenizer
														__A     :						Dict          =    ftfy.fix_text
									except ImportError:
														logger.warning('ftfy or spacy is not installed using BERT BasicTokenizer instead of SpaCy & ftfy.'					)
														__A     :						List[str]          =    BasicTokenizer(do_lower_case=_A					)
														__A     :						str          =    None

									with open(_A					, encoding='utf-8'					) as vocab_handle:
														__A     :						Union[str, Any]          =    json.load(_A					)
									__A     :						List[Any]          =    {v: k for k, v in self.encoder.items()}
									with open(_A					, encoding='utf-8'					) as merges_handle:
														__A     :						List[str]          =    merges_handle.read().split('\n'					)[1:-1]
									__A     :						List[Any]          =    [tuple(merge.split()					) for merge in merges]
									__A     :						Dict          =    dict(zip(_A					, range(len(_A					)					)					)					)
									__A     :						Any          =    {}



				@property
				def  UpperCAmelCase_		(      self					):
									return True



				@property
				def  UpperCAmelCase_		(      self					):
									return len(self.encoder					)



				def  UpperCAmelCase_		(      self					):
									return dict(self.encoder					, **self.added_tokens_encoder					)



				def  UpperCAmelCase_		(      self					, _A					):
									__A     :						Optional[int]          =    tuple(token[:-1]					) + (token[-1] + '</w>',)
									if token in self.cache:
														return self.cache[token]
									__A     :						Any          =    get_pairs(_A					)

									if not pairs:
														return token + "</w>"

									while True:
														__A     :						Tuple          =    min(_A					, key=lambda _A					: self.bpe_ranks.get(_A					, float('inf'					)					)					)
														if bigram not in self.bpe_ranks:
																			break
														__A   ,    __A     :						Optional[Any]          =    bigram
														__A     :						Dict          =    []
														__A     :						List[str]          =    0
														while i < len(_A					):
																			try:
																								__A     :						Union[str, Any]          =    word.index(_A					, _A					)
																			except ValueError:
																								new_word.extend(word[i:]					)
																								break
																			else:
																								new_word.extend(word[i:j]					)
																								__A     :						List[str]          =    j

																			if word[i] == first and i < len(_A					) - 1 and word[i + 1] == second:
																								new_word.append(first + second					)
																								i += 2
																			else:
																								new_word.append(word[i]					)
																								i += 1
														__A     :						Union[str, Any]          =    tuple(_A					)
														__A     :						Union[str, Any]          =    new_word
														if len(_A					) == 1:
																			break
														else:
																			__A     :						List[Any]          =    get_pairs(_A					)
									__A     :						Optional[int]          =    ' '.join(_A					)
									if word == "\n  </w>":
														__A     :						Tuple          =    '\n</w>'
									__A     :						List[Any]          =    word
									return word



				def  UpperCAmelCase_		(      self					, _A					):
									__A     :						Union[str, Any]          =    []
									if self.fix_text is None:
														# Using BERT's BasicTokenizer
														__A     :						Optional[Any]          =    self.nlp.tokenize(_A					)
														for token in text:
																			split_tokens.extend(list(self.bpe(_A					).split(' '					)					)					)
									else:
														# Using SpaCy & ftfy (original tokenization process of OpenAI GPT)
														__A     :						Optional[int]          =    self.nlp(text_standardize(self.fix_text(_A					)					)					)
														for token in text:
																			split_tokens.extend(list(self.bpe(token.text.lower()					).split(' '					)					)					)
									return split_tokens



				def  UpperCAmelCase_		(      self					, _A					):
									return self.encoder.get(_A					, self.encoder.get(self.unk_token					)					)



				def  UpperCAmelCase_		(      self					, _A					):
									return self.decoder.get(_A					, self.unk_token					)



				def  UpperCAmelCase_		(      self					, _A					):
									__A     :						Tuple          =    ''.join(_A					).replace('</w>'					, ' '					).strip()
									return out_string





				def  UpperCAmelCase_		(      self					, _A					, _A = None					):
									if not os.path.isdir(_A					):
														logger.error(F"""Vocabulary path ({save_directory}) should be a directory"""					)
														return
									__A     :						Optional[int]          =    os.path.join(
									    _A					, (filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['vocab_file']					)
									__A     :						Any          =    os.path.join(
									    _A					, (filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['merges_file']					)

									with open(_A					, 'w'					, encoding='utf-8'					) as f:
														f.write(json.dumps(self.encoder					, indent=2					, sort_keys=_A					, ensure_ascii=_A					) + '\n'					)

									__A     :						Optional[Any]          =    0
									with open(_A					, 'w'					, encoding='utf-8'					) as writer:
														writer.write('#version: 0.2\n'					)
														for bpe_tokens, token_index in sorted(self.bpe_ranks.items()					, key=lambda _A					: kv[1]					):
																			if index != token_index:
																								logger.warning(
																								    F"""Saving vocabulary to {merge_file}: BPE merge indices are not consecutive."""
																								    ' Please check that the tokenizer is not corrupted!'					)
																								__A     :						Optional[int]          =    token_index
																			writer.write(' '.join(_A					) + '\n'					)
																			index += 1

									return vocab_file, merge_file











from __future__ import annotations







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







def 			_SCREAMING_SNAKE_CASE    (       a  )				->				Optional[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 			_SCREAMING_SNAKE_CASE    (       )				->				Optional[int]:
					global graph, reversed_graph, scc, component, visit, stack
					for i in range(a  ):
										dfs(a  )
					__A     :						str          =    [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						:       List[str]        =					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						:       int        =					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())




