Problem:
 Score : 500 points    Problem Statement N players will participate in a tennis tournament. We will call them Player 1 , Player 2 , \ldots , Player N .  The tournament is round-robin format, and there will be N(N-1)/2 matches in total.
Is it possible to schedule these matches so that all of the following conditions are satisfied? If the answer is yes, also find the minimum number of days required.   Each player plays at most one matches in a day.  Each player i  (1 \leq i \leq N) plays one match against Player A_{i, 1}, A_{i, 2}, \ldots, A_{i, N-1} in this order.       Constraints  3 \leq N \leq 1000  1 \leq A_{i, j} \leq N  A_{i, j} \neq i  A_{i, 1}, A_{i, 2}, \ldots, A_{i, N-1} are all different.         Input Input is given from Standard Input in the following format:  N  A_{1, 1}  A_{1, 2}  \ldots  A_{1, N-1}  A_{2, 1}  A_{2, 2}  \ldots  A_{2, N-1}  :  A_{N, 1}  A_{N, 2}  \ldots  A_{N, N-1}       Output If it is possible to schedule all the matches so that all of the conditions are satisfied, print the minimum number of days required; if it is impossible, print -1 .        Sample Input 1 3
2 3
1 3
1 2      Sample Output 1 3  All the conditions can be satisfied if the matches are scheduled for three days as follows:   Day 1 : Player 1 vs Player 2  Day 2 : Player 1 vs Player 3  Day 3 : Player 2 vs Player 3   This is the minimum number of days required.       Sample Input 2 4
2 3 4
1 3 4
4 1 2
3 1 2      Sample Output 2 4  All the conditions can be satisfied if the matches are scheduled for four days as follows:   Day 1 : Player 1 vs Player 2 , Player 3 vs Player 4  Day 2 : Player 1 vs Player 3  Day 3 : Player 1 vs Player 4 , Player 2 vs Player 3  Day 4 : Player 2 vs Player 4   This is the minimum number of days required.       Sample Input 3 3
2 3
3 1
1 2      Sample Output 3 -1  Any scheduling of the matches violates some condition.

Solution (Python):
from collections import deque

def is_not_empty(A):
    for x in A:
        if x: return True
    return False

N = int(input())
A = [deque([int(i) - 1 for i in input().split()]) for _ in range(N)]

ans = 0
yesterday = set(range(N))
while is_not_empty(A):
    today = set()
    for my in yesterday:
        if not A[my]: continue
        if my in today: continue
        enemy = A[my][0]
        if my == A[enemy][0] and enemy not in today:
            today.add(A[my].popleft())
            today.add(A[enemy].popleft())

    if not today:
        ans = -1
        break

    ans += 1
    yesterday = today

print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
from collections import *

N = int(input())
A = [list(map(int, input().split())) for _ in range(N)]
serial = [[0]*N for _ in range(N)]
c = 0

for i in range(N):
    for j in range(i+1, N):
        serial[i][j] = c
        serial[j][i] = c
        c += 1
        
