import os
import random
from pathlib import Path
from typing import List

import numpy as np
import torch
from torch.cuda.amp import GradScaler

from .utils import (
    MODEL_NAME,
    OPTIMIZER_NAME,
    RNG_STATE_NAME,
    SCALER_NAME,
    SCHEDULER_NAME,
    get_pretty_name,
    is_tpu_available,
    is_xpu_available,
    save,
)


if is_tpu_available(check_device=False):
     import torch_xla.core.xla_model as xm

from .logging import get_logger
from .state import PartialState


_SCREAMING_SNAKE_CASE   		=			get_logger(__name__)





def  lowercase(  UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_ = None       ,				)		->  str:







 '''simple docstring'''







 for i, state in enumerate(_A					):
  UpperCamelCase      =			f"""{MODEL_NAME}.bin""" if i == 0 else f"""{MODEL_NAME}_{i}.bin"""
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  save(_A       ,				_A					)
  logger.info(f"""Model weights saved in {output_model_file}"""					)
 # Optimizer states
 for i, opt in enumerate(_A					):
  UpperCamelCase      =			opt.state_dict()
  UpperCamelCase      =			f"""{OPTIMIZER_NAME}.bin""" if i == 0 else f"""{OPTIMIZER_NAME}_{i}.bin"""
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  save(_A       ,				_A					)
  logger.info(f"""Optimizer state saved in {output_optimizer_file}"""					)
 # Scheduler states
 for i, scheduler in enumerate(_A					):
  UpperCamelCase      =			scheduler.state_dict()
  UpperCamelCase      =			f"""{SCHEDULER_NAME}.bin""" if i == 0 else f"""{SCHEDULER_NAME}_{i}.bin"""
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  save(_A       ,				_A					)
  logger.info(f"""Scheduler state saved in {output_scheduler_file}"""					)
 # GradScaler state
 if scaler is not None:
  UpperCamelCase      =			scaler.state_dict()
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  torch.save(_A       ,				_A					)
  logger.info(f"""Gradient scaler state saved in {output_scaler_file}"""					)
 # Random number generator states
 UpperCamelCase      =			{}
 UpperCamelCase      =			f"""{RNG_STATE_NAME}_{process_index}.pkl"""
 UpperCamelCase      =			random.getstate()
 UpperCamelCase      =			np.random.get_state()
 UpperCamelCase      =			torch.get_rng_state()
 if is_xpu_available():
  UpperCamelCase      =			torch.xpu.get_rng_state_all()
 else:
  UpperCamelCase      =			torch.cuda.get_rng_state_all()
 if is_tpu_available():
  UpperCamelCase      =			xm.get_rng_state()
 UpperCamelCase      =			os.path.join(_A       ,				_A					)
 torch.save(_A       ,				_A					)
 logger.info(f"""Random states saved in {output_states_file}"""					)
 return output_dir





def  lowercase(  UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_=None       ,				UpperCamelCase_=None       ,				**UpperCamelCase_       ,				)		->  Tuple:







 '''simple docstring'''







 if map_location not in [None, "cpu", "on_device"]:
  raise TypeError(
      """Unsupported optimizer map location passed, please choose one of `None`, `\'cpu\'`, or `\'on_device\'`"""					)
 if map_location is None:
  UpperCamelCase      =			"""cpu"""
 elif map_location == "on_device":
  UpperCamelCase      =			PartialState().device
 # Model states
 for i, model in enumerate(_A					):
  UpperCamelCase      =			f"""{MODEL_NAME}.bin""" if i == 0 else f"""{MODEL_NAME}_{i}.bin"""
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  models[i].load_state_dict(torch.load(_A       ,				map_location=_A					)       ,				**_A					)
 logger.info("""All model weights loaded successfully"""					)

 # Optimizer states
 for i, opt in enumerate(_A					):
  UpperCamelCase      =			f"""{OPTIMIZER_NAME}.bin""" if i == 0 else f"""{OPTIMIZER_NAME}_{i}.bin"""
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  UpperCamelCase      =			torch.load(_A       ,				map_location=_A					)
  optimizers[i].load_state_dict(_A					)
 logger.info("""All optimizer states loaded successfully"""					)

 # Scheduler states
 for i, scheduler in enumerate(_A					):
  UpperCamelCase      =			f"""{SCHEDULER_NAME}.bin""" if i == 0 else f"""{SCHEDULER_NAME}_{i}.bin"""
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  scheduler.load_state_dict(torch.load(_A					)					)
 logger.info("""All scheduler states loaded successfully"""					)

 # GradScaler state
 if scaler is not None:
  UpperCamelCase      =			os.path.join(_A       ,				_A					)
  scaler.load_state_dict(torch.load(_A					)					)
  logger.info("""GradScaler state loaded successfully"""					)

 # Random states
 try:
  UpperCamelCase      =			torch.load(os.path.join(_A       ,				f"""{RNG_STATE_NAME}_{process_index}.pkl"""					)					)
  random.setstate(states["""random_state"""]					)
  np.random.set_state(states["""numpy_random_seed"""]					)
  torch.set_rng_state(states["""torch_manual_seed"""]					)
  if is_xpu_available():
   torch.xpu.set_rng_state_all(states["""torch_xpu_manual_seed"""]					)
  else:
   torch.cuda.set_rng_state_all(states["""torch_cuda_manual_seed"""]					)
  if is_tpu_available():
   xm.set_rng_state(states["""xm_seed"""]					)
  logger.info("""All random states loaded successfully"""					)
 except Exception:
  logger.info("""Could not load random states"""					)





def  lowercase(  UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_ = 0					)		->  Union[str, Any]:







 '''simple docstring'''
 UpperCamelCase      =			Path(_A					) / f"""custom_checkpoint_{index}.pkl"""
 logger.info(f"""Saving the state of {get_pretty_name(_A					)} to {save_location}"""					)
 torch.save(obj.state_dict()       ,				_A					)





def  lowercase(  UpperCamelCase_       ,				UpperCamelCase_       ,				UpperCamelCase_ = 0					)		->  Any:







 '''simple docstring'''
 UpperCamelCase      =			f"""{path}/custom_checkpoint_{index}.pkl"""
 logger.info(f"""Loading the state of {get_pretty_name(_A					)} from {load_location}"""					)
 obj.load_state_dict(torch.load(_A       ,				map_location="""cpu"""					)					)

from __future__ import annotations





def  lowercase(  UpperCamelCase_					)		->  Dict:







 '''simple docstring'''
 global graph, reversed_graph, scc, component, visit, stack
 if visit[u]:
  return
 UpperCamelCase      =			True
 for v in graph[u]:
  dfs(UpperCamelCase_					)
 stack.append(UpperCamelCase_					)





def  lowercase(  UpperCamelCase_					)		->  Optional[int]:







 '''simple docstring'''
 global graph, reversed_graph, scc, component, visit, stack
 if visit[u]:
  return
 UpperCamelCase      =			True
 component.append(UpperCamelCase_					)
 for v in reversed_graph[u]:
  dfsa(UpperCamelCase_					)





def  lowercase(  )		->  Any:







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