import sys





def recursion_g(eges, length, f):

    if length[f] != -1:

        return length[f]

    memo = [0]

    for t in eges[f]:

        memo.append(recursion_g(eges, length, t) + 1)

    length[f] = max(memo)

    return length[f]





def p_g():

    sys.setrecursionlimit(10 ** 6)

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

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

    length = [-1] * N

    for _ in range(M):

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

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



    for i in range(N):

        recursion_g(edges, length, i)

    print((max(length)))





if __name__ == '__main__':

    p_g()

from collections import deque





def p_g_dp():

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

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

    ins = [0] * N

    for _ in range(M):

        f, t = list(map(int, input().split()))

        outs[f - 1].append(t - 1)

        ins[t - 1] += 1

    q = deque(t for t in range(N) if ins[t] == 0)

    res = []

    dp = [0] * N

    while q:

        f = q.popleft()

        res.append(f)

        for t in outs[f]:

            ins[t] -= 1

            if ins[t] == 0:

                q.append(t)

                dp[t] = max(dp[t], dp[f] + 1)

    print((max(dp)))





if __name__ == '__main__':

    p_g_dp()

import sys


def recursion_g(eges, length, f):
    if length[f] != -1:
        return length[f]
    memo = [0]
    for t in eges[f]:
        memo.append(recursion_g(eges, length, t) + 1)
    length[f] = max(memo)
    return length[f]


def p_g():
    sys.setrecursionlimit(10**6)
    N, M = list(map(int, input().split()))
    edges = [[] for _ in range(N)]
    length = [-1] * N
    for _ in range(M):
        x, y = list(map(int, input().split()))
        edges[x - 1].append(y - 1)
    for i in range(N):
        recursion_g(edges, length, i)
    print((max(length)))


if __name__ == "__main__":
    p_g()

from collections import deque


def p_g_dp():
    N, M = list(map(int, input().split()))
    outs = [[] for _ in range(N)]
    ins = [0] * N
    for _ in range(M):
        f, t = list(map(int, input().split()))
        outs[f - 1].append(t - 1)
        ins[t - 1] += 1
    q = deque(t for t in range(N) if ins[t] == 0)
    res = []
    dp = [0] * N
    while q:
        f = q.popleft()
        res.append(f)
        for t in outs[f]:
            ins[t] -= 1
            if ins[t] == 0:
                q.append(t)
                dp[t] = max(dp[t], dp[f] + 1)
    print((max(dp)))


if __name__ == "__main__":
    p_g_dp()

-import sys +from collections import deque -def recursion_g(eges, length, f): -    if length[f] != -1: -        return length[f] -    memo = [0] -    for t in eges[f]: -        memo.append(recursion_g(eges, length, t) + 1) -    length[f] = max(memo) -    return length[f] - - -def p_g(): -    sys.setrecursionlimit(10**6) +def p_g_dp(): -    edges = [[] for _ in range(N)] -    length = [-1] * N +    outs = [[] for _ in range(N)] +    ins = [0] * N -        x, y = list(map(int, input().split())) -        edges[x - 1].append(y - 1) -    for i in range(N): -        recursion_g(edges, length, i) -    print((max(length))) +        f, t = list(map(int, input().split())) +        outs[f - 1].append(t - 1) +        ins[t - 1] += 1 +    q = deque(t for t in range(N) if ins[t] == 0) +    res = [] +    dp = [0] * N +    while q: +        f = q.popleft() +        res.append(f) +        for t in outs[f]: +            ins[t] -= 1 +            if ins[t] == 0: +                q.append(t) +                dp[t] = max(dp[t], dp[f] + 1) +    print((max(dp))) -    p_g() +    p_g_dp()