import sys

input = sys.stdin.readline

sys.setrecursionlimit(10 ** 7)



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

graph = [[] for _ in range(N+1)]

for _ in range(M):

    x,y = list(map(int,input().split()))

    graph[x].append(y)



dp = [None] * (N+1)



def dfs(x):

    if dp[x] is not None:

        return dp[x]

    if graph[x]:

        dp[x] = 1 + max(dfs(y) for y in graph[x])

    else:

        dp[x] = 0

    return dp[x]



answer = max(dfs(x) for x in range(1,N+1))



print(answer)
import sys

read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



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

m = list(map(int,read().split()))

XY = list(zip(m,m))



in_edge = [[] for _ in range(N+1)]

out_edge = [[] for _ in range(N+1)]

for x,y in XY:

    out_edge[x].append(y)

    in_edge[y].append(x)



out_deg = [len(x) for x in out_edge]



stack = [i for i,x in enumerate(out_deg[1:],1) if x==0]



dp = [0] * (N+1)

while stack:

    c = stack.pop()

    for p in in_edge[c]:

        y = dp[c]+1

        if dp[p] < y:

            dp[p] = y

        out_deg[p] -= 1

        if not out_deg[p]:

            stack.append(p)



answer = max(dp)

print(answer)
import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**7)
N, M = list(map(int, input().split()))
graph = [[] for _ in range(N + 1)]
for _ in range(M):
    x, y = list(map(int, input().split()))
    graph[x].append(y)
dp = [None] * (N + 1)


def dfs(x):
    if dp[x] is not None:
        return dp[x]
    if graph[x]:
        dp[x] = 1 + max(dfs(y) for y in graph[x])
    else:
        dp[x] = 0
    return dp[x]


answer = max(dfs(x) for x in range(1, N + 1))
print(answer)

import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
N, M = list(map(int, readline().split()))
m = list(map(int, read().split()))
XY = list(zip(m, m))
in_edge = [[] for _ in range(N + 1)]
out_edge = [[] for _ in range(N + 1)]
for x, y in XY:
    out_edge[x].append(y)
    in_edge[y].append(x)
out_deg = [len(x) for x in out_edge]
stack = [i for i, x in enumerate(out_deg[1:], 1) if x == 0]
dp = [0] * (N + 1)
while stack:
    c = stack.pop()
    for p in in_edge[c]:
        y = dp[c] + 1
        if dp[p] < y:
            dp[p] = y
        out_deg[p] -= 1
        if not out_deg[p]:
            stack.append(p)
answer = max(dp)
print(answer)

-input = sys.stdin.readline -sys.setrecursionlimit(10**7) -N, M = list(map(int, input().split())) -graph = [[] for _ in range(N + 1)] -for _ in range(M): -    x, y = list(map(int, input().split())) -    graph[x].append(y) -dp = [None] * (N + 1) - - -def dfs(x): -    if dp[x] is not None: -        return dp[x] -    if graph[x]: -        dp[x] = 1 + max(dfs(y) for y in graph[x]) -    else: -        dp[x] = 0 -    return dp[x] - - -answer = max(dfs(x) for x in range(1, N + 1)) +read = sys.stdin.buffer.read +readline = sys.stdin.buffer.readline +readlines = sys.stdin.buffer.readlines +N, M = list(map(int, readline().split())) +m = list(map(int, read().split())) +XY = list(zip(m, m)) +in_edge = [[] for _ in range(N + 1)] +out_edge = [[] for _ in range(N + 1)] +for x, y in XY: +    out_edge[x].append(y) +    in_edge[y].append(x) +out_deg = [len(x) for x in out_edge] +stack = [i for i, x in enumerate(out_deg[1:], 1) if x == 0] +dp = [0] * (N + 1) +while stack: +    c = stack.pop() +    for p in in_edge[c]: +        y = dp[c] + 1 +        if dp[p] < y: +            dp[p] = y +        out_deg[p] -= 1 +        if not out_deg[p]: +            stack.append(p) +answer = max(dp)