Buggy python submission (verdict: Time Limit Exceeded):
class DirectedGraph:
    def __init__(self, adj):
        self.n = len(adj)
        self.adj = adj
        self.is_asyclic = False
        self.max_path_len = None

    def topological_sort(self):
        indegree = [0] * self.n
        for i, vs in enumerate(self.adj):
            for dest in vs:
                indegree[dest] += 1
        zero_v = []
        for v, indeg in enumerate(indegree):
            if indeg == 0:
                zero_v.append(v)
        max_path_len = 1
        tp_sorted = []
        to_be_added = []
        while True:
            while zero_v:
                v = zero_v.pop()
                tp_sorted.append(v)
                for dest in self.adj[v]:
                    indegree[dest] -= 1
                    if indegree[dest] == 0:
                        to_be_added.append(dest)
            if len(to_be_added) > 0:
                zero_v += to_be_added
                to_be_added = []
                max_path_len += 1
            else:
                break
        if len(tp_sorted) == self.n:
            self.is_asyclic = True
            self.max_path_len = max_path_len
            return tp_sorted
        else:
            self.is_asyclic = False
            return None

if __name__ == "__main__":
    n = int(input())
    dic = {}
    itr = 0
    for i in range(n):
        for j in range(i+1, n):
            dic[i*n + j] = itr
            itr += 1
    edge = [[] for _ in range(n * (n-1) // 2)]
    for i in range(n):
        a = [int(item) - 1 for item in input().split()]
        for j1, j2 in zip(a, a[1:]):
            if i < j1:
                u = i * n + j1 
            else:
                u = j1 * n + i 
            if i < j2:
                v = i * n + j2 
            else:
                v = j2 * n + i 
            edge[dic[u]].append(dic[v])

    DG = DirectedGraph(edge)
    tps = DG.topological_sort()

    if DG.is_asyclic:
        print(DG.max_path_len)
    else:
        print(-1)

Fixed submission:
class DirectedGraph:
    def __init__(self, adj):
        self.n = len(adj)
        self.adj = adj
        self.is_asyclic = False
        self.max_path_len = None

    def topological_sort(self):
        indegree = [0] * self.n
        for i, vs in enumerate(self.adj):
            for dest in vs:
                indegree[dest] += 1
        zero_v = []
        for v, indeg in enumerate(indegree):
            if indeg == 0:
                zero_v.append(v)
        max_path_len = 1
        tp_sorted = []
        to_be_added = []
        while True:
            while zero_v:
                v = zero_v.pop()
                tp_sorted.append(v)
                for dest in self.adj[v]:
                    indegree[dest] -= 1
                    if indegree[dest] == 0:
                        to_be_added.append(dest)
            if len(to_be_added) > 0:
                zero_v += to_be_added
                to_be_added = []
                max_path_len += 1
            else:
                break
        if len(tp_sorted) == self.n:
            self.is_asyclic = True
            self.max_path_len = max_path_len
            return tp_sorted
        else:
            self.is_asyclic = False
            return None

if __name__ == "__main__":
    n = int(input())
    dic = {}
    itr = 0
    for i in range(n):
        for j in range(i+1, n):
            dic[i*n + j] = itr
            itr += 1
    edge = [[] for _ in range(n * (n-1) // 2)]
    for i in range(n):
        a = [int(item) - 1 for item in input().split()]
        for j1, j2 in zip(a, a[1:]):
            if i < j1:
                u = i * n + j1 
            else:
                u = j1 * n + i 
            if i < j2:
                v = i * n + j2 
            else:
                v = j2 * n + i 
            edge[dic[u]].append(dic[v])

    DG = DirectedGraph(edge)
    tps = DG.topological_sort()

    if DG.is_asyclic:
        print(DG.max_path_len)
    else:
        print(-1)

Buggy python submission (verdict: Time Limit Exceeded):
n = int(input())
a_s = [] 
for i in range(n):
    a_s.append([int(item) - 1 for item in input().split()])

total = n * (n - 1) // 2
days = 0
itrs = [0] * n
fights = 0

while True:
    wants = set()
    has_match = False
    for item in range(n):
        idx = itrs[item]
        if idx == n - 1:
            continue
        want = a_s[item][idx]
        # Check there is match or not
        if a_s[want][itrs[want]] == item:
            has_match = True
            if item < want:
                wants.add((item, want))
            else:
                wants.add((want, item))
    if not has_match:
        break
    # Process match
    for a, b in wants:
        itrs[a] += 1
        itrs[b] += 1
        fights += 1
    days += 1
    if days > total:
        print(-1)
        exit()

if fights == total:
    print(days)
else:
    print(-1)

Fixed submission:
class DirectedGraph:
    def __init__(self, adj):
        self.n = len(adj)
        self.adj = adj
        self.is_asyclic = False
        self.max_path_len = None

    def topological_sort(self):
        indegree = [0] * self.n
        for i, vs in enumerate(self.adj):
            for dest in vs:
                indegree[dest] += 1
        zero_v = []
        for v, indeg in enumerate(indegree):
            if indeg == 0:
                zero_v.append(v)
        max_path_len = 1
        tp_sorted = []
        to_be_added = []
        while True:
            while zero_v:
                v = zero_v.pop()
                tp_sorted.append(v)
                for dest in self.adj[v]:
                    indegree[dest] -= 1
                    if indegree[dest] == 0:
                        to_be_added.append(dest)
            if len(to_be_added) > 0:
                zero_v += to_be_added
                to_be_added = []
                max_path_len += 1
            else:
                break
        if len(tp_sorted) == self.n:
            self.is_asyclic = True
            self.max_path_len = max_path_len
            return tp_sorted
        else:
            self.is_asyclic = False
            return None

if __name__ == "__main__":
    n = int(input())
    dic = {}
    itr = 0
    for i in range(n):
        for j in range(i+1, n):
            dic[i*n + j] = itr
            itr += 1
    edge = [[] for _ in range(n * (n-1) // 2)]
    for i in range(n):
        a = [int(item) - 1 for item in input().split()]
        for j1, j2 in zip(a, a[1:]):
            if i < j1:
                u = i * n + j1 
            else:
                u = j1 * n + i 
            if i < j2:
                v = i * n + j2 
            else:
                v = j2 * n + i 
            edge[dic[u]].append(dic[v])

    DG = DirectedGraph(edge)
    tps = DG.topological_sort()

    if DG.is_asyclic:
        print(DG.max_path_len)
    else:
        print(-1)

Buggy python submission (verdict: Time Limit Exceeded):
n = int(input())
a_s = [] 
for i in range(n):
    a_s.append([int(item) - 1 for item in input().split()])

total = n * (n - 1) // 2
days = 0
itrs = [0] * n
fights = 0

while True:
    wants = set()
    has_match = False
    for item in range(n):
        idx = itrs[item]
        if idx == n - 1:
            continue
        want = a_s[item][idx]
        # Check there is match or not
        if a_s[want][itrs[want]] == item:
            has_match = True
            if item < want:
                wants.add((item, want))
            else:
                wants.add((want, item))
    if not has_match:
        break
    # Process match
    for a, b in wants:
        itrs[a] += 1
        itrs[b] += 1
        fights += 1
    days += 1

if fights == total:
    print(days)
else:
    print(-1)

Fixed submission:
class DirectedGraph:
    def __init__(self, adj):
        self.n = len(adj)
        self.adj = adj
        self.is_asyclic = False
        self.max_path_len = None

    def topological_sort(self):
        indegree = [0] * self.n
        for i, vs in enumerate(self.adj):
            for dest in vs:
                indegree[dest] += 1
        zero_v = []
        for v, indeg in enumerate(indegree):
            if indeg == 0:
                zero_v.append(v)
        max_path_len = 1
        tp_sorted = []
        to_be_added = []
        while True:
            while zero_v:
                v = zero_v.pop()
                tp_sorted.append(v)
                for dest in self.adj[v]:
                    indegree[dest] -= 1
                    if indegree[dest] == 0:
                        to_be_added.append(dest)
            if len(to_be_added) > 0:
                zero_v += to_be_added
                to_be_added = []
                max_path_len += 1
            else:
                break
        if len(tp_sorted) == self.n:
            self.is_asyclic = True
            self.max_path_len = max_path_len
            return tp_sorted
        else:
            self.is_asyclic = False
            return None

if __name__ == "__main__":
    n = int(input())
    dic = {}
    itr = 0
    for i in range(n):
        for j in range(i+1, n):
            dic[i*n + j] = itr
            itr += 1
    edge = [[] for _ in range(n * (n-1) // 2)]
    for i in range(n):
        a = [int(item) - 1 for item in input().split()]
        for j1, j2 in zip(a, a[1:]):
            if i < j1:
                u = i * n + j1 
            else:
                u = j1 * n + i 
            if i < j2:
                v = i * n + j2 
            else:
                v = j2 * n + i 
            edge[dic[u]].append(dic[v])

    DG = DirectedGraph(edge)
    tps = DG.topological_sort()

    if DG.is_asyclic:
        print(DG.max_path_len)
    else:
        print(-1)

Buggy python submission (verdict: Time Limit Exceeded):
n = int(input())
a_s = [] 
for i in range(n):
    a_s.append([int(item) - 1 for item in input().split()])

total = n * (n - 1) // 2
days = 0
itrs = [0] * n
fights = 0

while True:
    wants = set()
    has_match = False
    for item in range(n):
        idx = itrs[item]
        if idx == n - 1:
            continue
        want = a_s[item][idx]
        # Check there is match or not
        if a_s[want][itrs[want]] == item:
            has_match = True
            if item < want:
                wants.add((item, want))
            else:
                wants.add((want, item))
    if not has_match:
        break
    # Process match
    for a, b in wants:
        itrs[a] += 1
        itrs[b] += 1
        fights += 1
    days += 1

if fights == total:
    print(days)
else:
    print(-1)

Fixed submission:
class DirectedGraph:
    def __init__(self, adj):
        self.n = len(adj)
        self.adj = adj
        self.is_asyclic = False
        self.max_path_len = None

    def topological_sort(self):
        indegree = [0] * self.n
        for i, vs in enumerate(self.adj):
            for dest in vs:
                indegree[dest] += 1
        zero_v = []
        for v, indeg in enumerate(indegree):
            if indeg == 0:
                zero_v.append(v)
        max_path_len = 1
        tp_sorted = []
        to_be_added = []
        while True:
            while zero_v:
                v = zero_v.pop()
                tp_sorted.append(v)
                for dest in self.adj[v]:
                    indegree[dest] -= 1
                    if indegree[dest] == 0:
                        to_be_added.append(dest)
            if len(to_be_added) > 0:
                zero_v += to_be_added
                to_be_added = []
                max_path_len += 1
            else:
                break
        if len(tp_sorted) == self.n:
            self.is_asyclic = True
            self.max_path_len = max_path_len
            return tp_sorted
        else:
            self.is_asyclic = False
            return None

if __name__ == "__main__":
    n = int(input())
    dic = {}
    itr = 0
    for i in range(n):
        for j in range(i+1, n):
            dic[i*n + j] = itr
            itr += 1
    edge = [[] for _ in range(n * (n-1) // 2)]
    for i in range(n):
        a = [int(item) - 1 for item in input().split()]
        for j1, j2 in zip(a, a[1:]):
            if i < j1:
                u = i * n + j1 
            else:
                u = j1 * n + i 
            if i < j2:
                v = i * n + j2 
            else:
                v = j2 * n + i 
            edge[dic[u]].append(dic[v])

    DG = DirectedGraph(edge)
    tps = DG.topological_sort()

    if DG.is_asyclic:
        print(DG.max_path_len)
    else:
        print(-1)