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):



import sys
import math
import bisect
import time
sys.setrecursionlimit(1000000000)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

n = I()
a = [LI() + [-1] for _ in range(n)]
cnt,day = [0]*n,[0]*n
que = deque([i for i in range(n)])
while que:
    u = que.popleft()
    v = a[u][cnt[u]] - 1
    if a[v][cnt[v]] - 1 == u:
        day[u] = max(day[u],day[v]) + 1
        day[v] = day[u]
        cnt[u] += 1
        cnt[v] += 1
        que.append(u)
        que.append(v)
for i in range(n):
    if cnt[i] != n-1:
        print(-1)
        quit()
print(max(day))

Solution (Python):
from heapq import heappush, heappop
from collections import deque,defaultdict,Counter
import itertools
from itertools import permutations
import sys
import bisect
import string
import math
import time
ts=time.time()
sys.setrecursionlimit(10**6)
def SI():
    return input().split()
def MI():
    return map(int,input().split())
def I():
    return int(input())
def LI():
    return [int(i) for i in input().split()]
YN=['Yes','No']
mo=10**9+7

n=I()
t=[]
nx=[-1]*n
for i in range(n):
    a=[i-1 for i in LI()[::-1]]
    nx[i]=a.pop()
    t.append(a)

IsMatch=True
ans=0
MacthNum=0
search=set(range(n))

while IsMatch and MacthNum<n*(n-1)//2:
    ans+=1
    IsMatch=False
    done=set()
    nx_search=[]
    for i in search:
        if (i in done) or (nx[i] in done) or nx[i]==-1:
            continue
        c1=i
        c2=nx[i]
        if c1==nx[c2]:
            IsMatch=True
            MacthNum+=1
            if t[c1]:
                n_i=t[c1].pop()
                nx_search.append(c1)
            else:
                n_i=-1
            if t[c2]:
                n_n_i=t[c2].pop()
                nx_search.append(c2)
            else:
                n_n_i=-1
            nx[nx[i]],nx[i]=n_n_i,n_i
            done.add(c1)
            done.add(c2)
    search=[i for i in nx_search]
    ans=ans if IsMatch else -1

print(ans)

Solution (Python):
from collections import deque

n = int(input())
orders = [deque([x - 1 for x in list(map(int, input().split()))] + [-1]) for _ in range(n)]

nxt = [orders[i].popleft() for i in range(n)]
days = [0 for _ in range(n)]

q = deque([i for i in range(n)])
while q:
	a = q.popleft()
	b = nxt[a]
	if nxt[nxt[a]] == a:
		days[a], days[b] = [max(days[a], days[b]) + 1 for _ in range(2)]
		nxt[a] = orders[a].popleft()
		nxt[b] = orders[b].popleft()
		q.append(a)
		q.append(b)

if sum(nxt) == -n:
	print(max(days))
else:
	print(-1)

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

N = int(input())
A = [[n-1 for n in list(map(int, input().split()))] + [-1] for _ in range(N)]
A = [a[::-1] for a in A]

def main(N, A):
    now = [A[i].pop() for i in range(N)]
    day = 0
    rest = N * (N-1)
    candidate = set(range(N))

    
    while True:
        
        
        if rest == 0:
            return day

        change = []
        next_candidate = set()
        for i in candidate:
            if now[now[i]] == i:
                j = A[i].pop()
                change.append((i, j))
                
                next_candidate.add(i)
                if j != -1:
                    next_candidate.add(j)
                
                rest -= 1
                have_match = True

        if len(change) == 0:
            return -1
        for (a, b) in change:
            now[a] = b
            
        candidate = next_candidate
        
        day += 1

print(main(N, A))

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

N = int(input())
A = [[n-1 for n in list(map(int, input().split()))] + [-1] for _ in range(N)]
A = [a[::-1] for a in A]

def main(N, A):
    now = [A[i].pop() for i in range(N)]
    day = 0
    rest = N * (N-1)
    candidate = set(range(N))

    
    while True:
        
        
        if rest == 0:
            return day

        
        
        have_match = False
        
        
        
        
        
        
        
        change = []
        next_candidate = set()
        for i in candidate:
            if now[now[i]] == i:
                j = A[i].pop()
                change.append((i, j))
                
                next_candidate.add(i)
                if j != -1:
                    next_candidate.add(j)
                
                rest -= 1
                have_match = True

        if len(change) == 0:
            return -1
        for (a, b) in change:
            now[a] = b
            
        candidate = next_candidate
        
        day += 1

