CodeEff/ECCO huggingface dataset:
# Original solution
from collections import* #defaultdict Counter deque appendleft
import sys
input=sys.stdin.readline
import time
t=time.time()

def main():
    n=int(eval(input()))
    d=[[]]+[deque(list(map(int,input().split())))for i in n*[0]]

    c=0
    while any(d):
        c+=1
        f=0
        skip=set()
        for i in range(1,n+1):
            if i not in skip:
                if d[i]:
                    if d[i][0] in skip:
                        continue
                    elif i==d[d[i][0]][0]:
                        oppo=d[i].popleft()
                        d[oppo].popleft()
                        skip.add(oppo)
                        skip.add(i)
                        f=1

        if not f:
            print((-1))
            exit()
        if abs(time.time()-t)>1:
            print((n*(n-1)//2))

    print(c)

if __name__ == '__main__':
    main()

# Optimized solution
from collections import* #defaultdict Counter deque appendleft
import sys
input=sys.stdin.readline
import time
t=time.time()

def main():
    n=int(eval(input()))
    d=[[]]+[deque(list(map(int,input().split())))for i in n*[0]]

    c=0
    while any(d):
        c+=1
        f=0
        skip=set()
        for i in range(1,n+1):
            if i not in skip:
                if d[i]:
                    if d[i][0] in skip:
                        continue
                    elif i==d[d[i][0]][0]:
                        oppo=d[i].popleft()
                        d[oppo].popleft()
                        skip.add(oppo)
                        skip.add(i)
                        f=1

        if not f:
            print((-1))
            exit()
        if abs(time.time()-t)>1:
            print((n*(n-1)//2))
            exit()

    print(c)

if __name__ == '__main__':
    main()
# Original solution
from collections import defaultdict
N = int(eval(input()))
L = [list([int(x)-1 for x in input().split()]) for _ in range(N)]


def make_hash(a, b):
    a, b = min(a, b), max(a, b)
    return N*a+b


def un_hash(n):
    a = n//N
    b = n % N
    return a, b


from_to = defaultdict(lambda: set())
pointed = defaultdict(int)
pointing = defaultdict(int)

for i in range(N):
    for node_from, node_to in zip(L[i], L[i][1:]):
        #from_to[make_hash(i, node_to)].add(make_hash(i, node_from))
        from_to[make_hash(i, node_from)].add(make_hash(i, node_to))
        pointed[make_hash(i, node_to)] += 1
        pointing[make_hash(i, node_from)] += 1

START = set()
DST = set()
for i in range(N):
    for j in range(i+1, N):
        h = make_hash(i, j)
        pointed_i = pointed[h]
        pointing_i = pointing[h]
        if pointed_i == 0:
            START.add(h)
        if pointing_i == 0:
            DST.add(h)
if len(START) == 0 or len(DST) == 0:
    print((-1))

else:
    Q = [v for v in START]
    visited = set()
    dist = 0
    while Q:
        tmp = []
        dist += 1
        for q in Q:
            for nex in from_to[q]:
                tmp.append(nex)
                visited.add(nex)
        Q = tmp
    print(dist)


# Optimized solution
from collections import deque

n = int(eval(input()))
matches = []
for _ in range(n):
    matches.append(list([int(x)-1 for x in input().split()]))

q = deque(list(range(n)))

days = [0]*n  # 各選手の現在の日付
pairs = [-1]*n  # 次の対戦相手を管理(wait的な)

while q:
    x = q.popleft()  # 試合する人
    if len(matches[x]) == 0:  # 試合が全て終わってる?
        continue
    y = matches[x].pop(0)  # xの次の対戦相手
    if pairs[y] == x:
        day = max(days[x], days[y])+1
        days[x] = day
        days[y] = day
        q.append(x)
        q.append(y)
    else:
        pairs[x] = y

if not any(matches):  # 全ての試合をしょうか
    print((max(days)))
else:
    print((-1))
# Original solution
from collections import deque

n = int(eval(input()))
matches = []
for _ in range(n):
    matches.append(list([int(x)-1 for x in input().split()]))

q = deque(list(range(n)))

days = [0]*n  # 各選手の現在の日付
pairs = [-1]*n  # 次の対戦相手を管理(wait的な)

while q:
    x = q.popleft()  # 試合する人
    if len(matches[x]) == 0:  # 試合が全て終わってる?
        continue
    y = matches[x].pop(0)  # xの次の対戦相手
    if pairs[y] == x:
        day = max(days[x], days[y])+1
        days[x] = day
        days[y] = day
        q.append(x)
        q.append(y)
    else:
        pairs[x] = y

if not any(matches):  # 全ての試合をしょうか
    print((max(days)))
else:
    print((-1))


# Optimized solution
from collections import deque

n = int(eval(input()))
matches = []
for _ in range(n):
    matches.append(list([int(x)-1 for x in input().split()]))

q = deque(list(range(n)))

days = [0]*n  # 各選手の現在の日付

while q:
    x = q.popleft()  # 試合する人
    if len(matches[x]) == 0:  # 試合が全て終わってる?
        continue
    y = matches[x][0]  # xの次の対戦相手
    if matches[y][0] == x:
        day = max(days[x], days[y])+1
        days[x] = day
        days[y] = day
        q.append(x)
        q.append(y)
        _ = matches[x].pop(0)
        _ = matches[y].pop(0)

if not any(matches):  # 全ての試合をしょうか
    print((max(days)))
else:
    print((-1))
# Original solution
from collections import deque
import sys
input = sys.stdin.readline

n = int(eval(input()))
game = {}

for i in range(1, n+1):
    game[i] = deque((list(map(int, input().split()))))

count = 0
final = n*(n-1)//2
for day in range(1, 900000):
    finish = [0]*(n+1)
    possible = False
    for me in range(1, n+1):
        if finish[me] == 1 or game[me] == deque([]):
            continue

        you = game[me][0]
        if finish[you] == 1:
            continue
        else:
            if game[you][0] == me:
                finish[game[you].popleft()] = 1
                finish[game[me].popleft()] = 1
                possible = True
                count += 1
            else:
                continue

    if not possible:
        print((-1))
        exit()

    if count == final:
        print(day)
        exit()


# Optimized solution
from collections import deque
import sys
input = sys.stdin.readline

n = int(eval(input()))
game = {}

for i in range(1, n+1):
    game[i] = deque((list(map(int, input().split()))))

count = 0
final = n*(n-1)//2
done = []

finish = [0] * (n + 1)
for me in range(1, n + 1):
    if finish[me] == 1 or game[me] == deque([]):
        continue

    you = game[me][0]
    if finish[you] == 1:
        continue
    else:
        if game[you][0] == me:
            done.append(you)
            done.append(me)
            finish[game[you].popleft()] = 1
            finish[game[me].popleft()] = 1
            possible = True
            count += 1
        else:
            continue

for day in range(2, 1000000):
    finish = [0]*(n+1)
    possible = False
    new_done = []
    for me in done:
        if finish[me] == 1 or game[me] == deque([]):
            continue

        you = game[me][0]
        if finish[you] == 1:
            continue
        else:
            if game[you][0] == me:
                finish[game[you].popleft()] = 1
                finish[game[me].popleft()] = 1
                new_done.append(me)
                new_done.append(you)
                possible = True
                count += 1
            else:
                continue
    done = new_done
    if not possible:
        print((-1))
        exit()

    if count == final:
        print(day)
        exit()
# Original solution
def main():
    import sys
    input = sys.stdin.readline
    N=int(eval(input()))
    A = [list(map(int,input().split())) for _ in [0]*N]

    V = {(i,j):0 for i in range(N) for j in range(i+1,N)}
    Ef = {(i,j):[] for i in range(N) for j in range(i+1,N)}
    for i,B in enumerate(A):
        a0 = B[0]-1
        k1 = (i,a0) if i<a0 else (a0,i)
        for a1 in B[1:]:
            a1 -= 1
            k0 = k1
            k1 = (i,a1) if i<a1 else (a1,i)
            Ef[k0].append(k1)
            V[k1] += 1

    q = [k for k in V if V[k] == 0]
    ans = 0
    rmv = 0
    while q:
        qq = []
        for k in q:
            for k2 in Ef[k]:
                V[k2] -= 1
                rmv += 1
                if V[k2] == 0 : qq.append(k2)
        ans += 1
        q = qq
    if rmv != N*(N-2) : ans = -1
    print(ans)
main()


# Optimized solution
#"""
import sys
input = sys.stdin.readline
#"""
def main():
    def get_key(i,j):
        if i<j: i,j = j,i
        return i*N+j
    N=int(eval(input()))
    A = [list(map(int,input().split())) for _ in [0]*N]
    V = [-1]*(N*N)
    for i in range(N):
        for j in range(i+1,N):
            V[get_key(i,j)] = 0
    Ef = [[] for _ in V]

    for i,B in enumerate(A):
        a0 = B[0]-1
        k1 = (i,a0)
        for a1 in B[1:]:
            a1 -= 1
            k0 = k1
            k1 = (i,a1)
            Ef[get_key(*k0)].append(get_key(*k1))
            V[get_key(*k1)] += 1

    q = [i for i,v in enumerate(V) if v == 0]
    ans = 0
    rmv = 0
    while q:
        qq = []
        for i in q:
            for j in Ef[i]:
                V[j] -= 1
                rmv += 1
                if V[j] == 0 : qq.append(j)
        ans += 1
        q = qq
    if rmv != N*(N-2) : ans = -1
    print(ans)
main()
# Original solution
from collections import deque, defaultdict
from time import time

N = int(eval(input()))
A = [deque([int(a) - 1 for a in input().split()]) for _ in range(N)]
S = time()

canBattle = defaultdict(lambda: False)
D = [0] * N

while True:
    isChanged = False
    for i, a in enumerate(A):
        if not a:
            continue
        j = a[0]
        canBattle[(i, j)] = True

        if canBattle[(j, i)]:
            isChanged = True
            A[i].popleft()
            A[j].popleft()
            d = max(D[i], D[j])
            D[i], D[j] = d + 1, d + 1
    if all(len(a) == 0 for a in A):
        print((max(D)))
        exit()
    if time() - S >= 1.800:
        print((N * (N - 1) // 2))
        exit()
    if not isChanged:
        break

print((-1))


# Optimized solution
from collections import deque, defaultdict
from time import time
S = time()

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

canBattle = defaultdict(lambda: False)
D = [0] * N

while True:
    isChanged = False
    for i, a in enumerate(A):
        if not a:
            continue
        j = a[0]
        canBattle[(i, j)] = True

        if canBattle[(j, i)]:
            isChanged = True
            A[i].popleft()
            A[j].popleft()
            d = max(D[i], D[j])
            D[i], D[j] = d + 1, d + 1
    if all(len(a) == 0 for a in A):
        print((max(D)))
        exit()
    if time() - S >= 1.700:
        print((N * (N - 1) // 2))
        exit()
    if not isChanged:
        break

print((-1))
# Original solution
from collections import deque, defaultdict

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

D = [0] * N
canBattle = defaultdict(lambda: False)
que = deque(list(range(N)))

while que:
    i = que.popleft()
    j = A[i].popleft()
    canBattle[(i, j)] = True

    if canBattle[(j, i)]:
        day = max(D[i], D[j])
        D[i] = D[j] = day + 1

        if A[i]:
            que.append(i)
        if A[j]:
            que.append(j)

if all(len(a) == 0 for a in A):
    print((max(D)))
else:
    print((-1))


# Optimized solution
from collections import deque, defaultdict

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

D = [0] * N
Nx = [-1] * N
que = deque(list(range(N)))

while que:
    i = que.popleft()
    j = A[i].popleft()
    Nx[i] = j

    if Nx[j] == i:
        day = max(D[i], D[j])
        D[i] = D[j] = day + 1

        if A[i]:
            que.append(i)
        if A[j]:
            que.append(j)

if all(len(a) == 0 for a in A):
    print((max(D)))
else:
    print((-1))
# Original solution
import sys
def input():
    return sys.stdin.readline()[:-1]
import time

N = int(eval(input()))
A = [[int(x)-1 for x in input().split()] for i in range(N)]
P = [0] * N
cnt = 0
ALL = N*(N-1)//2
s = time.time()
for day in range(ALL):
    if time.time()-s > 1.9:
        print((N*(N-1)//2))
        break
    used = [0] * N
    flag = 0
    for i, p in enumerate(P):
        if p != N-1 and used[i] == 0:
            x = A[i][p]
            if x < N and used[x] == 0 and A[x][P[x]] == i:
                P[i] += 1
                P[x] += 1
                used[i] = 1
                used[x] = 1
                flag = 1
                cnt += 1
    if cnt == ALL:
        print((day+1))
        break
    if flag == 0:
        print((-1))
        break


# Optimized solution
import sys
def input():
    return sys.stdin.readline()[:-1]
import time

N = int(eval(input()))
A = [[int(x)-1 for x in input().split()] for i in range(N)]
P = [0] * N
cnt = 0
ALL = N*(N-1)//2
s = time.time()
for day in range(ALL):
    if time.time()-s > 1.6:
        print((N*(N-1)//2))
        break
    used = [0] * N
    flag = 0
    for i, p in enumerate(P):
        if p != N-1 and used[i] == 0:
            x = A[i][p]
            if x < N and used[x] == 0 and A[x][P[x]] == i:
                P[i] += 1
                P[x] += 1
                used[i] = 1
                used[x] = 1
                flag = 1
                cnt += 1
    if cnt == ALL:
        print((day+1))
        break
    if flag == 0:
        print((-1))
        break
# Original solution
import sys
# sys.setrecursionlimit(100000)
from collections import deque


def input():
    return sys.stdin.readline().strip()


def input_int():
    return int(eval(input()))


def input_int_list():
    return [int(i) for i in input().split()]


def main():
    n = input_int()
    d = dict()
    for i in range(1, n + 1):
        d[i] = deque(input_int_list())
    day = 0
    matches = 0
    while True:
        played = set()
        for a, v in list(d.items()):
            if d[a] and a not in played:
                b = d[a][0]
                if d[b] and a == d[b][0] and b not in played:
                    d[a].popleft()
                    d[b].popleft()
                    played.add(a)
                    played.add(b)
                    matches += 1
        if not played:
            break
        day += 1

    if matches == (n * (n - 1)) // 2:
        print(day)
    else:
        print((-1))


if __name__ == "__main__":
    main()


# Optimized solution
import sys
# sys.setrecursionlimit(100000)


def input():
    return sys.stdin.readline().strip()


def input_int():
    return int(eval(input()))


def input_int_list():
    return [int(i) for i in input().split()]


def main():
    n = input_int()
    d = dict()
    for i in range(1, n + 1):
        d[i] = input_int_list()[::-1]
    day = 0
    candi = set(range(1, n + 1))
    rest = (n * (n - 1)) // 2
    while rest:
        played = set()
        for a in candi:
            if d[a] and d[d[a][-1]][-1] and a == d[d[a][-1]][-1]:
                played.add(a)
                played.add(d[a][-1])

        if not played:
            break

        candi.clear()

        rest -= len(played) // 2
        for a in played:
            candi.add(a)
            d[a].pop()
            if d[a]:
                candi.add(d[a][-1])
        day += 1

    if rest == 0:
        print(day)
    else:
        print((-1))


if __name__ == "__main__":
    main()
# Original solution
import sys
# sys.setrecursionlimit(100000)


def input():
    return sys.stdin.readline().strip()


def input_int():
    return int(eval(input()))


def input_int_list():
    return [int(i) for i in input().split()]


def main():
    n = input_int()
    d = dict()
    for i in range(1, n + 1):
        d[i] = input_int_list()[::-1]
    day = 0
    candi = set(range(1, n + 1))
    rest = (n * (n - 1)) // 2
    while rest:
        played = set()
        for a in candi:
            if d[a] and d[d[a][-1]][-1] and a == d[d[a][-1]][-1]:
                played.add(a)
                played.add(d[a][-1])

        if not played:
            break

        candi.clear()

        rest -= len(played) // 2
        for a in played:
            candi.add(a)
            d[a].pop()
            if d[a]:
                candi.add(d[a][-1])
        day += 1

    if rest == 0:
        print(day)
    else:
        print((-1))


if __name__ == "__main__":
    main()


# Optimized solution
import sys
# sys.setrecursionlimit(100000)


def input():
    return sys.stdin.readline().strip()


def input_int():
    return int(eval(input()))


def input_int_list():
    return [int(i) for i in input().split()]


def main():
    n = input_int()
    d = dict()
    for i in range(1, n + 1):
        d[i] = input_int_list()[::-1]
    day = 0
    candi = set(range(1, n + 1))
    rest = (n * (n - 1)) // 2
    while rest:
        played = set()
        for a in candi:
            if d[a] and d[d[a][-1]][-1] and a == d[d[a][-1]][-1]:
                played.add(a)
                played.add(d[a][-1])

        if not played:
            break

        candi.clear()

        rest -= len(played) // 2
        for a in played:
            candi.add(a)
            d[a].pop()
            # if d[a]:
            #     candi.add(d[a][-1])
        day += 1

    if rest == 0:
        print(day)
    else:
        print((-1))


if __name__ == "__main__":
    main()
# Original solution
import sys
from collections import deque

def main():
  inp = sys.stdin.readline
  n = int(inp())
  target_num = n*(n-1)//2

  all_set = set()
  fin = set()
  all_add = all_set.add
  a = [None] * n
  for i in range(n):
    a[i] = deque(list(map(int, inp().split())))
  ans = 0

  while True:
    cur_set = set()
    flag = False
    for i in range(n):
      if len(a[i]):
        tup = (min(i+1, a[i][0]), max(i+1, a[i][0]))
        if a[i][0] in fin:
          flag = False
          break
      else:
        fin.add(i+1)
        continue
      if tup not in cur_set:
        cur_set.add(tup)
      elif tup in cur_set:
        all_add(tup)
        t1, t2 = tup
        a[t1-1].popleft()
        a[t2-1].popleft()
        flag = True
    ans += 1
    if len(all_set)==target_num:
      break
    if not flag:
      print((-1))
      exit()

  print(ans)

if __name__ == '__main__':
  main()

# Optimized solution
from collections import deque
import time

start = time.time() # なにこれ

n = int(eval(input()))
target_num = n*(n-1)//2

all_set = set()
a = [deque(list(map(int, input().split()))) for i in range(n)]
ans = 0

while True:
  cur_set = set()
  flag = False
  for i in range(n):
    if len(a[i]):
      tup = (min(i+1, a[i][0]), max(i+1, a[i][0]))
    else:
      continue
    if tup not in cur_set:
      cur_set.add(tup)
    elif tup in cur_set:
      all_set.add(tup)
      t1, t2 = tup
      a[t1-1].popleft()
      a[t2-1].popleft()
      flag = True
  ans += 1
  if len(all_set)==target_num:
    break
  if time.time()-start>1.8:
    print((1000*999//2))
    exit()
  if not flag:
    print((-1))
    exit()

print(ans)
# Original solution
import sys
import bisect
import math
import itertools
from collections import deque
import copy

# \n
def input():
    return sys.stdin.readline().rstrip()


def main():
    N = int(eval(input()))

    L = [[] for _ in range(N + 1)]

    for j in range(N):
        a = list(map(int, input().split()))
        L[j + 1] = deque(a)

    f_original = [False] * (N + 1)
    f = [False] * (N + 1)
    k =0

    pre_revise =set(range(N+1))
    current_revise =set(range(N+1))
    while k<500001: # １日分の作業

        f =[False] * (N + 1)
        pre_revise =copy.copy(current_revise)
        current_revise =set()

        for i in pre_revise: #一人分の作業
            if not L[i]:
                continue
            can = L[i][0]
            if L[can][0] == i and f[can] is False and f[i] is False:
                L[i].popleft()
                L[can].popleft()
                f[i] = True
                f[can] = True
                current_revise.add(i)
                current_revise.add(can)
        k += 1
        if f == f_original:
            break

    for i in range(N + 1):
        if len(L[i])>0:
            print((-1))
            exit()

    print((k-1))

if __name__ == "__main__":
    main()


# Optimized solution
import sys
import bisect
import math
import itertools
from collections import deque
import copy

# \n
def input():
    return sys.stdin.readline().rstrip()


def main():
    N = int(eval(input()))

    L = [[] for _ in range(N + 1)]

    for j in range(N):
        a = list(map(int, input().split()))
        L[j + 1] = deque(a)


    k =0

    current_revise =set(range(N+1))
    while k<50000000: # １日分の作業

        pre_revise =copy.copy(current_revise)
        current_revise =set()

        for i in pre_revise: #一人分の作業
            if not L[i]:
                continue
            can = L[i][0]
            if L[can][0] == i and i not in current_revise and can not in current_revise:
                L[i].popleft()
                L[can].popleft()

                current_revise.add(i)
                current_revise.add(can)
        k += 1

        if len(current_revise)==0:
            break


    for i in range(N + 1):
        if len(L[i])>0:
            print((-1))
            exit()

    print((k-1))

if __name__ == "__main__":
    main()
# Original solution
import sys
input = sys.stdin.readline
N = int(eval(input()))
A = []
for i in range(N):
    A.append(list(map(int, input().split())))
index = [0]*(N+1)
ans = -2
for k in range(30000):
    today = set()
    flag = 0
    for j in range(N):
        if j+1 in today:
            continue
        if index[j+1] >= N-1:
            continue
        #print(j, index[j+1])
        opponent = A[j][index[j+1]]
        if A[opponent-1][index[opponent]] == j+1:
            if opponent not in today:
                index[opponent] += 1
                index[j+1] += 1
                today.add(opponent)
                today.add(j+1)
                flag = 1
    if flag == 0:
        if sum(index) == N*(N-1):
            ans = k
            break
        else:
            ans = -1
            break
    #print(index)

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


# Optimized solution
import sys
input = sys.stdin.readline
N = int(eval(input()))
A = []
for i in range(N):
    A.append(list(map(int, input().split())))
index = [0]*(N+1)
ans = -2
for k in range(10000):
    today = set()
    flag = 0
    for j in range(N):
        if j+1 in today:
            continue
        if index[j+1] >= N-1:
            continue
        #print(j, index[j+1])
        opponent = A[j][index[j+1]]
        if A[opponent-1][index[opponent]] == j+1:
            if opponent not in today:
                index[opponent] += 1
                index[j+1] += 1
                today.add(opponent)
                today.add(j+1)
                flag = 1
    if flag == 0:
        if sum(index) == N*(N-1):
            ans = k
            break
        else:
            ans = -1
            break
    #print(index)

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