import sys



sys.setrecursionlimit(1000000)





def dfs(v):

    if cache[v] > -1:

        return cache[v]

    lv = links[v]

    cache[v] = ret = max(list(map(dfs, lv))) + 1 if lv else 0

    return ret





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

sss = set(range(n))

links = [set() for _ in range(n)]

cache = [-1] * n

for line in sys.stdin.readlines():

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

    x -= 1

    y -= 1

    sss.discard(y)

    links[x].add(y)



print((max(list(map(dfs, sss)))))

import sys



sys.setrecursionlimit(1000000)





def dfs(v):

    if cache[v] > -1:

        return cache[v]

    lv = links[v]

    cache[v] = ret = max(list(map(dfs, lv))) + 1 if lv else 0

    return ret





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

links = [set() for _ in range(n)]

cache = [-1] * n

for line in sys.stdin.readlines():

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

    x -= 1

    y -= 1

    links[x].add(y)



print((max(list(map(dfs, list(range(n)))))))

import sys

sys.setrecursionlimit(1000000)


def dfs(v):
    if cache[v] > -1:
        return cache[v]
    lv = links[v]
    cache[v] = ret = max(list(map(dfs, lv))) + 1 if lv else 0
    return ret


n, m = list(map(int, input().split()))
sss = set(range(n))
links = [set() for _ in range(n)]
cache = [-1] * n
for line in sys.stdin.readlines():
    x, y = list(map(int, line.split()))
    x -= 1
    y -= 1
    sss.discard(y)
    links[x].add(y)
print((max(list(map(dfs, sss)))))

import sys

sys.setrecursionlimit(1000000)


def dfs(v):
    if cache[v] > -1:
        return cache[v]
    lv = links[v]
    cache[v] = ret = max(list(map(dfs, lv))) + 1 if lv else 0
    return ret


n, m = list(map(int, input().split()))
links = [set() for _ in range(n)]
cache = [-1] * n
for line in sys.stdin.readlines():
    x, y = list(map(int, line.split()))
    x -= 1
    y -= 1
    links[x].add(y)
print((max(list(map(dfs, list(range(n)))))))

-sss = set(range(n)) -    sss.discard(y) -print((max(list(map(dfs, sss))))) +print((max(list(map(dfs, list(range(n)))))))