print(main(N, A))

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

N = int(input())
A = [[n-1 for n in list(map(int, input().split()))] + [-1] for _ in range(N)]
A = [a[::-1] for a in A]

def main(N, A):
    now = [A[i].pop() for i in range(N)]
    day = 0
    rest = N * (N-1)
    candidate = set(range(N))

    
    while True:
        
        
        if rest == 0:
            return day

        
        
        have_match = False
        
        
        
        
        
        
        
        change = []
        next_candidate = set()
        for i in candidate:
            if now[now[i]] == i:
                j = A[i].pop()
                change.append((i, j))
                
                next_candidate.add(i)
                if j != -1:
                    next_candidate.add(j)
                
                rest -= 1
                have_match = True

        if len(change) == 0:
            return -1
        for (a, b) in change:
            now[a] = b
            
        candidate = next_candidate
        
        day += 1

print(main(N, A))

Solution (Python):
from heapq import heappush, heappop
from collections import deque,defaultdict,Counter
import itertools
from itertools import permutations
import sys
import bisect
import string
import math
import time
ts=time.time()
sys.setrecursionlimit(10**6)
def SI():
    return input().split()
def MI():
    return map(int,input().split())
def I():
    return int(input())
def LI():
    return [int(i) for i in input().split()]
YN=['Yes','No']
mo=10**9+7

n=I()
t=[]
d=[]
nx=[0]*n
for i in range(n):
    a=[i-1 for i in LI()[::-1]]
    nx[i]=a.pop()
    t.append(a)
    d.append([-1]*(n))

flg=True
ans=0
MacthNum=0
yet=set(range(n))
n_yet=set(range(n))
while flg and MacthNum<n*(n-1)//2:
    elp=time.time()-ts
    if elp>1.8:
        ans=0
        break
    ans+=1
    IsMatch=False
    done=set()
    n_yet=[]
    
    for i in yet:
        if (i in done) or (nx[i] in done) or nx[i]==n:
            continue
        c1=i
        c2=nx[i]
        if c1==nx[c2]:
            IsMatch=True
            MacthNum+=1
            
            if t[c1]:
                n_i=t[c1].pop()
                n_yet.append(c1)
            else:
                n_i=n
            if t[c2]:
                n_n_i=t[c2].pop()
                n_yet.append(c2)
            else:
                n_n_i=n
            
            nx[nx[i]],nx[i]=n_n_i,n_i
            done.add(c1)
            done.add(c2)
            
    yet=[i for i in n_yet]
    ans=ans if IsMatch else -1
    flg=True if IsMatch else False

print(ans)

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

N = int(input())
A = [[n-1 for n in list(map(int, input().split()))] + [-1] for _ in range(N)]
A = [a[::-1] for a in A]

def main(N, A):
    now = [A[i].pop() for i in range(N)]
    day = 0
    rest = N * (N-1)
    candidate = set(range(N))

    
    while True:
        
        
        if rest == 0:
            return day

        
        
        have_match = False
        
        
        
        
        
        
        
        change = []
        next_candidate = set()
        for i in candidate:
            if now[now[i]] == i:
                j = A[i].pop()
                change.append((i, j))
                
                next_candidate.add(i)
                if j != -1:
                    next_candidate.add(j)
                
                rest -= 1
                have_match = True

        if len(change) == 0:
            return -1
        for (a, b) in change:
            now[a] = b
            
        candidate = next_candidate
        
        day += 1

print(main(N, A))

Solution (Python):


def main():
    n = int(input())
    a = [list(map(lambda x: int(x) - 1, input().split()))[::-1] for _ in range(n)]
    
    gam = []  
    
    for i in range(n):
        ii = a[i][-1]
        if ii < i: continue
        if a[ii][-1] == i:
            gam.append([i, ii])
    days = 0
    fin = [False] * n
    fin_cnt = 0
    
    while 1:
        days += 1
        pla = []  
        for i, ii in gam:
            a[i].pop()
            a[ii].pop()
            pla.append(i)
            pla.append(ii)
        gam = []
        dec = set()
        for i in pla:
            if fin[i]: continue
            if not a[i]:
                fin[i] = True
                fin_cnt += 1
                if fin_cnt == n:
                    print(days)
                    exit()
                continue
            if i in dec: continue
            ii = a[i][-1]
            if a[ii][-1] == i:
                gam.append([i, ii])
                dec.add(ii)
        if not gam:
            print(-1)
            exit()

