Problem p02925 (python)

Fixed submission:
# ABC139E - League
from collections import deque


def main():
    N, *A = map(int, open(0).read().split())
    B = {}
    for i in range(N):
        x = i * (N - 1)
        B[i + 1] = deque(A[x : x + N - 1])
    ans, cnt, matched = 0, 0, set()
    q = [i for i in range(1, N + 1)]
    while q:
        ans += 1
        next_q = []
        for i in q:
            if i in B and i not in matched:
                x = B[i][0]
                if x in B and x not in matched and B[x][0] == i:
                    B[i].popleft(), B[x].popleft()
                    matched |= {i, x}
                    cnt += 1
                    if not B[i]:
                        del B[i]
                    else:
                        next_q += [i]
                    if not B[x]:
                        del B[x]
                    else:
                        next_q += [x]
        q = next_q
        matched = set()
    flg = cnt == N * (N - 1) // 2
    print(ans if flg else -1)


if __name__ == "__main__":
    main()

Buggy submission (verdict: Runtime Error):
from collections import deque
from typing import List, Optional, Tuple


def cycle_detectable_topological_sort(
    graph: List[List[int]], in_degrees: List[int], first_index: int = 0
) -> Tuple[Optional[List[int]], Optional[List[int]]]:
    """Topological sort that uses Kahn's algorithm and detects a loop (DAG or not).
    Returns:
        if the given graph is DAG, a list of sorted vertices and a list of depths of
        each vertex is returned.
        Otherwise, (None, None) is returned.
    """
    V = len(graph) + first_index
    order = []
    depths = [-1] * V  # depths[i] := the length of the longest path to V_i
    for i in range(first_index, V):
        if not in_degrees[i]:
            order.append(i)
            depths[i] = 0

    queue = deque(order)
    while queue:
        u = queue.popleft()
        cur_depth = depths[u]
        for v in graph[u]:
            in_degrees[v] -= 1
            if not in_degrees[v]:
                depths[v] = max(depths[v], cur_depth + 1)
                queue.append(v), order.append(v)
    return (order, depths) if len(order) + first_index == V else (None, None)


def abc139_e():
    N, *A = map(int, open(0).read().split())

    ids = [[-1] * (N + 1) for _ in range(N + 1)]
    cur_id = 0
    for i in range(1, N + 1):
        for j in range(i + 1, N + 1):
            ids[i][j] = ids[j][i] = cur_id
            cur_id += 1

    graph = [[] for _ in range(N * (N - 1) // 2)]
    in_degrees = [0] * (N * (N - 1) // 2)
    for i, a in enumerate(zip(*[iter(A)] * (N - 1)), 1):
        prev_id = -1
        for j in a:
            cur_id = ids[i][j]
            if prev_id != -1:
                graph[prev_id].append(cur_id)
                in_degrees[cur_id] += 1
            prev_id = cur_id

    _, depths = cycle_detectable_topological_sort(graph, in_degrees, 1)
    print(max(depths) + 1 if depths is not None else -1)


if __name__ == "__main__":
    abc139_e()

Buggy submission (verdict: Runtime Error):
# E - League
import sys
from collections import deque
from typing import Deque, List

readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readline


def main():
    N = int(readline())
    A: List[Deque[int]] = [deque()] + list(
        deque(map(int, line.split())) for line in readlines()
    )
    matched_games_cnt = 0
    next_games_opponent, last_games_day = [0] * (N + 1), [0] * (N + 1)
    queue = deque(list(range(1, N + 1)))
    while queue:
        player = queue.popleft()
        if not A[player]:  # The player has finished all games.
            continue
        opponent = A[player].popleft()

        # The opponent will have another game before playing against x.
        if next_games_opponent[opponent] != player:
            next_games_opponent[player] = opponent
            continue

        # The opponent's next game is against the player and vice versa.
        matched_games_cnt += 1
        last_games_day[player] = last_games_day[opponent] = (
            max(last_games_day[player], last_games_day[opponent]) + 1
        )
        # No next game is currently planned.
        next_games_opponent[player] = next_games_opponent[opponent] = 0
        queue.append(player), queue.append(opponent)

    print(max(last_games_day) if matched_games_cnt == N * (N - 1) // 2 else -1)


if __name__ == "__main__":
    main()