from typing import Any

import numpy as np
class SCREAMING_SNAKE_CASE_		:







   def __init__(    self	:	Optional[Any]      ,      lowerCamelCase_	:	np.ndarray      ,      lowerCamelCase_	:	int							):





    """simple docstring"""


    if np.any(tableau[:, -1]      ,      where=tableau[:, -1] < 0							):
     raise ValueError("""RHS must be > 0"""							)

    UpperCamelCase      =			tableau
    UpperCamelCase     ,    UpperCamelCase      =			tableau.shape

    # Number of decision variables x1, x2, x3...
    UpperCamelCase      =			n_vars

    # Number of artificial variables to be minimised
    UpperCamelCase      =			len(np.where(tableau[self.n_vars : -1] == -1							)[0]							)

    # 2 if there are >= or == constraints (nonstandard), 1 otherwise (std)
    UpperCamelCase      =			(self.n_art_vars > 0) + 1

    # Number of slack variables added to make inequalities into equalities
    UpperCamelCase      =			self.n_rows - self.n_stages

    # Objectives for each stage
    UpperCamelCase      =			["""max"""]

    # In two stage simplex, first minimise then maximise
    if self.n_art_vars:
     self.objectives.append("""min"""							)

    UpperCamelCase      =			[""""""]

    # Index of current pivot row and column
    UpperCamelCase      =			None
    UpperCamelCase      =			None

    # Does objective row only contain (non)-negative values?
    UpperCamelCase      =			False







   @staticmethod
   def 	lowerCamelCase_  (    *lowerCamelCase_	:	int							):





    """simple docstring"""


    if len(lowerCamelCase_							) != 3:
     raise ValueError("""Must provide n_vars, n_slack, and n_art_vars"""							)

    if not all(x >= 0 and isinstance(lowerCamelCase_      ,      lowerCamelCase_							) for x in args							):
     raise ValueError("""All arguments must be non-negative integers"""							)

    # decision | slack | artificial
    UpperCamelCase      =			["""x""", """s""", """a"""]
    UpperCamelCase      =			[]
    for i in range(3							):
     for j in range(args[i]							):
      titles.append(string_starts[i] + str(j + 1							)							)
    titles.append("""RHS"""							)
    return titles







   def 	lowerCamelCase_  (    self	:	List[Any]      ,      lowerCamelCase_	:	np.ndarray							):





    """simple docstring"""


    UpperCamelCase      =			self.objectives[-1]

    # Find entries of highest magnitude in objective rows
    UpperCamelCase      =			(objective == """min""") - (objective == """max""")
    UpperCamelCase      =			np.argmax(sign * tableau[0, : self.n_vars]							)

    # Choice is only valid if below 0 for maximise, and above for minimise
    if sign * self.tableau[0, col_idx] <= 0:
     UpperCamelCase      =			True
     return 0, 0

    # Pivot row is chosen as having the lowest quotient when elements of
    # the pivot column divide the right-hand side

    # Slice excluding the objective rows
    UpperCamelCase      =			slice(self.n_stages      ,      self.n_rows							)

    # RHS
    UpperCamelCase      =			tableau[s, -1]

    # Elements of pivot column within slice
    UpperCamelCase      =			tableau[s, col_idx]

    # Array filled with nans
    UpperCamelCase      =			np.full(self.n_rows - self.n_stages      ,      np.nan							)

    # If element in pivot column is greater than zeron_stages, return
    # quotient or nan otherwise
    UpperCamelCase      =			np.divide(lowerCamelCase_      ,      lowerCamelCase_      ,      out=lowerCamelCase_      ,      where=divisor > 0							)

    # Arg of minimum quotient excluding the nan values. n_stages is added
    # to compensate for earlier exclusion of objective columns
    UpperCamelCase      =			np.nanargmin(lowerCamelCase_							) + self.n_stages
    return row_idx, col_idx







   def 	lowerCamelCase_  (    self	:	int      ,      lowerCamelCase_	:	np.ndarray      ,      lowerCamelCase_	:	int      ,      lowerCamelCase_	:	int							):





    """simple docstring"""


    UpperCamelCase      =			tableau[row_idx].copy()

    UpperCamelCase      =			piv_row[col_idx]

    # Entry becomes 1
    piv_row *= 1 / piv_val

    # Variable in pivot column becomes basic, ie the only non-zero entry
    for idx, coeff in enumerate(tableau[:, col_idx]							):
     tableau[idx] += -coeff * piv_row
    UpperCamelCase      =			piv_row
    return tableau







   def 	lowerCamelCase_  (    self	:	int      ,      lowerCamelCase_	:	np.ndarray							):





    """simple docstring"""


    self.objectives.pop()

    if not self.objectives:
     return tableau

    # Slice containing ids for artificial columns
    UpperCamelCase      =			slice(-self.n_art_vars - 1      ,      -1							)

    # Delete the artificial variable columns
    UpperCamelCase      =			np.delete(lowerCamelCase_      ,      lowerCamelCase_      ,      axis=1							)

    # Delete the objective row of the first stage
    UpperCamelCase      =			np.delete(lowerCamelCase_      ,      0      ,      axis=0							)

    UpperCamelCase      =			1
    self.n_rows -= 1
    UpperCamelCase      =			0
    UpperCamelCase      =			False
    return tableau







   def 	lowerCamelCase_  (    self	:	Optional[int]							):





    """simple docstring"""


    for _ in range(100							):
     # Completion of each stage removes an objective. If both stages
     # are complete, then no objectives are left
     if not self.objectives:
      UpperCamelCase      =			self.generate_col_titles(
          self.n_vars      ,      self.n_slack      ,      self.n_art_vars							)

      # Find the values of each variable at optimal solution
      return self.interpret_tableau(self.tableau      ,      self.col_titles							)

     UpperCamelCase     ,    UpperCamelCase      =			self.find_pivot(self.tableau							)

     # If there are no more negative values in objective row
     if self.stop_iter:
      # Delete artificial variable columns and rows. Update attributes
      UpperCamelCase      =			self.change_stage(self.tableau							)
     else:
      UpperCamelCase      =			self.pivot(self.tableau      ,      lowerCamelCase_      ,      lowerCamelCase_							)
    return {}







   def 	lowerCamelCase_  (    self	:	Any      ,      lowerCamelCase_	:	np.ndarray      ,      lowerCamelCase_	:	list[str]							):





    """simple docstring"""


    UpperCamelCase      =			{"""P""": abs(tableau[0, -1]							)}

    for i in range(self.n_vars							):
     # Gives ids of nonzero entries in the ith column
     UpperCamelCase      =			np.nonzero(tableau[:, i]							)
     UpperCamelCase      =			len(nonzero[0]							)

     # First entry in the nonzero ids
     UpperCamelCase      =			nonzero[0][0]
     UpperCamelCase      =			tableau[nonzero_rowidx, i]

     # If there is only one nonzero value in column, which is one
     if n_nonzero == nonzero_val == 1:
      UpperCamelCase      =			tableau[nonzero_rowidx, -1]
      UpperCamelCase      =			rhs_val

        # Check for basic variables
    for title in col_titles:
     # Don't add RHS or slack variables to output dict
     if title[0] not in "R-s-a":
      output_dict.setdefault(lowerCamelCase_      ,      0							)
    return output_dict


if __name__ == "__main__":
     import doctest

     doctest.testmod()

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())