main()

Solution (Python):

import sys
N = int(input())
A = [[0] * (N-1)]+[list(map(int,input().split())) for _ in range(N)]

idx = [0] * (N+1)
cnt = 0
day = 0
flag_max = [False] * (N+1)
looplist = list(range(1,N+1))
while cnt != N:
    
    error = True
    flag =[False] * (N+1)
    nxtlst = []
    
    while looplist:
        
        i = looplist.pop()
        if (flag[i]) or flag_max[i]:continue
        tmp = A[i][idx[i]]
        if (flag[tmp]) or flag_max[tmp]:continue
    
        if A[tmp][idx[tmp]] == i:
            nxtlst.append(i)
            nxtlst.append(tmp)
            idx[tmp] = idx[tmp] + 1
            idx[i] = idx[i] + 1
            if idx[tmp] == N-1:
                flag_max[tmp] = True
                cnt += 1
            if idx[i] == N-1:
                flag_max[i] = True
                cnt += 1
            flag[i] = True
            flag[tmp] = True
            error = False
    looplist = nxtlst
    if error:
        print(-1)
        sys.exit()
    
    day += 1
            

    if day > 10000:
        print(N*(N-1)//2)
        sys.exit()
    
    
print(day)

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

n = int(input())

def calc_idx(x, y):
    if x > y:
        x, y = y, x
    return x + y*(y-1)//2


n_game = n * (n-1) // 2
edge = [[] for i in range(n_game)]
indegree = [0] * n_game
for i in range(n):
    ai = list(map(int, input().split()))

    for j in range(1, n-1):
        g1 = calc_idx(i, ai[j-1]-1)
        g2 = calc_idx(i, ai[j]-1)
        edge[g1].append(g2)
        indegree[g2] += 1


ans = 0
cand = deque([(i, 1) for i in range(n_game) if indegree[i] == 0])
n_ts = 0
while len(cand) > 0:
    u, day = cand.popleft()
    ans = max(ans, day)
    n_ts += 1
    for v in edge[u]:
        indegree[v] -= 1
        if indegree[v] == 0:
            cand.append((v, day+1))

if n_ts != n_game:
    ans = -1

print(ans)

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

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

    def calc_idx(x, y):
        if x > y:
            x, y = y, x
        return x + y*(y-1)//2

    
    n_game = n * (n-1) // 2
    edge = [[] for i in range(n_game)]
    indegree = [0] * n_game
    for i in range(n):
        ai = list(map(int, input().split()))

        for j in range(1, n-1):
            g1 = calc_idx(i, ai[j-1]-1)
            g2 = calc_idx(i, ai[j]-1)
            edge[g1].append(g2)
            indegree[g2] += 1


    ans = 0
    cand = deque([(i, 1) for i in range(n_game) if indegree[i] == 0])
    n_ts = 0
    while len(cand) > 0:
        u, day = cand.popleft()
        ans = max(ans, day)
        n_ts += 1
        for v in edge[u]:
            indegree[v] -= 1
            if indegree[v] == 0:
                cand.append((v, day+1))

    if n_ts != n_game:
        ans = -1

    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(lambda x:x-1, list(map(int, input().split()))))for i in range(n)]


    
    v = 0  
    
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:
                Id[i][j] = v
                Id[j][i] = v
                v += 1

    
    e = [[] for i in range(maxv)]
    for i in range(n):
        
        for j in range(n - 1):
            a[i][j] = Id[i][a[i][j]]

        
        for j in range(n - 2):
            e[a[i][j]].append(a[i][j+1])


    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]
    def dfs(v):
        if dp[v] != -1:
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True 
        return dp[v]
    

    
    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

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

n = int(input())
a = [list(map(lambda x: int(x)-1, input().split())) for _ in range(n)]

def calc_idx(x, y):
    if x > y:
        x, y = y, x
    return x + y*(y-1)//2


n_game = n * (n-1) // 2
edge = [[] for i in range(n_game)]
indegree = [0] * n_game
for i in range(n):
    for j in range(1, n-1):
        g1 = calc_idx(i, a[i][j-1])
        g2 = calc_idx(i, a[i][j])
        edge[g1].append(g2)
        indegree[g2] += 1


