Buggy python submission (verdict: Time Limit Exceeded):
from sys import stdin
import math
import fractions
from collections import deque
import sys

# 再起の上限を変更
sys.setrecursionlimit(100000)

INF = 10 ** 10

# 深さ優先探索
def dfs(i):
    global is_visited
    global tsort_res

    if is_visited[i]:
        return 

    is_visited[i] = True
    for j in nextl[i]:
        dfs(j)
    
    # 帰りがけ順で追加
    # 追加は先頭に行う
    tsort_res.insert(0, i)


# トポロジカルソート
def tsort():
    for i in range(1, N+1):
        dfs(i)

if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]
    xv = [list(map(int, stdin.readline().rstrip().split())) for _ in range(M)]

    # トポロジカルソートで頂点iより後ろのパスの最大長
    dp = [0] * (N+1)

    # 頂点xから頂点vへの有向辺
    nextl = [[] for _ in range(N+1)]
    for x, v in xv:
        nextl[x].append(v)
    
    # トポロジカルソートされた結果の入るリスト
    tsort_res = []

    is_visited = [False] * (N+1)

    tsort()

    # 今回は逆順に使うのでリバースする
    # 汎用性のため、dfsでは先頭に追加するようにしている
    tsort_res = tsort_res[::-1]

    for x in tsort_res:
        for v in nextl[x]:
            dp[x] = max(dp[x], dp[v] + 1)


    # for DEBUG
    #print(dp)
    print(max(dp))

Fixed submission:
from sys import stdin
import math
import fractions
from collections import deque
import sys

# 再起の上限を変更
sys.setrecursionlimit(100000)

INF = 10 ** 10

# 深さ優先探索
def dfs(i):
    global is_visited
    global tsort_res

    if is_visited[i]:
        return 

    is_visited[i] = True
    for j in nextl[i]:
        dfs(j)
    
    # 帰りがけ順で追加
    # 追加は先頭に行う
    tsort_res.appendleft(i)


# トポロジカルソート
def tsort():
    for i in range(1, N+1):
        dfs(i)

if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]

    # トポロジカルソートで頂点iより後ろのパスの最大長
    dp = [0] * (N+1)

    # 頂点xから頂点vへの有向辺
    nextl = [[] for _ in range(N+1)]
    for _ in range(M):
        x, v = list(map(int, stdin.readline().rstrip().split()))
        nextl[x].append(v)
    
    # トポロジカルソートされた結果の入るリスト
    tsort_res = deque([])

    is_visited = [False] * (N+1)

    tsort()

    # 今回は逆順に使うのでリバースする
    # 汎用性のため、dfsでは先頭に追加するようにしている
    tsort_res = list(tsort_res)[::-1]

    for x in tsort_res:
        for v in nextl[x]:
            dp[x] = max(dp[x], dp[v] + 1)


    # for DEBUG
    #print(dp)
    print(max(dp))

Buggy python submission (verdict: Runtime Error):
from sys import stdin
import math
import fractions
from collections import deque

INF = 10 ** 10

# 深さ優先探索
def dfs(i):
    global is_visited
    global tsort_res

    if is_visited[i]:
        return 

    is_visited[i] = True
    for j in nextl[i]:
        dfs(j)
    
    # 帰りがけ順で追加
    # 追加は先頭に行う
    tsort_res.insert(0, i)


# トポロジカルソート
def tsort():
    for i in range(1, N+1):
        dfs(i)

if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]
    xv = [list(map(int, stdin.readline().rstrip().split())) for _ in range(M)]

    # トポロジカルソートで頂点iより後ろのパスの最大長
    dp = [0] * (N+1)

    # 頂点xから頂点vへの有向辺
    nextl = [[] for _ in range(N+1)]
    for x, v in xv:
        nextl[x].append(v)
    
    # トポロジカルソートされた結果の入るリスト
    tsort_res = []

    is_visited = [False] * (N+1)

    tsort()

    # 今回は逆順に使うのでリバースする
    # 汎用性のため、dfsでは先頭に追加するようにしている
    tsort_res = tsort_res[::-1]

    for x in tsort_res:
        for v in nextl[x]:
            dp[x] = max(dp[x], dp[v] + 1)


    # for DEBUG
    #print(dp)
    print(max(dp))

Fixed submission:
from sys import stdin
import math
import fractions
from collections import deque
import sys

# 再起の上限を変更
sys.setrecursionlimit(100000)

INF = 10 ** 10

# 深さ優先探索
def dfs(i):
    global is_visited
    global tsort_res

    if is_visited[i]:
        return 

    is_visited[i] = True
    for j in nextl[i]:
        dfs(j)
    
    # 帰りがけ順で追加
    # 追加は先頭に行う
    tsort_res.appendleft(i)


# トポロジカルソート
def tsort():
    for i in range(1, N+1):
        dfs(i)

