Buggy python submission (verdict: Runtime Error):
import sys
 
sys.setrecursionlimit(150000)sys.setrecursionlimit(150000)

def gdp(n, dp, G):
    if dp[n]!=-1:
        return dp[n]
 
    if G[n]==[]:
        dp[n]=0
        return 0
 
    for i in G[n]:
        ll=gdp(i, dp, G)
        if dp[n]<ll+1:
            dp[n]=ll+1
 
    return dp[n]
 
def solve(N: int, M: int, x: "List[int]", y: "List[int]"):
    G=[[] for _ in range(N)]
    for i in range(M):
        G[x[i]-1].append(y[i]-1)
 
    dp=[-1]*N
 
    print(max(gdp(i, dp, G) for i in range(N)))
 
    return
 
 
# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    x = [int()] * (M)  # type: "List[int]"
    y = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        x[i] = int(next(tokens))
        y[i] = int(next(tokens))
    solve(N, M, x, y)
 
if __name__ == '__main__':
    main()

Fixed submission:
#!/usr/bin/env python3
import sys
 
sys.setrecursionlimit(150000)

def gdp(n, dp, G):
    if dp[n]!=-1:
        return dp[n]
 
    if G[n]==[]:
        dp[n]=0
        return 0
 
    for i in G[n]:
        ll=gdp(i, dp, G)
        if dp[n]<ll+1:
            dp[n]=ll+1
 
    return dp[n]
 
def solve(N: int, M: int, x: "List[int]", y: "List[int]"):
    G=[[] for _ in range(N)]
    for i in range(M):
        G[x[i]-1].append(y[i]-1)
 
    dp=[-1]*N
 
    print(max(gdp(i, dp, G) for i in range(N)))
 
    return
 
 
# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    x = [int()] * (M)  # type: "List[int]"
    y = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        x[i] = int(next(tokens))
        y[i] = int(next(tokens))
    solve(N, M, x, y)
 
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys


def gdp(n, dp, G):
    if dp[n]!=-1:
        return dp[n]

    if G[n]==[]:
        dp[n]=0
        return 0

    for i in G[n]:
        ll=gdp(i, dp, G)
        if dp[n]<ll+1:
            dp[n]=ll+1

    return dp[n]

def solve(N: int, M: int, x: "List[int]", y: "List[int]"):
    G=[[] for _ in range(N)]
    for i in range(M):
        G[x[i]-1].append(y[i]-1)

    dp=[-1]*N

    print(max(gdp(i, dp, G) for i in range(N)))

    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    x = [int()] * (M)  # type: "List[int]"
    y = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        x[i] = int(next(tokens))
        y[i] = int(next(tokens))
    solve(N, M, x, y)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys
 
sys.setrecursionlimit(150000)

def gdp(n, dp, G):
    if dp[n]!=-1:
        return dp[n]
 
    if G[n]==[]:
        dp[n]=0
        return 0
 
    for i in G[n]:
        ll=gdp(i, dp, G)
        if dp[n]<ll+1:
            dp[n]=ll+1
 
    return dp[n]
 
def solve(N: int, M: int, x: "List[int]", y: "List[int]"):
    G=[[] for _ in range(N)]
    for i in range(M):
        G[x[i]-1].append(y[i]-1)
 
    dp=[-1]*N
 
    print(max(gdp(i, dp, G) for i in range(N)))
 
    return
 
 
# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    x = [int()] * (M)  # type: "List[int]"
    y = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        x[i] = int(next(tokens))
        y[i] = int(next(tokens))
    solve(N, M, x, y)
 
if __name__ == '__main__':
    main()