ans = 0
cand = [[i for i in range(n_game) if indegree[i] == 0], []]
cand = deque([(i, 1) for i in range(n_game) if indegree[i] == 0])
n_ts = 0
while cand:
    u, day = cand.popleft()
    ans = max(ans, day)
    n_ts += 1
    for v in edge[u]:
        indegree[v] -= 1
        if indegree[v] == 0:
            cand.append((v, day+1))

if n_ts != n_game:
    ans = -1

print(ans)

Solution (Python):
def MAP(): return list(map(int,input().split()))
import collections

n = int(input())
a = [MAP() for _ in range(n)]
q = list(range(n))
c = collections.defaultdict(int)
t = [0]*n
r=0

while q:
    r += 1
    nq = []
    for i in q:
        j = a[i][t[i]]-1
        k = i
        if k<j:
            j,k = k,j
        c[(j,k)] += 1
        if c[(j,k)] == 2:
            t[j] += 1
            t[k] += 1
            if t[j] < n-1:
                nq.append(j)
            if t[k] < n-1:
                nq.append(k)
    q = nq

for tt in t:
    if tt!=n-1:
        print(-1)
        exit(0)
print(r)

Solution (Python):
import sys
import time
def input():
    return sys.stdin.readline()
 
def main():
    a = time.time()
    N = int(input())
    A = [list(map(int, input().split())) for _ in range(N)]
    l = [0] * N
    ans = 0
    count = 0
    check = [False] * N
    tmpl = []
    next = False
 
    while(count < N):
        check = [False] * N
        for i in range(N):
            if l[i] < N - 1:
                to = A[i][l[i]] - 1
                if (not check[to]) and (not check[i]):
                    if A[to][l[to]] - 1 == i:
                        l[i] += 1
                        l[to] += 1
                        check[to] = True
                        check[i] = True
                        next = True
                    if l[i] == N - 1:
                        count += 1
                    if l[to] == N - 1:
                        count += 1
        ans += 1
        if not next:
            print(-1)
            exit()
        next = False

        b = time.time()
        if b - a >= 1.7:
            print(N*(N - 1)//2)
            exit()
        
 
    print(ans)
 
if __name__ == '__main__':
    main()

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

n = int(input())
a = [list(map(lambda x: int(x)-1, input().split())) for _ in range(n)]

def calc_idx(x, y):
    if x > y:
        x, y = y, x
    return x + y*(y-1)//2

n_game = n * (n-1) // 2
edge = [[] for i in range(n_game)]
for i in range(n):
    for j in range(1, n-1):
        g1 = calc_idx(i, a[i][j-1])
        g2 = calc_idx(i, a[i][j])
        edge[g1].append(g2)

indegree = [0] * n_game
for i in range(n_game):
    for v in edge[i]:
        indegree[v] += 1

ans = 0
cand = [[i for i in range(n_game) if indegree[i] == 0], []]
n_ts = 0
while cand[ans%2]:
    n_ts += len(cand[ans%2])
    cand[(ans+1)%2] = []
    for ci in cand[ans%2]:
        for v in edge[ci]:
            indegree[v] -= 1
            if indegree[v] == 0:
                cand[(ans+1)%2].append(v)
    ans += 1

if n_ts != n_game:
    ans = -1

print(ans)

Solution (Python):
from collections import deque
import copy, sys

input = sys.stdin.readline
n = int(input())
a = [deque(map(lambda x: int(x) - 1, input().split())) for _ in range(n)]
q = deque()
pre_q = deque()
day = 0

def check(p, q):
    if not len(a[p]):
        return
    o = a[p][0]
    if p == a[o][0]:
        if p > o: p, o = o, p
        if not (p, o) in q:
            q.append((p, o))

fin = []
for p in range(n):
    if not p in fin:
        o = a[p][0]
        if p == a[o][0]:
            q.append((p, o))
            fin += [p, o]

while q:
    day += 1
    pre_q = copy.copy(q)
    q.clear()
    for (p, o) in pre_q:
        a[p].popleft()
        a[o].popleft()
        check(p, q)
        check(o, q)

if all(map(len, a)):
    print(-1)
else:
    print(day)

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

n = int(input())
a = [list(map(lambda x: int(x)-1, input().split())) for _ in range(n)]

def calc_idx(x, y):
    if x > y:
        x, y = y, x
    return x + y*(y-1)//2

n_game = n * (n-1) // 2
edge = [[] for i in range(n_game)]
for i in range(n):
    for j in range(1, n-1):
        g1 = calc_idx(i, a[i][j-1])
        g2 = calc_idx(i, a[i][j])
        edge[g1].append(g2)

indegree = [0] * n_game
for i in range(n_game):
    for v in edge[i]:
        indegree[v] += 1

ans = 0
cand = [i for i in range(n_game) if indegree[i] == 0]
ts = []
while cand:
    ts.extend(cand)
    cand2 = []
    for ci in cand:
        for v in edge[ci]:
            indegree[v] -= 1
            if indegree[v] == 0:
                cand2.append(v)
    cand = cand2
    ans += 1

if len(ts) != n_game:
    ans = -1

print(ans)

Solution (Python):
import sys
from collections import deque

n = int(input())
a = [deque(map(int, sys.stdin.readline().rstrip().split())) for _ in range(n)]

current = []

for i in range(n):
    target = a[i][0] -1
    if a[target][0] -1 == i and i < target:
        current.append([i, target])

day = 0
zc = 0
while True:
    popped = 0
    plist = set()
    zeros = 0
    tc = []
    for i in current:
        a[i[0]].popleft()
        a[i[1]].popleft()
        if len(a[i[0]]) > 0:
            plist.add(i[0])
        else:
            zc += 1
        if len(a[i[1]]) > 0:
            plist.add(i[1])
        else:
            zc += 1
    for i in plist:
        target = a[i][0] -1
        if a[target][0] -1 == i:
            if not target in plist or i < target:
                tc.append([i, target])
    day += 1
    if len(tc) == 0:
        break
    current = tc

if zc != n:
    day = -1

print(day)

Solution (Python):
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(int, input().split())) for i in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1

    
    v = 0  
    
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:
                Id[i][j] = v
                Id[j][i] = v
                v += 1


    
    e = [[] for i in range(maxv)]
    for i in range(n):
        
        for j in range(n - 1):
            a[i][j] = Id[i][a[i][j]]

        
        for j in range(n - 2):
            e[a[i][j]].append(a[i][j+1])



    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]

    def dfs(v):
        if dp[v] != -1:  
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

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

