Buggy python submission (verdict: Runtime Error):
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

from functools import lru_cache

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

@lru_cache(maxsize=None)
def dp(p):
    return max((1 + dp(c) for c in E[p]), default=0)

print(max(dp(p) for p in range(1, N + 1)))

Fixed submission:
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    if p in memo:
        return memo[p]

    memo[p] = max((1 + dp(c) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))

Buggy python submission (verdict: Runtime Error):
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

from functools import lru_cache

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

@lru_cache
def dp(p):
    return max((1 + dp(c) for c in E[p]), default=0)

print(max(dp(p) for p in range(1, N + 1)))

Fixed submission:
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    if p in memo:
        return memo[p]

    memo[p] = max((1 + dp(c) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))

Buggy python submission (verdict: Runtime Error):
N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    if p not in memo:
        memo[p] = max((1 + dp(c) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))

Fixed submission:
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    if p in memo:
        return memo[p]

    memo[p] = max((1 + dp(c) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))

Buggy python submission (verdict: Runtime Error):
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    return memo.get(p, max((1 + dp(c) for c in E[p]), default=0))

print(max(dp(p) for p in range(1, N + 1)))

Fixed submission:
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    if p in memo:
        return memo[p]

    memo[p] = max((1 + dp(c) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))

Buggy python submission (verdict: Runtime Error):
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    memo[p] = max((1 + memo.get(c, dp(c)) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))

Fixed submission:
from sys import setrecursionlimit
setrecursionlimit(10 ** 5 + 10)

N, M, *XY = map(int, open(0).read().split())

E = [[] for _ in range(N + 1)]
for x, y in zip(*[iter(XY)] * 2):
    E[x].append(y)

memo = {}
def dp(p):
    if p in memo:
        return memo[p]

    memo[p] = max((1 + dp(c) for c in E[p]), default=0)
    return memo[p]

print(max(dp(p) for p in range(1, N + 1)))