N, M = list(map(int, input().split()))

edge = [[] for _ in range(N)]

to = [False]*N

for i in range(M):

  a,b = list(map(int, input().split()))

  edge[a-1].append(b-1)

  to[b-1] = True



import sys

sys.setrecursionlimit(10**8)



def dfs(v):

  if lis[v]>=0:

    return lis[v]

  if len(edge[v])==0:

    lis[v] = 1

    return 1

  ans = 0

  for u in edge[v]:

    ans = max(ans, dfs(u))

  lis[v] = ans+1

  return ans+1



ans = 0

lis = [-1]*N

for r in range(N):

  if to[r]==False:

    ans = max(ans, dfs(r)-1)

print(ans)
import sys

input = sys.stdin.readline



N, M = list(map(int, input().split()))

edge = [[] for _ in range(N)]

for i in range(M):

  a,b = list(map(int, input().split()))

  edge[a-1].append(b-1)



def dfs(start):

  stack = [start]

  while stack:

    v = stack[-1]

    marker = 0

    path_l[v] = 0

    for u in edge[v]:

      if path_l[u]==-1: #子へ降ろす

        marker = 1

        stack.append(u)

      else: #子から吸い上げる

        #吸い上げる際の個々の処理

        path_l[v] = max(path_l[v], path_l[u]+1)

    if marker==0:

      stack.pop()

  return



path_l = [-1]*N

for i in range(N):

  if path_l[i]==-1:

    dfs(i)

ans = max(path_l)

print(ans)

N, M = list(map(int, input().split()))
edge = [[] for _ in range(N)]
to = [False] * N
for i in range(M):
    a, b = list(map(int, input().split()))
    edge[a - 1].append(b - 1)
    to[b - 1] = True
import sys

sys.setrecursionlimit(10**8)


def dfs(v):
    if lis[v] >= 0:
        return lis[v]
    if len(edge[v]) == 0:
        lis[v] = 1
        return 1
    ans = 0
    for u in edge[v]:
        ans = max(ans, dfs(u))
    lis[v] = ans + 1
    return ans + 1


ans = 0
lis = [-1] * N
for r in range(N):
    if to[r] == False:
        ans = max(ans, dfs(r) - 1)
print(ans)

import sys

input = sys.stdin.readline
N, M = list(map(int, input().split()))
edge = [[] for _ in range(N)]
for i in range(M):
    a, b = list(map(int, input().split()))
    edge[a - 1].append(b - 1)


def dfs(start):
    stack = [start]
    while stack:
        v = stack[-1]
        marker = 0
        path_l[v] = 0
        for u in edge[v]:
            if path_l[u] == -1:  # 子へ降ろす
                marker = 1
                stack.append(u)
            else:  # 子から吸い上げる
                # 吸い上げる際の個々の処理
                path_l[v] = max(path_l[v], path_l[u] + 1)
        if marker == 0:
            stack.pop()
    return


path_l = [-1] * N
for i in range(N):
    if path_l[i] == -1:
        dfs(i)
ans = max(path_l)
print(ans)

+import sys + +input = sys.stdin.readline -to = [False] * N -    to[b - 1] = True -import sys - -sys.setrecursionlimit(10**8) -def dfs(v): -    if lis[v] >= 0: -        return lis[v] -    if len(edge[v]) == 0: -        lis[v] = 1 -        return 1 -    ans = 0 -    for u in edge[v]: -        ans = max(ans, dfs(u)) -    lis[v] = ans + 1 -    return ans + 1 +def dfs(start): +    stack = [start] +    while stack: +        v = stack[-1] +        marker = 0 +        path_l[v] = 0 +        for u in edge[v]: +            if path_l[u] == -1:  # 子へ降ろす +                marker = 1 +                stack.append(u) +            else:  # 子から吸い上げる +                # 吸い上げる際の個々の処理 +                path_l[v] = max(path_l[v], path_l[u] + 1) +        if marker == 0: +            stack.pop() +    return -ans = 0 -lis = [-1] * N -for r in range(N): -    if to[r] == False: -        ans = max(ans, dfs(r) - 1) +path_l = [-1] * N +for i in range(N): +    if path_l[i] == -1: +        dfs(i) +ans = max(path_l)