def main():
    N = int(input())
    A = [deque()] + [deque( map( int, input().split())) for _ in range(N)]
    NOW = [0]*(N+1)
    Days = [0]*(N+1)
    q = deque( [ i+1 for i in range(N)])
    while q:
      i = q.popleft()
      if not A[i]:
        continue
      
      a = A[i].popleft()
      
      if NOW[a] == i:
        NOW[a] = 0
        Days[a] = Days[i] = max((Days[i], Days[a])) + 1
        q.append(i)
        q.append(a)
      else:
        NOW[i] = a
    for i in range(N+1):
      if A[i]:
        print(-1)
        return
    print(max(Days))
if __name__ == '__main__':
    main()

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline
    
    N = int(input())
    A = []
    tmp = (0,)*(N+1)
    A.append(tmp)
    for i in range(N):
        tmp = (0,) + tuple(map(int, input().split()))
        A.append(tmp)
    B = [1]*(N+1)
    C = [[0]*N for i in range(N+1)]
    count = 0
    flag = 0
    
    
    Q = []
    nextQ = []
    for i in range(1,N+1):
        j = A[i][B[i]]
        if A[j][B[j]] == i:
            ii = min(i,j)
            jj = max(i,j)
            if not (ii,jj) in nextQ:
                nextQ.append((ii,jj))
    
    day = 0    
    while count < N*(N-1)//2 and len(nextQ) >= 1:
        day += 1
        Q = nextQ
        nextQ = []
        for T in Q:
            i = T[0]
            j = T[1]
            k = max(C[i][B[i]-1], C[j][B[j]-1]) + 1
            C[i][B[i]] = k
            C[j][B[j]] = k
            B[i] += 1
            B[j] += 1
            count += 1
            if B[i] < N:
                I = A[i][B[i]]
                if A[I][B[I]] == i:
                    ii = min(i,I)
                    jj = max(i,I)
                    if not (ii,jj) in nextQ:
                        nextQ.append((ii,jj))
            if B[j] < N:
                J = A[j][B[j]]
                if A[J][B[J]] == j:
                    ii = min(j,J)
                    jj = max(j,J)
                    if not (ii,jj) in nextQ:
                        nextQ.append((ii,jj))
            
                    
    
    if count < N*(N-1)//2:
        print(-1)
    else:
        print(day)
    
    
    
