# coding: utf-8

# Your code here!



import sys

sys.setrecursionlimit(10**6)

readline = sys.stdin.readline



n = int(eval(input()))

a = [[min(i,int(j)-1)+max(i,int(j)-1)*(max(i,int(j)-1)-1)//2 for j in readline().split()] for i in range(n)]



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



g = [[] for i in range(N)]

p = [[] for i in range(N)]



for i in range(n):

    for j in range(n-2):

        g[a[i][j]].append(a[i][j+1])

        p[a[i][j+1]].append(a[i][j])

        

#print(g)

#print(p)



ans = [0]*(N)



indegree = [len(v) for v in p] # 流入辺の数を数えた配列

Source = [i for i, c in enumerate(indegree) if c == 0] #流入辺0の点の集合

#L = [] #ソート結果をためておく配列

num = 0

while Source:

    node = Source.pop()

    #L.append(node)

    num += 1

    for child in g[node]:

        indegree[child] -= 1 #辺 node -> child を削除する

        if ans[child] < ans[node]+1: ans[child] = ans[node]+1     

        if indegree[child] == 0:

            Source.append(child)



#print(num)

if num != N:

    print((-1))

else:

    print((max(ans)+1))



#print(ans)

    

# coding: utf-8

# Your code here!



import sys

sys.setrecursionlimit(10**6)

readline = sys.stdin.readline



n = int(eval(input()))

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



a = [[int(j)-1 for j in readline().split()] for _ in range(n)]

g = [[] for i in range(N)]

indegree = [0]*N



def encode(x,y):

    if x > y: x,y = y,x

    return y*(y-1)//2 + x



for i in range(n):

    for j in range(n-2):

        p,q = encode(i,a[i][j]), encode(i,a[i][j+1])

        g[p].append(q)

        indegree[q] += 1



"""

トポロジカルソート

q をheapq にしたりすると、辞書順にとりだしたりとかができる。

返り値：DAG ならトポソのひとつを返す。ループがあれば-1を返す

"""

"""

g: グラフの隣接行列

indegree: 流入辺の数を数えた配列

"""

def topological_sort_queue(g,indegree):

    q = [i for i,c in enumerate(indegree) if c == 0] #流入辺0の点の集合

    L = [] #ソート結果をためておく配列

    ans =[0]*len(g)

    a = 0

    while q:

        v = q.pop()

        L.append(v)

        for c in g[v]: #配る

            ans[c] = max(ans[c],ans[v]+1)

            a = max(a,ans[c])

            indegree[c] -= 1 #辺 node -> child を削除する

            if indegree[c] == 0:

                q.append(c)

    if len(L) != N: #print("サイクル検出")

        return -1

    else: #return(L)

        return(a+1)        



print((topological_sort_queue(g,indegree)))

# coding: utf-8
# Your code here!
import sys

sys.setrecursionlimit(10**6)
readline = sys.stdin.readline
n = int(eval(input()))
a = [
    [
        min(i, int(j) - 1) + max(i, int(j) - 1) * (max(i, int(j) - 1) - 1) // 2
        for j in readline().split()
    ]
    for i in range(n)
]
N = n * (n - 1) // 2
g = [[] for i in range(N)]
p = [[] for i in range(N)]
for i in range(n):
    for j in range(n - 2):
        g[a[i][j]].append(a[i][j + 1])
        p[a[i][j + 1]].append(a[i][j])
# print(g)
# print(p)
ans = [0] * (N)
indegree = [len(v) for v in p]  # 流入辺の数を数えた配列
Source = [i for i, c in enumerate(indegree) if c == 0]  # 流入辺0の点の集合
# L = [] #ソート結果をためておく配列
num = 0
while Source:
    node = Source.pop()
    # L.append(node)
    num += 1
    for child in g[node]:
        indegree[child] -= 1  # 辺 node -> child を削除する
        if ans[child] < ans[node] + 1:
            ans[child] = ans[node] + 1
        if indegree[child] == 0:
            Source.append(child)
# print(num)
if num != N:
    print((-1))
else:
    print((max(ans) + 1))
# print(ans)

# coding: utf-8
# Your code here!
import sys

sys.setrecursionlimit(10**6)
readline = sys.stdin.readline
n = int(eval(input()))
N = n * (n - 1) // 2
a = [[int(j) - 1 for j in readline().split()] for _ in range(n)]
g = [[] for i in range(N)]
indegree = [0] * N


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


for i in range(n):
    for j in range(n - 2):
        p, q = encode(i, a[i][j]), encode(i, a[i][j + 1])
        g[p].append(q)
        indegree[q] += 1
"""
トポロジカルソート
q をheapq にしたりすると、辞書順にとりだしたりとかができる。
返り値：DAG ならトポソのひとつを返す。ループがあれば-1を返す
"""
"""
g: グラフの隣接行列
indegree: 流入辺の数を数えた配列
"""


def topological_sort_queue(g, indegree):
    q = [i for i, c in enumerate(indegree) if c == 0]  # 流入辺0の点の集合
    L = []  # ソート結果をためておく配列
    ans = [0] * len(g)
    a = 0
    while q:
        v = q.pop()
        L.append(v)
        for c in g[v]:  # 配る
            ans[c] = max(ans[c], ans[v] + 1)
            a = max(a, ans[c])
            indegree[c] -= 1  # 辺 node -> child を削除する
            if indegree[c] == 0:
                q.append(c)
    if len(L) != N:  # print("サイクル検出")
        return -1
    else:  # return(L)
        return a + 1


print((topological_sort_queue(g, indegree)))

-a = [ -    [ -        min(i, int(j) - 1) + max(i, int(j) - 1) * (max(i, int(j) - 1) - 1) // 2 -        for j in readline().split() -    ] -    for i in range(n) -] +a = [[int(j) - 1 for j in readline().split()] for _ in range(n)] -p = [[] for i in range(N)] +indegree = [0] * N + + +def encode(x, y): +    if x > y: +        x, y = y, x +    return y * (y - 1) // 2 + x + + -        g[a[i][j]].append(a[i][j + 1]) -        p[a[i][j + 1]].append(a[i][j]) -# print(g) -# print(p) -ans = [0] * (N) -indegree = [len(v) for v in p]  # 流入辺の数を数えた配列 -Source = [i for i, c in enumerate(indegree) if c == 0]  # 流入辺0の点の集合 -# L = [] #ソート結果をためておく配列 -num = 0 -while Source: -    node = Source.pop() -    # L.append(node) -    num += 1 -    for child in g[node]: -        indegree[child] -= 1  # 辺 node -> child を削除する -        if ans[child] < ans[node] + 1: -            ans[child] = ans[node] + 1 -        if indegree[child] == 0: -            Source.append(child) -# print(num) -if num != N: -    print((-1)) -else: -    print((max(ans) + 1)) -# print(ans) +        p, q = encode(i, a[i][j]), encode(i, a[i][j + 1]) +        g[p].append(q) +        indegree[q] += 1 +""" +トポロジカルソート +q をheapq にしたりすると、辞書順にとりだしたりとかができる。 +返り値：DAG ならトポソのひとつを返す。ループがあれば-1を返す +""" +""" +g: グラフの隣接行列 +indegree: 流入辺の数を数えた配列 +""" + + +def topological_sort_queue(g, indegree): +    q = [i for i, c in enumerate(indegree) if c == 0]  # 流入辺0の点の集合 +    L = []  # ソート結果をためておく配列 +    ans = [0] * len(g) +    a = 0 +    while q: +        v = q.pop() +        L.append(v) +        for c in g[v]:  # 配る +            ans[c] = max(ans[c], ans[v] + 1) +            a = max(a, ans[c]) +            indegree[c] -= 1  # 辺 node -> child を削除する +            if indegree[c] == 0: +                q.append(c) +    if len(L) != N:  # print("サイクル検出") +        return -1 +    else:  # return(L) +        return a + 1 + + +print((topological_sort_queue(g, indegree)))