#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = (int)(j);i <= (int)(k);i ++)
#define debug(x) cerr<<#x<<":"<<x<<endl
#define fix cout<<fixed<<setprecision(20);
const int maxn=(int)2e6+5;
vector<int> E[maxn];
int vis[maxn],ind[maxn],dis[maxn];
int reach[maxn];//longest can reach
inline int id(int x,int y){
    if(x>y)swap(x,y);
    //x--,y--;
    return x+1000*y;
}
int ans=-1;

int dfs(int x){
    //debug(x);
    if(vis[x]==2)return dis[x];
    vis[x]=1;
    for(auto v:E[x]){
        if(vis[v]==1)return -1;
        
        //dis[v]=dis[x]+1;ans=max(ans,dis[v]);
        int ret=dfs(v);
        if(ret==-1)return -1;
        dis[x]=max(dis[x],ret+1);//每个节点存最大值。
        
        
    }
    
    //debug(dis[x]);debug(x);
    
    vis[x]=2;
    return dis[x];
}
int main(){
    //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;cin>>n;
    rep(i,1,n){
        int last=0;
        rep(j,1,n)if(i!=j){
            int x;scanf("%d",&x);
            if(last==0){last=id(i,x);continue;}
            E[last].push_back(id(i,x));ind[id(i,x)]++;
            last=id(i,x);
        }
    }
    
    rep(i,1,n)rep(j,1,i-1)if(ind[id(i,j)]==0){
       // memset(vis,0,sizeof(vis));
        E[0].push_back(id(i,j));
        /* dis[id(i,j)]=1;
        if(dfs(id(i,j))==0){cout<<-1<<endl;return 0;};
        //debug("--"); */
    }
    dis[0]=-1;
    int ans=dfs(0);
    
    cout<<ans<<endl;
    

}
/* 
建DAG，判环
topo 可判环（无法进入队列的点），但无法找最长路径
两种环
一种是链环，用
一种是纯环，
3
2 3
1 3
1 2

12-13
12-23
13-23

4
2 3 4
1 3 4
4 1 2
3 1 2

12-13
13-14
12-23
23-24
34-13
13-23
34-14
14-24

 queue<int> Q;
    rep(i,1,n)rep(j,1,i-1)if(ind[id(i,j)]==0)Q.push(id(i,j)),vis[id(i,j)]=1;
    while(!Q.empty()){
        
        int cur=Q.front();Q.pop();
        debug(cur);debug(vis[cur]);
        for(auto v:E[cur]){
            if(vis[v]){continue;}
            //if(vis[v]==1){cout<<-1<<endl;return 0;}
            ind[v]--;
            if(ind[v]==0)Q.push(v),vis[v]=vis[cur]+1,ans=max(ans,vis[v]);
        }
    }
   // rep(i,1,n)rep(j,1,n)if(i!=j)debug(vis[id(i,j)]),debug(i),debug(j);
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <tuple>
#include <utility>
#include <vector>
#define ll long long
#define itn int
#define endl '\n'
#define co(ans) cout<<ans<<endl
#define COYE cout<<"YES"<<endl
#define COYe cout<<"Yes"<<endl
#define COye cout<<"yes"<<endl
#define CONO cout<<"NO"<<endl
#define CONo cout<<"No"<<endl
#define COno cout<<"no"<<endl
#define FORE(i,a) for(auto &i:a)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define FFOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define RREP(i,n)  FFOR(i,1,n)
#define PB push_back
#define MP make_pair
#define ALL(V) (V).begin(),(V).end()
#define SORT(V) sort((V).begin(),(V).end())
#define REVERSE(V) reverse((V).begin(),(V).end())
#define EACH(V,i) for(typeof((V).begin()) i=(V).begin();i!=(V).end();++i)
#define equals(a,b) (fabs((a)-(b))<EPS)
#define INF ((1LL<<62)-(1LL<<31))
#define EPS 1e-10
#define PI 3.141592653589793238
#define MOD 1000000007
#define MAX 5100000
using namespace std;
using Edge=pair<int,int>;
using Graph=vector<vector<int>>;
inline int toInt(string s){int v;istringstream sin(s);sin>>v;return v;}
template<class T>inline string toString(T x){ostringstream sout;sout<<x;return sout.str();}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return 1;}return 0;}
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
const int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

int N;
deque<int> A[1010];
int step[1010];
int M;
int main(){
  cin>>N;
  REP(i,N){
    REP(j,N-1){
      int x;
	  cin>>x;
	  A[i].push_back(x-1);
    }
  }
  M=N*(N-1)/2;
  
  queue<int> Q;
  REP(i,N) Q.push(i);
  
  int num=0;
  while(Q.size()){
    queue<int> Q2;
    
    while(Q.size()){
      int i=Q.front();
      Q.pop();
      if(step[i]<=num && A[i].size() && A[A[i].front()].front()==i && step[A[i].front()]<=num) {
        step[i]=step[A[i].front()]=num+1;
        Q2.push(i);
        Q2.push(A[i].front());
        A[A[i].front()].pop_front();
        A[i].pop_front();
        M--;
      }
    }
    num++;
    if(M==0) break;
    swap(Q,Q2);
  }
  
  if(M) cout<<-1<<endl;
  else cout<<num<<endl;
}