# 根付き木に対して根から最大でどれだけかかるかを使う方法



import sys

sys.setrecursionlimit(1000000000)

input = sys.stdin.readline

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

co = [[] for i in range(n)] # 有効辺の向きを逆にした

for i in range(m):

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

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



dp = [-1] * n



def memo(v):

    if dp[v] != -1: #更新済

        return dp[v]



    for i in co[v]:

        x = memo(i) + 1

        if x > dp[v]:

            parent[v] = i + 1

            dp[v] = x



    return max(dp[v], 0)

# 経路復元

parent = [0] * n





ans = 0

for i in range(n):

    ans = max(ans, memo(i))



print(ans)
#解説AC



import sys

sys.setrecursionlimit(1000000000)

input = sys.stdin.readline



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

es=[[] for i in range(n)]

for i in range(m):

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

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



dp=[-1]*n



def memo(v):

    if dp[v]+1: #更新済 dp[v]!=-1

        return dp[v]

    a=0

    for i in es[v]:

        a=max(a,memo(i)+1)

    dp[v]=a

    return a



ans=0

for i in range(n):

    ans=max(ans,memo(i))



print(ans)

# 根付き木に対して根から最大でどれだけかかるかを使う方法
import sys

sys.setrecursionlimit(1000000000)
input = sys.stdin.readline
n, m = list(map(int, input().split()))
co = [[] for i in range(n)]  # 有効辺の向きを逆にした
for i in range(m):
    a, b = list(map(int, input().split()))
    co[b - 1].append(a - 1)
dp = [-1] * n


def memo(v):
    if dp[v] != -1:  # 更新済
        return dp[v]
    for i in co[v]:
        x = memo(i) + 1
        if x > dp[v]:
            parent[v] = i + 1
            dp[v] = x
    return max(dp[v], 0)


# 経路復元
parent = [0] * n
ans = 0
for i in range(n):
    ans = max(ans, memo(i))
print(ans)

# 解説AC
import sys

sys.setrecursionlimit(1000000000)
input = sys.stdin.readline
n, m = list(map(int, input().split()))
es = [[] for i in range(n)]
for i in range(m):
    x, y = list(map(int, input().split()))
    es[x - 1].append(y - 1)
dp = [-1] * n


def memo(v):
    if dp[v] + 1:  # 更新済 dp[v]!=-1
        return dp[v]
    a = 0
    for i in es[v]:
        a = max(a, memo(i) + 1)
    dp[v] = a
    return a


ans = 0
for i in range(n):
    ans = max(ans, memo(i))
print(ans)

-# 根付き木に対して根から最大でどれだけかかるかを使う方法 +# 解説AC -co = [[] for i in range(n)]  # 有効辺の向きを逆にした +es = [[] for i in range(n)] -    a, b = list(map(int, input().split())) -    co[b - 1].append(a - 1) +    x, y = list(map(int, input().split())) +    es[x - 1].append(y - 1) -    if dp[v] != -1:  # 更新済 +    if dp[v] + 1:  # 更新済 dp[v]!=-1 -    for i in co[v]: -        x = memo(i) + 1 -        if x > dp[v]: -            parent[v] = i + 1 -            dp[v] = x -    return max(dp[v], 0) +    a = 0 +    for i in es[v]: +        a = max(a, memo(i) + 1) +    dp[v] = a +    return a -# 経路復元 -parent = [0] * n