if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]

    # トポロジカルソートで頂点iより後ろのパスの最大長
    dp = [0] * (N+1)

    # 頂点xから頂点vへの有向辺
    nextl = [[] for _ in range(N+1)]
    for _ in range(M):
        x, v = list(map(int, stdin.readline().rstrip().split()))
        nextl[x].append(v)
    
    # トポロジカルソートされた結果の入るリスト
    tsort_res = deque([])

    is_visited = [False] * (N+1)

    tsort()

    # 今回は逆順に使うのでリバースする
    # 汎用性のため、dfsでは先頭に追加するようにしている
    tsort_res = list(tsort_res)[::-1]

    for x in tsort_res:
        for v in nextl[x]:
            dp[x] = max(dp[x], dp[v] + 1)


    # for DEBUG
    #print(dp)
    print(max(dp))

Buggy python submission (verdict: Time Limit Exceeded):
from sys import stdin
import math
import fractions
from collections import deque

INF = 10 ** 10

# 再帰的に更新
def update_dp(dp, n):
    for i in nextl[n]:
        if dp[i] < dp[n] + 1:
            dp[i] = dp[n]+1
            update_dp(dp, i)


if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]
    xv = [list(map(int, stdin.readline().rstrip().split())) for _ in range(M)]

    # iにいくまでの最長のパス
    dp = [0] * (N+1)

    # iのnextを保持するリスト
    nextl = [[] for _ in range(N+1)]

    for x, v in xv:
        if dp[v] < dp[x] + 1:
            dp[v] = dp[x]+1
            update_dp(dp, v)
        nextl[x].append(v)

    # for DEBUG
    #print(dp)
    print(max(dp))

Fixed submission:
from sys import stdin
import math
import fractions
from collections import deque
import sys

# 再起の上限を変更
sys.setrecursionlimit(100000)

INF = 10 ** 10

# 深さ優先探索
def dfs(i):
    global is_visited
    global tsort_res

    if is_visited[i]:
        return 

    is_visited[i] = True
    for j in nextl[i]:
        dfs(j)
    
    # 帰りがけ順で追加
    # 追加は先頭に行う
    tsort_res.appendleft(i)


# トポロジカルソート
def tsort():
    for i in range(1, N+1):
        dfs(i)

if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]

    # トポロジカルソートで頂点iより後ろのパスの最大長
    dp = [0] * (N+1)

    # 頂点xから頂点vへの有向辺
    nextl = [[] for _ in range(N+1)]
    for _ in range(M):
        x, v = list(map(int, stdin.readline().rstrip().split()))
        nextl[x].append(v)
    
    # トポロジカルソートされた結果の入るリスト
    tsort_res = deque([])

    is_visited = [False] * (N+1)

    tsort()

    # 今回は逆順に使うのでリバースする
    # 汎用性のため、dfsでは先頭に追加するようにしている
    tsort_res = list(tsort_res)[::-1]

    for x in tsort_res:
        for v in nextl[x]:
            dp[x] = max(dp[x], dp[v] + 1)


    # for DEBUG
    #print(dp)
    print(max(dp))

Buggy python submission (verdict: Time Limit Exceeded):
from sys import stdin
import math
import fractions
from collections import deque

INF = 10 ** 10

# 再帰的に更新
def update_dp(dp, n):
    for i in nextl[n]:
        dp[i] = max(dp[i], dp[n]+1)
        update_dp(dp, i)


if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]
    xv = [list(map(int, stdin.readline().rstrip().split())) for _ in range(M)]

    # iにいくまでの最長のパス
    dp = [0] * (N+1)

    # iのnextを保持するリスト
    nextl = [[] for _ in range(N+1)]

    for x, v in xv:
        dp[v] = max(dp[v], dp[x]+1)
        update_dp(dp, v)
        nextl[x].append(v)

    # for DEBUG
    #print(dp)
    print(max(dp))

Fixed submission:
from sys import stdin
import math
import fractions
from collections import deque
import sys

# 再起の上限を変更
sys.setrecursionlimit(100000)

INF = 10 ** 10

# 深さ優先探索
def dfs(i):
    global is_visited
    global tsort_res

    if is_visited[i]:
        return 

    is_visited[i] = True
    for j in nextl[i]:
        dfs(j)
    
    # 帰りがけ順で追加
    # 追加は先頭に行う
    tsort_res.appendleft(i)


# トポロジカルソート
def tsort():
    for i in range(1, N+1):
        dfs(i)

if __name__ == "__main__":

    N, M = [int(x) for x in stdin.readline().rstrip().split()]

    # トポロジカルソートで頂点iより後ろのパスの最大長
    dp = [0] * (N+1)

    # 頂点xから頂点vへの有向辺
    nextl = [[] for _ in range(N+1)]
    for _ in range(M):
        x, v = list(map(int, stdin.readline().rstrip().split()))
        nextl[x].append(v)
    
    # トポロジカルソートされた結果の入るリスト
    tsort_res = deque([])

    is_visited = [False] * (N+1)

    tsort()

    # 今回は逆順に使うのでリバースする
    # 汎用性のため、dfsでは先頭に追加するようにしている
    tsort_res = list(tsort_res)[::-1]

    for x in tsort_res:
        for v in nextl[x]:
            dp[x] = max(dp[x], dp[v] + 1)


    # for DEBUG
    #print(dp)
    print(max(dp))