ins = [0]*(N*(N-1)//2)
outs = defaultdict(list)

for i in range(N):
    for j in range(1, N-1):
        s = serial[i][A[i][j-1]-1]
        t = serial[i][A[i][j]-1]
        ins[t] += 1
        outs[s].append(t)

q = deque([i for i in range(N*(N-1)//2) if ins[i]==0])
ans = 0

while True:
    if len(q)==0:
        break
    
    nq = deque([])
    
    while q:
        v = q.popleft()
        
        for nv in outs[v]:
            ins[nv] -= 1
            
            if ins[nv]==0:
                nq.append(nv)
    
    ans += 1
    q = nq

if ins!=[0]*(N*(N-1)//2):
    print(-1)
    exit()
    
print(ans)

Solution (Python):
def main():
    import sys
    sys.setrecursionlimit(10**7)
    input = sys.stdin.readline
    n = int(input())
    l = [list(map(int,input().split())) for i in range(n)]
    ans = 1
    count = [0]*n
    check = set()
    game = []
    for i in range(n):
        if count[i] >= n-1 or i in check:
            continue
        ind = l[i][count[i]]-1
        if ind in check:
            continue
        if l[ind].index(i+1) == count[ind]:
            check |= set([i,ind])
            game.append([i,ind])
            count[i] += 1
            count[ind] += 1
    while True:
        gamepre = game
        check = set()
        game = []
        for i,j in gamepre:
            ci = True
            cj = True
            if count[i] >= n-1 or i in check:
                ci = False
            if count[j] >= n-1 or j in check:
                cj = False
            if ci:
                ci = True
                ind = l[i][count[i]]-1
                if ind in check:
                    ci = False
                if ci and l[ind].index(i+1) == count[ind]:
                    check |= set([i,ind])
                    game.append([i,ind])
                    count[i] += 1
                    count[ind] += 1
            if cj:
                cj = True
                ind = l[j][count[j]]-1
                if ind in check:
                    cj = False
                if cj and l[ind].index(j+1) == count[ind]:
                    check |= set([j,ind])
                    game.append([j,ind])
                    count[j] += 1
                    count[ind] += 1
        if not check:
            if sum(count) != n*(n-1):
                print(-1)
                exit()
            else:
                print(ans)
                exit()
        ans += 1
if __name__ == "__main__":
    main()

Solution (Python):
N=int(input())
A=[[] for i in range(0,N)]
nodes=[]
for i in range(0,N-1):
    for j in range(i+1,N):
        nodes.append((i,j))

order={i:[0 for j in range(0,N)] for i in range(0,N)}
for i in range(0,N):
    A[i]=list(map(int,input().split()))
    for j in range(0,N-1):
        order[i][A[i][j]-1]=j
        


q=set([])
for battle in nodes:
    i,j=battle
    if order[i][j]==0 and order[j][i]==0:
        q.add(battle)

flag=[0 for i in range(0,N)]

day=0
sub=set([])
while q:
    while q:
        i,j=q.pop()
        flag[i]+=1
        flag[j]+=1
        if flag[i]!=N-1:
            s=A[i][order[i][j]+1]-1
            if flag[s]>=order[s][i]:
                sub.add((i,s))
        if flag[j]!=N-1:
            t=A[j][order[j][i]+1]-1
            if flag[t]>=order[t][j]:
                sub.add((j,t))

        if not q:
            day+=1
            q=sub
            sub=set([])
            break

able=True
for i in range(0,N):
    if flag[i]!=N-1:
        able=False

if able:
    print(day)
else:
    print(-1)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 7)

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


N = int(input())
A = [[int(x) for x in input().split()] for _ in range(N)]

A = [[-1]] + A


def check(a, q=[]):
    if not A[a]:
        return False

    b = A[a][-1]
    b_op = A[b][-1]

    ok = False
    if a == b_op:
        ok = True

        if b < a:
            a, b = b, a
        q.append((a, b))

    return ok


q = []
for i in range(1, N + 1):
    check(i, q)

q = list(set(q))

day = 0
while q:
    nq = []
    for a, b in q:
        A[a].pop()
        A[b].pop()
        check(a, nq)
        check(b, nq)

    day += 1
    q = list(set(nq))

for i in range(1, N + 1):
    if len(A[i]) != 0:
        print(-1)
        exit()

print(day)
exit()

Solution (Python):
import sys
INF = 10 ** 9
MOD = 10 ** 9 + 7
from collections import deque
sys.setrecursionlimit(100000000)
input = sys.stdin.readline
from copy import deepcopy 

MAXN = 1005
MAXV = MAXN * (MAXN - 1)//2
G = [[] for _ in range(MAXV)]

id = [[-1] * MAXN for _ in range(MAXN)]
def toId(i,j):
    if i > j:
        i,j = j,i
    return id[i][j]


finished = [0] * MAXV
dp = [-1] * MAXV
def dfs(v):
    if dp[v] != -1:
        if finished[v] == 0:
            return -1
        return dp[v]
    dp[v] = 0
    for e in G[v]:
        res = dfs(e)
        if res == -1:
            return -1
        dp[v] = max(dp[v],res + 1)
    finished[v] = 1
    return dp[v]


def main():
    n = int(input())
    a = [[int(i) - 1 for i in input().split()] for _ in range(n)]

    v = 0
    for i in range(n):
        for j in range(i + 1,n):
            id[i][j] = v
            v += 1
    
    for i in range(n):
        for j in range(n - 1):
            a[i][j] = toId(i,a[i][j])
        for j in range(n - 2):
            G[a[i][j]].append(a[i][j + 1])
    
    ans = 0
    for i in range(v):
        res = dfs(i)
        if res == -1:
            ans = -1
            break
        ans = max(ans,dfs(i) + 1)
    
    print(ans)

if __name__=='__main__':
    main()

Solution (Python):
import sys
from collections import deque

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

N = ir()
A = [deque([(i, x) for x in lr()]) for i in range(1, N+1)]
day = 0
candidate = {A[i][0] for i in range(N)}
match = 0

while candidate:
    day += 1
    used = set()
    next = set()
    for a, b in candidate:
        if a in used or b in used:
            continue
        if A[b-1][0] == (b, a):
            match += 1
            A[a-1].popleft()
            A[b-1].popleft()
            if A[a-1]:                
                next.add(A[a-1][0])
            if A[b-1]:
                next.add(A[b-1][0])
            used.add(a)
            used.add(b)
    if match == N * (N-1) // 2:
        break
    candidate = next
    if not used:
        print(-1); exit()

print(day)

Solution (Python):
import sys
from collections import deque

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

N = ir()
A = [deque([(i, x) for x in lr()]) for i in range(1, N+1)]
day = 0
candidate = {A[i][0] for i in range(N)}
match = 0

while candidate:
    day += 1
    used = set()
    next = set()
    for a, b in candidate:
        if a in used or b in used:
            continue
        if A[b-1][0] == (b, a):
            match += 1
            A[a-1].popleft()
            A[b-1].popleft()
            if A[a-1]:                
                next.add(A[a-1][0])
            if A[b-1]:
                next.add(A[b-1][0])
            used |= {a, b}
    if match == N * (N-1) // 2:
        break
    candidate = next
    if not used:
        print(-1); exit()

print(day)

Solution (Python):
import sys
from collections import deque

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

N = ir()
A = [deque([(i, x) for x in lr()]) for i in range(1, N+1)]
day = 0
candidate = set()
match = 0
for i in range(N):
    c = A[i][0]
    candidate.add(c)

while candidate:
    day += 1
    used = set()
    next = set()
    for a, b in candidate:
        if a in used or b in used:
            continue
        if A[b-1][0] == (b, a):
            match += 1
            A[a-1].popleft()
            A[b-1].popleft()
            if A[a-1]:                
                next.add(A[a-1][0])
            if A[b-1]:
                next.add(A[b-1][0])
            used.add(a)
            used.add(b)
    if match == N * (N-1) // 2:
        break
    candidate = next
    if not used:
        print(-1); exit()

print(day)

Solution (Python):

from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def dfs(x):
        if r[x] != None:
            return 1
        f = 1
        res = 0
        for y in v[x]:
            if d[y]:
                d[y] = 0
                f &= dfs(y)
                d[y] = 1
            else:
                res = float("inf")
                f = 0
                break
            if res < r[y]:
                res = r[y]
        r[x] = res+1
        return f

    n = I()
    a = LIR(n)
    N = n*(n-1)
    f = [0]*N
    v = [[] for i in range(N)]
    lis = set()
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1
        k = a[i][0]
        x = n*min(i,k)+max(i,k)
        for j in range(1,n-1):
            l = a[i][j]
            y = n*min(i,l)+max(i,l)
            v[y].append(x)
            f[x] += 1
            lis.add(x)
            lis.add(y)
            x = y
    if min([f[i] for i in lis]):
        print(-1)
        return
    d = [1]*N
    r = defaultdict(lambda : None)
    for i in lis:
        if not f[i]:
            d[i] = 0
            if not dfs(i):
                print(-1)
                return
    print(max(r.values()))
    return


if __name__ == "__main__":
    solve()

Solution (Python):
N=int(input())
def proc(x):
  return int(x)-1
from collections import deque
A=[deque(list(map(proc,input().split()))+[-1]) for i in range(N)]

ans = 0
rest = N*(N-1)
cand = set(range(N))
while rest>0:
  cand_next=set()
  for n in cand:
    if A[A[n][0]][0]==n:
      cand_next.add(n)
  if len(cand_next)==0:
    ans=-1
    break
  rest-=len(cand_next)
  cand=set()
  for n in cand_next:
    A[n].popleft()
    cand.add(n)
    if A[n][0]!=-1:
      cand.add(A[n][0])
  ans+=1
    

print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline

def main():
    n = int(input())

    A = [0]*n
    for i in range(n):
        a = list(map(int, input().split()))
        a = [a_-1 for a_ in a]
        A[i] = a

    g = [[] for i in range(n*(n-1)//2)]
    id = [[[-1] for i in range(n)] for j in range(n)]

    temp = 0
    for i in range(n-1):
        for j in range(i+1, n):
            id[i][j] = temp
            id[j][i] = temp
            temp += 1

    for i in range(n):
        for j in range(n-2):
            g[id[i][A[i][j]]].append(id[i][A[i][j+1]])

    visit = [-1]*(n*(n-1)*2)
    clc = [-1]*(n*(n-1)*2)
    dp = [1]*(n*(n-1)*2)
    def dfs(v):
        if visit[v] != -1:
            if clc[v] == -1:
                return -1
            return dp[v]
        visit[v] = 0
        for u in g[v]:
            res = dfs(u)
            if res == -1:
                return -1
            dp[v] = max(dp[v], res+1)
        clc[v] = 0
        return dp[v]

    ans = 0
    for i in range(n*(n-1)//2):
        res = dfs(i)
        if res == -1:
            print(-1)
            exit()
        ans = max(ans, res)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline

from collections import deque

n = int(input())
a = [[]]
for _ in range(n):
    a.append(deque([int(x) for x in input().split()]))

day = 1
next_day = []
used_player = [set() for _ in range(n**2)]


for i in range(1, n + 1):
    if a[a[i][0]][0] == i and (i not in used_player[day]) and (a[i][0] not in used_player[day]):
        used_player[day].add(i)
        used_player[day].add(a[i][0])
        next_day.append(a[a[i][0]].popleft())
        next_day.append(a[i].popleft())



from copy import deepcopy

while next_day:
    day += 1
    u = deepcopy(next_day)
    next_day = []
    
    
    for i in u:
        if len(a[i]) > 0 and len(a[a[i][0]]) > 0:
            if a[a[i][0]][0] == i and (i not in used_player[day]) and (a[i][0] not in used_player[day]):
                used_player[day].add(i)
                used_player[day].add(a[i][0])
                next_day.append(a[a[i][0]].popleft()) 
                next_day.append(a[i].popleft())

for i in a:
    if len(i) != 0:
        print(-1)
        sys.exit()

print(day - 1)

Solution (Python):
import sys
from collections import deque
sys.setrecursionlimit(10**9)
INF=10**18
def input():
    return sys.stdin.readline().rstrip()

def main():
    N=int(input())
    A=[[] for _ in range(N)]
    for i in range(N):
        A[i]=deque(list(map(lambda x: int(x)-1,input().split())))
    days=1
    c=0
    pre=[]
    tmp=[]
    for i in range(N):
        if A[i] and A[A[i][0]][0]==i:
            tmp.append(i)
            tmp.append(A[i][0])
    tmp=list(set(tmp))
    for i in tmp:
        A[i].popleft()
        c+=1
    pre=tmp
    if c<N*(N-1):
        while c<N*(N-1):
            tmp=[]
            for i in pre:
                if A[i] and A[A[i][0]][0]==i:
                    tmp.append(i)
                    tmp.append(A[i][0])
            tmp=list(set(tmp))
            for i in tmp:
                A[i].popleft()
                c+=1
            pre=tmp
            days+=1
            if days>N*(N-1)//2:
                print(-1)
                exit()
    print(days)
                
            
        
    
        
        

    

        
if __name__ == '__main__':
    main()

Solution (Python):
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]


def match2int(x, y):
    x, y = min(x, y), max(x, y)
    return (2 * n - 1 - x) * x // 2 + y - x - 1


match_sm = n * (n - 1) // 2

adj = [[] for _ in range(match_sm)]
in_deg = [0] * match_sm
for i, li in enumerate(a):
    for j, k in zip(li, li[1:]):
        j -= 1
        k -= 1
        match1 = match2int(i, j)
        match2 = match2int(i, k)
        adj[match1].append(match2)
        in_deg[match2] += 1

cnd = [i for i, e in enumerate(in_deg) if e == 0]
day = 0
while cnd:
    nxt_cnd = []
    for u in cnd:
        for v in adj[u]:
            in_deg[v] -= 1
            if in_deg[v] == 0:
                nxt_cnd.append(v)

    cnd = nxt_cnd
    day += 1

if in_deg.count(0) != match_sm:
    day = -1

print(day)

Solution (Python):
def main():
    import sys
    input = sys.stdin.buffer.readline
    N = int(input())
    c = [[int(i) for i in input().split()] for j in range(N)]
    from collections import defaultdict
    edge = defaultdict(set)
    deg = defaultdict(int)
    for i, A in enumerate(c, start=1):
        for j in range(N-2):
            if i < A[j]:
                if i < A[j+1]:
                    edge[i*N+A[j]].add(i*N+A[j+1])
                    deg[i*N+A[j+1]] += 1
                else:
                    edge[i*N+A[j]].add(A[j+1]*N+i)
                    deg[A[j+1]*N+i] += 1
            else:
                if i < A[j+1]:
                    edge[A[j]*N+i].add(i*N+A[j+1])
                    deg[i*N+A[j+1]] += 1
                else:
                    edge[A[j]*N+i].add(A[j+1]*N+i)
                    deg[A[j+1]*N+i] += 1
    from collections import deque
    que = deque()
    dist = defaultdict(int)
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            
            if deg[i*N+j] == 0:
                que.append(i*N+j)  
                dist[i*N+j] = 1
    while que:
        u = que.popleft()
        for v in edge[u]:
            deg[v] -= 1
            dist[v] = max(dist[v], dist[u] + 1)
            if deg[v] == 0:
                que.append(v)

    if any(deg.values()):
        
        print(-1)
    else:
        print(max(dist.values()))


if __name__ == '__main__':
    main()

Solution (Python):
N = int(input())
A = [list(map(lambda x:int(x)-1, input().split())) for _ in range(N)]

M = N*N

def c(a,b):
    if a>b: a,b=b,a
    return a*N+b

G = [[] for _ in range(M)]
for i in range(N):
    a = A[i]
    x = i
    for j in range(N-1-1):
        y1 = a[j]
        y2 = a[j+1]
        G[c(x,y1)].append(c(x,y2))

dp = [0]*M
started = [False]*M
finished = [False]*M
for i in range(N):
    for j in range(i+1, N):
        s = c(i,j)
        if started[s]: continue
        stk = [(s, 0)]
        while stk:
            v, s = stk.pop()
            if s == 0:
                if started[v]:
                    if not finished[v]:
                        print(-1)
                        exit()
                    continue
                started[v] = True
                stk.append((v, 1))
                for to in G[v]:
                    stk.append((to, 0))
            else:
                finished[v] = True
                for to in G[v]:
                    dp[v] = max(dp[v], dp[to] + 1)

print(max(dp) + 1)

Solution (Python):
from collections import deque
import sys
input = sys.stdin.readline

N = int(input())
A = [deque(map(lambda x: int(x)-1, input().split())) for _ in range(N)]
ans = 0
used_prev = set(range(N))
while any(A):
    used = set()
    for i in used_prev:
        if not A[i] or i in used:
            continue
        j = A[i][0]
        if j in used:
            continue
        if A[j][0] == i:
            used.add(i)
            used.add(j)
            A[i].popleft()
            A[j].popleft()
    if not used:
        ans = -1
        break
    used_prev = used
    ans += 1
print(ans)

Solution (Python):
N = int(input())
A = [list(map(lambda x:int(x)-1, input().split())) for _ in range(N)]

indices = [0] * N
def next(i):
    return A[i][indices[i]] if indices[i] < N-1 else -1

from collections import deque
q = deque()
for i in range(N):
    j = next(i)
    if i < j and next(j) == i:
        q.append((i, j))

m = N*(N-1)//2
days = 0
while q:
    days += 1
    nq = deque()
    while q:
        i, j = q.pop()
        m -= 1
        indices[i] += 1
        indices[j] += 1
        ni = next(i)
        nj = next(j)
        if ni >= 0 and next(ni) == i:
            nq.append((i, ni))
        if nj >= 0 and nj != i and next(nj) == j:
            nq.append((j, nj))
    q = nq

if m > 0:
    print(-1)
else:
    print(days)

Solution (Python):
from collections import deque

def main():
    n = int(input())
    a = []
    for i in range(n):
        a.append(list(map(int, input().split())))

    que = deque()
    lastdone = []
    next = []
    for i in range(n):
        que.append((i, 1))
        lastdone.append(-1)
        next.append(0)
    while len(que) > 0:
        now, day = que.popleft()
        if lastdone[now] == day:
            continue
        if next[now] == n-1:
            continue
        candidate = a[now][next[now]]-1
        if lastdone[candidate] == day:
            continue
        if next[candidate] == n-1:
            continue
        if a[candidate][next[candidate]]-1 == now:
            next[now] += 1
            next[candidate] += 1
            lastdone[now] = day
            lastdone[candidate] = day
            que.append((now, day+1))
            que.append((candidate, day+1))

    for i in range(n):
        if next[i] != n-1:
            print(-1)
            return

    print(max(lastdone))

if __name__ == '__main__':
    main()

Solution (Python):
"""from collections import *
from itertools import *
from bisect import *
from heapq import *

import math
from fractions import gcd"""
import copy
N=int(input())
A=[list(reversed(list(map(int,input().split())))) for i in range(N)]
for i in range(N):
    for m in range(N-1):
        A[i][m]-=1

playerlst=set([i for i in range(N)])

count=0
nlst=copy.copy(playerlst)
while playerlst:
    flag=0
    lst=set()
    playedlst=set()
    while nlst:
        p=nlst.pop()
        if not p in lst and p in playerlst:
            p2=A[p][-1]
            if not p2 in lst and p2 in playerlst:
                if A[p2][-1]==p:
                    flag=1
                    A[p].pop()
                    A[p2].pop()
                    lst.add(p)
                    lst.add(p2)
                    if p2 in nlst:
                        nlst.remove(p2)
                    playedlst.add(p)
                    playedlst.add(p2)
                    if not A[p]:
                        playerlst.remove(p)
                    if not A[p2]:
                        playerlst.remove(p2)
    if not flag:
        print(-1)
        exit()
    count+=1
    nlst=copy.copy(playedlst)
print(count)

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

def main():
	N = INT()
	A = [LIST() for _ in range(N)]

	match_id = [[0]*N for _ in range(N)]

	def toid(i, j):  
		if i > j: i, j = j, i
		return match_id[i][j]

	cnt = 0
	for i in range(N):
		for j in range(N):
			if i < j:
				match_id[i][j] = cnt
				cnt += 1

	V = N*(N-1)//2
	gout = [[] for _ in range(V)]
	deg = [0]*(V)
	for i in range(N):
		for j in range(N-2):
			gout[toid(i, A[i][j]-1)].append(toid(i, A[i][j+1]-1))
			deg[toid(i, A[i][j+1]-1)] += 1
			
	topo = [v for v in range(V) if deg[v]==0]
	day = [0]*V
	deq = deque(topo)
	ans = 0
	while deq:
	    v = deq.popleft()
	    for t in gout[v]:
	        deg[t] -= 1
	        if deg[t]==0:
	            deq.append(t)
	            day[t] = day[v] + 1
	            ans = day[t]
	if any(deg):  
		print(-1)
		exit()
	print(ans+1)
	

if __name__ == '__main__':
	main()

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

def main():
	N = INT()
	A = [LIST() for _ in range(N)]

	graph_out = defaultdict(list)
	graph_in = defaultdict(list)
	match_id = [[0]*N for _ in range(N)]

	def toid(i, j):  
		if i > j: i, j = j, i
		return match_id[i][j]

	cnt = 0
	for i in range(N):
		for j in range(N):
			if i < j:
				match_id[i][j] = cnt
				cnt += 1

	V = N*(N-1)//2
	gout = [[] for _ in range(V)]
	gin = [[] for _ in range(V)]
	deg = [0]*(V)
	for i in range(N):
		for j in range(N-2):
			gout[toid(i, A[i][j]-1)].append(toid(i, A[i][j+1]-1))
			deg[toid(i, A[i][j+1]-1)] += 1
			gin[toid(i, A[i][j+1]-1)].append(toid(i, A[i][j]-1))
	
	ans = [v for v in range(V) if deg[v]==0]
	deq = deque(ans)
	used = [0]*V
	while deq:
	    v = deq.popleft()
	    for t in gout[v]:
	        deg[t] -= 1
	        if deg[t]==0:
	            deq.append(t)
	            ans.append(t)
	if any(deg):
		print(-1)
		exit()

	cnt = [0]*V  
	day = [0]*V
	q = deque(ans)
	ans = 0

	while q:
		n = q.popleft()
		for node in gout[n]:
			cnt[node] += 1
			if cnt[node] == len(gin[node]):
				q.append(node)
				day[node] = day[n] + 1
				ans = day[node]
	print(ans+1) 

if __name__ == '__main__':
	main()

Solution (Python):
from collections import Counter,defaultdict,deque
from bisect import bisect_left
import sys,math,itertools,pprint,fractions,time
sys.setrecursionlimit(10**8)
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

st = time.time()
n = inp()
a = []
for i in range(n):
    b = inpl()
    a.append(deque(b))
zan = n*(n-1)//2
res = 0
while True:
    res += 1
    now = zan
    s = set()
    for i in range(n):
        if i in s or a[i] == deque([]): continue
        end = True
        chk = a[i][0] - 1
        if not chk in s and a[chk][0] == i+1:
            zan -= 1
            if not zan: 
                print(res); quit()
            a[i].popleft(); a[chk].popleft()
            s.add(i); s.add(chk)
        
        nnn = time.time()
    if now == zan:
        print(-1)
        quit()
    if nnn - st > 1.7:
        print(n*(n-1)//2)
        quit()

Solution (Python):
import sys
input = sys.stdin.readline
from collections import deque

n = int(input())
U = n**2
G = [[] for _ in range(U)]
parent = [0]*U
for i in range(n):
  A = list(map(lambda x:int(x)-1, input().split()))
  for j in range(n-2):
    a = A[j]
    b = A[j+1]
    G[min(i, a)*n+max(i, a)].append(min(i, b)*n+max(i, b))
    parent[min(i, b)*n+max(i, b)] += 1

que = deque([(i*n+j, 1) for i in range(n-1) for j in range(i+1, n) if not parent[i*n+j]])
ans = 1
cnt = 0
while que:
  v, t = que.pop()
  ans = max(ans, t)
  cnt += 1
  for nv in G[v]:
    parent[nv] -= 1
    if not parent[nv]:
      que.appendleft((nv, t+1))
if cnt == n*(n-1)//2:
  print(ans)
else:
  print(-1)

Solution (Python):
import collections

n=int(input())
arr=[list(map(int,input().split())) for _ in range(n)]
arr=[0]+[collections.deque(arr[i]) for i in range(n)]
ans=0
cand=set(range(1,n+1))
while 1:
  check=set()
  for i in cand:
    if not arr[i]:
      continue
    pair=arr[i][0]
    if arr[pair][0]==i:
      check.add(i)
      check.add(pair)
  if not check:
    break
  cand=set()
  for i in check:
    cand.add(i)
    arr[i].popleft()
    if arr[i]:
      cand.add(arr[i][0])
  ans+=1
for i in range(1,n+1):
  if arr[i]:
    print(-1)
    break
else:
  print(ans)

Solution (Python):
import collections

n=int(input())
arr=[list(map(int,input().split())) for _ in range(n)]
arr=[0]+[collections.deque(arr[i]) for i in range(n)]
ans=0
cand=set(range(1,n+1))
while 1:
  check=set()
  for i in cand:
    if not arr[i]:
      continue
    pair=arr[i][0]
    if arr[pair][0]==i:
      check.add(i)
      check.add(pair)
  if not check:
    break
  cand=set()
  for i in check:
    cand.add(i)
    arr[i].popleft()
    if arr[i]:
      cand.add(arr[i][0])
  ans+=1
for i in range(1,n+1):
  if arr[i]:
    print(-1)
    break
else:
  print(ans)

Solution (Python):
n = int(input())
g = [[-1, -1] for i in range(n*n)]
z = [0] * (n*n)

a = []
for _ in range(n):
    a.append([int(i) for i in input().split()])

for i in range(n):
    for j in range(n-2):
        p, q = (i, a[i][j]-1)
        r, s = (i, a[i][j+1]-1)
        r, s = (min(r, s), max(r ,s))
        if p < q:
            g[p*n+q][0] = r*n + s
        else:
            g[q*n+p][1] = r*n + s
        z[r*n+s] += 1

qu = set([])
for i in range(n):
    p, q = (i, a[i][0]-1)
    p, q = (min(p, q), max(p ,q))
    if z[p*n+q] == 0:
        qu.add(p*n+q)

ans = 0
re = 0
while True:
    nqu = []
    while qu:
        s = qu.pop()
        re += 1
        for t in g[s]:
            if t != -1:
                z[t] -= 1
                if z[t] == 0:
                    nqu.append(t)
    ans += 1    
    qu = nqu
    if not qu:
        break

if re == n*(n-1)//2:
    print(ans)
else:
    print(-1)