






from __future__ import annotations
def        UpperCAmelCase      (   _lowercase,      _lowercase      ):


    '''simple docstring'''



    _lowercase     =	[None] * (len(_lowercase      ) + len(_lowercase      ))

    _lowercase     =	0  # pointer to current index for left Half
    _lowercase     =	0  # pointer to current index for the right Half
    _lowercase     =	0  # pointer to current index for the sorted array Half

    while pointera < len(_lowercase      ) and pointera < len(_lowercase      ):
        if left_half[pointera] < right_half[pointera]:
            _lowercase     =	left_half[pointera]
            pointera += 1
            index += 1
        else:
            _lowercase     =	right_half[pointera]
            pointera += 1
            index += 1
    while pointera < len(_lowercase      ):
        _lowercase     =	left_half[pointera]
        pointera += 1
        index += 1

    while pointera < len(_lowercase      ):
        _lowercase     =	right_half[pointera]
        pointera += 1
        index += 1

    return sorted_array
def        UpperCAmelCase      (   _lowercase      ):


    '''simple docstring'''



    if len(_lowercase      ) <= 1:
        return array
    # the actual formula to calculate the middle element = left + (right - left) // 2
    # this avoids integer overflow in case of large N
    _lowercase     =	0 + (len(_lowercase      ) - 0) // 2

    # Split the array into halves till the array length becomes equal to One
    # merge the arrays of single length returned by mergeSort function and
    # pass them into the merge arrays function which merges the array
    _lowercase     =	array[:middle]
    _lowercase     =	array[middle:]

    return merge(merge_sort(_lowercase      ),      merge_sort(_lowercase      )      )


if __name__ == "__main__":
   import doctest

   doctest.testmod()








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