n = int(eval(input()))

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



l = [i for i in range(n)]

pos = [0] * n

res = 0

cnt = 0

while True:

    res += 1

    flag = True

    tmp = l.copy()

    l = []

    used = [False] * n

    for v in tmp:

        if used[v] or pos[v] == n - 1:

            continue



        opp = a[v][pos[v]] - 1



        if used[opp] or pos[opp] == n - 1:

            continue



        if a[opp][pos[opp]] - 1 == v:

            pos[v] += 1

            pos[opp] += 1

            l.append(v)

            l.append(opp)

            used[v] = True

            used[opp] = True

            flag = False

            if pos[v] == n - 1:

                cnt += 1

            if pos[opp] == n - 1:

                cnt += 1



    if flag:

        print((-1))

        break



    if cnt == n:

        print(res)

        break
import collections



def topological():

    """トポロジカルソート (有向グラフ) O(V+E)



    Vars:

        n (int):     頂点数

        edge (list): 辺に関するリスト (edge[i]: iを始点に持つ辺の終点のリスト)

    

    Returns:

        list/bool: トポロジカル順序 (閉路が存在する場合はFalse)

    """

    in_degree = [0] * n

    for i in range(n):

        for v in edge[i]:

            in_degree[v] += 1

    

    nodelist = collections.deque()

    for i in range(n):

        if in_degree[i] == 0:

            nodelist.append(i)

    

    res = []

    while nodelist:

        p = nodelist.popleft()

        for q in edge[p]:

            in_degree[q] -= 1

            depth[q] = max(depth[q], depth[p] + 1)

            if in_degree[q] == 0:

                nodelist.append(q)

        

        res.append(p)

    

    if len(res) == n:

        return res

    else:

        return False





m = int(eval(input()))

a = [list(map(int, input().split())) for _ in range(m)]



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



num = 0

table = [[-1] * m for _ in range(m)]

for i in range(m):

    for j in range(i+1, m):

        table[i][j] = num

        table[j][i] = num

        num += 1



edge = [[] for _ in range(n)]

for i in range(m):

    for j in range(m-2):

        edge[table[i][a[i][j]-1]].append(table[i][a[i][j+1]-1])



depth = [0] * n

l = topological()



if not l:

    print((-1))

else:

    print((max(depth) + 1))
n = int(eval(input()))
a = [list(map(int, input().split())) for _ in range(n)]
l = [i for i in range(n)]
pos = [0] * n
res = 0
cnt = 0
while True:
    res += 1
    flag = True
    tmp = l.copy()
    l = []
    used = [False] * n
    for v in tmp:
        if used[v] or pos[v] == n - 1:
            continue
        opp = a[v][pos[v]] - 1
        if used[opp] or pos[opp] == n - 1:
            continue
        if a[opp][pos[opp]] - 1 == v:
            pos[v] += 1
            pos[opp] += 1
            l.append(v)
            l.append(opp)
            used[v] = True
            used[opp] = True
            flag = False
            if pos[v] == n - 1:
                cnt += 1
            if pos[opp] == n - 1:
                cnt += 1
    if flag:
        print((-1))
        break
    if cnt == n:
        print(res)
        break

import collections


def topological():
    """トポロジカルソート (有向グラフ) O(V+E)
    Vars:
        n (int):     頂点数
        edge (list): 辺に関するリスト (edge[i]: iを始点に持つ辺の終点のリスト)
    Returns:
        list/bool: トポロジカル順序 (閉路が存在する場合はFalse)
    """
    in_degree = [0] * n
    for i in range(n):
        for v in edge[i]:
            in_degree[v] += 1
    nodelist = collections.deque()
    for i in range(n):
        if in_degree[i] == 0:
            nodelist.append(i)
    res = []
    while nodelist:
        p = nodelist.popleft()
        for q in edge[p]:
            in_degree[q] -= 1
            depth[q] = max(depth[q], depth[p] + 1)
            if in_degree[q] == 0:
                nodelist.append(q)
        res.append(p)
    if len(res) == n:
        return res
    else:
        return False


m = int(eval(input()))
a = [list(map(int, input().split())) for _ in range(m)]
n = m * (m - 1) // 2
num = 0
table = [[-1] * m for _ in range(m)]
for i in range(m):
    for j in range(i + 1, m):
        table[i][j] = num
        table[j][i] = num
        num += 1
edge = [[] for _ in range(n)]
for i in range(m):
    for j in range(m - 2):
        edge[table[i][a[i][j] - 1]].append(table[i][a[i][j + 1] - 1])
depth = [0] * n
l = topological()
if not l:
    print((-1))
else:
    print((max(depth) + 1))

-n = int(eval(input())) -a = [list(map(int, input().split())) for _ in range(n)] -l = [i for i in range(n)] -pos = [0] * n -res = 0 -cnt = 0 -while True: -    res += 1 -    flag = True -    tmp = l.copy() -    l = [] -    used = [False] * n -    for v in tmp: -        if used[v] or pos[v] == n - 1: -            continue -        opp = a[v][pos[v]] - 1 -        if used[opp] or pos[opp] == n - 1: -            continue -        if a[opp][pos[opp]] - 1 == v: -            pos[v] += 1 -            pos[opp] += 1 -            l.append(v) -            l.append(opp) -            used[v] = True -            used[opp] = True -            flag = False -            if pos[v] == n - 1: -                cnt += 1 -            if pos[opp] == n - 1: -                cnt += 1 -    if flag: -        print((-1)) -        break -    if cnt == n: -        print(res) -        break +import collections + + +def topological(): +    """トポロジカルソート (有向グラフ) O(V+E) +    Vars: +        n (int):     頂点数 +        edge (list): 辺に関するリスト (edge[i]: iを始点に持つ辺の終点のリスト) +    Returns: +        list/bool: トポロジカル順序 (閉路が存在する場合はFalse) +    """ +    in_degree = [0] * n +    for i in range(n): +        for v in edge[i]: +            in_degree[v] += 1 +    nodelist = collections.deque() +    for i in range(n): +        if in_degree[i] == 0: +            nodelist.append(i) +    res = [] +    while nodelist: +        p = nodelist.popleft() +        for q in edge[p]: +            in_degree[q] -= 1 +            depth[q] = max(depth[q], depth[p] + 1) +            if in_degree[q] == 0: +                nodelist.append(q) +        res.append(p) +    if len(res) == n: +        return res +    else: +        return False + + +m = int(eval(input())) +a = [list(map(int, input().split())) for _ in range(m)] +n = m * (m - 1) // 2 +num = 0 +table = [[-1] * m for _ in range(m)] +for i in range(m): +    for j in range(i + 1, m): +        table[i][j] = num +        table[j][i] = num +        num += 1 +edge = [[] for _ in range(n)] +for i in range(m): +    for j in range(m - 2): +        edge[table[i][a[i][j] - 1]].append(table[i][a[i][j + 1] - 1]) +depth = [0] * n +l = topological() +if not l: +    print((-1)) +else: +    print((max(depth) + 1))