import sys

sys.setrecursionlimit(10**9)

from collections import defaultdict



n,m = list(map(int,input().split()))

d = defaultdict(list)

for i in range(m):

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

    d[x-1].append(y-1)



dp = [-1]*n



def rec(v):

    if dp[v] != -1:

        return dp[v]

    res = 0

    for nv in d[v]:

        res = max(res,rec(nv)+1)

    dp[v] = res

    return res



res = 0

for v in range(n):

    res = max(res,rec(v))

print(res)
from collections import defaultdict, deque

n,m = list(map(int,input().split()))

d = defaultdict(list)

deg = [0]*n  # 各頂点の入次数



for i in range(m):

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

    d[x-1].append(y-1)

    deg[y-1] += 1



que = deque([])

for v in range(n):

    if deg[v] == 0:

        que.append(v)



dp = [0]*100100



while que:

    v = que.popleft()

    for nv in d[v]:

        deg[nv] -= 1  # エッジ(v,nv)を破壊

        if deg[nv] == 0:

            que.append(nv)  # 入次数が0になったらキューに追加

            dp[nv] = max(dp[nv],dp[v]+1)  # ソースからnvまでの最長距離を確定



res = 0

for v in range(n):

    res = max(res,dp[v])

print(res)
import sys

sys.setrecursionlimit(10**9)
from collections import defaultdict

n, m = list(map(int, input().split()))
d = defaultdict(list)
for i in range(m):
    x, y = list(map(int, input().split()))
    d[x - 1].append(y - 1)
dp = [-1] * n


def rec(v):
    if dp[v] != -1:
        return dp[v]
    res = 0
    for nv in d[v]:
        res = max(res, rec(nv) + 1)
    dp[v] = res
    return res


res = 0
for v in range(n):
    res = max(res, rec(v))
print(res)

from collections import defaultdict, deque

n, m = list(map(int, input().split()))
d = defaultdict(list)
deg = [0] * n  # 各頂点の入次数
for i in range(m):
    x, y = list(map(int, input().split()))
    d[x - 1].append(y - 1)
    deg[y - 1] += 1
que = deque([])
for v in range(n):
    if deg[v] == 0:
        que.append(v)
dp = [0] * 100100
while que:
    v = que.popleft()
    for nv in d[v]:
        deg[nv] -= 1  # エッジ(v,nv)を破壊
        if deg[nv] == 0:
            que.append(nv)  # 入次数が0になったらキューに追加
            dp[nv] = max(dp[nv], dp[v] + 1)  # ソースからnvまでの最長距離を確定
res = 0
for v in range(n):
    res = max(res, dp[v])
print(res)

-import sys - -sys.setrecursionlimit(10**9) -from collections import defaultdict +from collections import defaultdict, deque +deg = [0] * n  # 各頂点の入次数 -dp = [-1] * n - - -def rec(v): -    if dp[v] != -1: -        return dp[v] -    res = 0 +    deg[y - 1] += 1 +que = deque([]) +for v in range(n): +    if deg[v] == 0: +        que.append(v) +dp = [0] * 100100 +while que: +    v = que.popleft() -        res = max(res, rec(nv) + 1) -    dp[v] = res -    return res - - +        deg[nv] -= 1  # エッジ(v,nv)を破壊 +        if deg[nv] == 0: +            que.append(nv)  # 入次数が0になったらキューに追加 +            dp[nv] = max(dp[nv], dp[v] + 1)  # ソースからnvまでの最長距離を確定 -    res = max(res, rec(v)) +    res = max(res, dp[v])