if __name__ == '__main__':
    main()

Solution (Python):
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(int, input().split())) for i in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1

    
    v = 0  
    
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:  
                Id[i][j] = v
                Id[j][i] = v
                v += 1


    e = [[] for i in range(maxv)]
    for i in range(n):
        for j in range(n - 1):
            
            
            
            
            
            
            a[i][j] = Id[i][a[i][j]]
        for j in range(n - 2):
            e[a[i][j + 1]].append(a[i][j])


    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]

    def dfs(v):
        if dp[v] != -1:  
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(int, input().split())) for i in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1

    v = 0  
    
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:  
                Id[i][j] = v
                v += 1

    def toId(i, j):
        if i > j:
            i, j = j, i
        return Id[i][j]



    e = [[] for i in range(maxv)]
    for i in range(n):
        for j in range(n - 1):
            
            x = i
            y = a[i][j]
            if x > y:
                x, y = y, x
            a[i][j] = Id[x][y]  
        for j in range(n - 2):
            e[a[i][j + 1]].append(a[i][j])


    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]

    def dfs(v):
        if dp[v] != -1:  
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):



import sys
import math
import bisect
import time
sys.setrecursionlimit(1000000000)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

n = I()
a = [deque() for _ in range(n)]
for i in range(1,n+1):
    x = LI()
    for j in x:
        a[i-1].append((i,j))
ans = 0
s = time.time()
for j in range(n*(n-1)//2+1):
    check = [1]*n
    flg = False
    flg2 = False
    if time.time() - s > 1.6:
        print(n*(n-1)//2)
        quit()
    for i in range(n):
        if len(a[i]) == 0 or check[i] == 0:
            continue
        (x,y) = a[i].popleft()
        flg2 = True
        check[i] = 0
        if a[y-1][0] == (y,x) and check[y-1]:
            a[y-1].popleft()
            flg = True
            check[y-1] = 0
        else:
            a[i].appendleft((x,y))
    if flg:
        ans += 1
    if not flg:
        for i in a:
            if len(i) != 0:
                print(-1)
                quit()
    if not flg2:
        print(ans)
        quit()

Solution (Python):
n = int(input())
a = []
for _ in range(n+1):
    a.append([-1])
for i in range(n):
    inp = list(map(int, input().split()))
    for j in range(n-2, -1, -1):
        a[i+1].append(inp[j])
matched = [i for i in range(1, n+1)]
finish = 0
days = 0
while True:
    used = set()
    while matched != []:
        i = matched.pop()
        p = a[i][-1]
        if p != -1 and a[p][-1] == i and (i not in used) and (p not in used) :
            a[i].pop()
            a[p].pop()
            used.add(i)
            used.add(p)
            if a[i][-1] == -1:
                finish += 1
            if a[p][-1] == -1:
                finish += 1
    days += 1
    matched = list(used)
    if len(used) == 0:
        days = -1
        break
    elif finish == n:
        break
print(days)

Solution (Python):

N = int(input())

A = []

for i in range(N):

    a = list(map(int,input().split()))

    A.append(a)

Q = []
for i in range(N):

    if A[ A[i][0]-1 ][0] == i + 1 and A[i][0]-1 > i:
        Q.append([min(A[i][0]-1,i),max(A[i][0]-1,i),1])

day = 0

while len(Q) > 0:

    q = Q.pop(0)

    del A[q[0]][0]
    del A[q[1]][0]




    if len(A[q[0]]) > 0 and A[ A[q[0]][0] - 1 ][0] == q[0] + 1:
        Q.append([min(A[q[0]][0] - 1,q[0]),max(A[q[0]][0] - 1,q[0]),q[2]+1])

    if len(A[q[1]]) > 0 and A[ A[q[1]][0] - 1 ][0] == q[1] + 1:
        Q.append([min(A[q[1]][0] - 1,q[1]),max(A[q[1]][0] - 1,q[1]),q[2]+1])

    day = max(day,q[2])

flag = True

for a in A:
    if len(a) > 0:
        flag = False
        
if flag:
    print (day)
else:
    print (-1)