//
// Created by Koki Igarashi on 7/28/20.
//

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef int Int;
typedef pair<Int, Int> pii;
typedef pair<Int, double> pid;
typedef pair<double, double> pdd;
typedef pair<Int, pii> pip;
typedef pair<pii, Int> ppi;
typedef pair<double, Int> pdp;
typedef vector<Int> veci;
typedef vector<double> vecd;
typedef vector<int> veci;
typedef vector<ll> vecll;
typedef vector<double> vecd;
typedef vector<pii> vecpii;
typedef vector<ppi> vecppi;
typedef vector<veci> mati;
typedef vector<vecll> matll;
typedef vector<vecd> matd;
#define PB(x) push_back(x)
#define EB(x) emplace_back(x)
#define ALL(x) x.begin(),x.end()
#define SZ(x) (x).size()
#define CLR(x) memset(x,0,sizeof x)
#define pdebug() printf("%d\n",__LINE__)
#define REP(i, a, b) for(int i = (a);i <= (b);i++)
#define FORO(i, n) REP(i,0,(int)n-1)
#define FORI(i, n) REP(i,1,(int)n)
#define FORIT(i, t) for(auto i = t.begin();i != t.end();i++)
#define eps 1e-6
#define sqr(x) ((x)*(x))
#define dist(_a, _b) sqrt(sqr(_a.A-_b.A)+sqr(_a.B-_b.B))
#define norm(_a) sqrt(sqr(_a.A)+sqr(_a.B))
#define DEBUG 1
#if DEBUG
#define DUMP(a) do { std::cout << #a " = " << (a) << ", "; } while(false)
#define DUMPLN(a) do { std::cout << #a " = " << (a) << std::endl; } while(false)
#else
#define DUMP(a)
#define DUMPLN(a)
#endif
template<typename T, typename U>
inline void getMin(T &a, U b) { if (a > b) a = b; }
template<typename T, typename U>
inline void getMax(T &a, U b) { if (a < b) a = b; }
template<typename T>
vector<T> getVector(const int n) { return vector<T>(n); }
template<typename T>
vector<T> getVector(const int n, const T a) { return vector<T>(n, a); }
template<typename T>
vector<T> getEmptyVector() { return vector<T>(); }
template<typename T>
void appendAll(vector<T> &a, vector<T> b) { a.insert(a.end(), b.begin(), b.end()); }
// #define X first
// #define Y second
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};
const ll MOD = 1000000007;
const int MAXN = 1 << 17;
const int inf = 1 << 20;
const int NIL = -inf;
int popcount(int x) { return __builtin_popcount(x); }

int N;
mati A;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> N;
    A.resize(N);
    FORO(i, N) {
        A[i].resize(N - 1);
        FORO(j, N - 1) {
            cin >> A[i][j];
        }
    }
    veci idx(N);
    int day = 0;
    int gcnt = 0;
    while(gcnt < N * (N - 1) / 2) {
        day++;
        veci used(N);
        bool no_game = true;
        for(int i = 0;i < N;i++) {
            if(used[i] || idx[i] == N - 1) continue;
            int opp = A[i][idx[i]] - 1;
            if(used[opp]) continue;
            if(A[opp][idx[opp]] == i + 1) {
                idx[opp]++;
                idx[i]++;
                used[i] = used[opp] = 1;
                gcnt++;
                no_game = false;
            }
        }
        if(no_game) break;
    }

    cout << (gcnt == N * (N - 1) / 2 ? day : -1) << endl;

    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(var, begin, end) for (int var = (begin); var <= (end); var++)
#define RFOR(var, begin, end) for (int var = (begin); var >= (end); var--)
#define REP(var, length) FOR(var, 0, length - 1)
#define RREP(var, length) RFOR(var, length - 1, 0)
#define EACH(value, var) for (auto value : var)
#define SORT(var) sort(var.begin(), var.end())
#define REVERSE(var) reverse(var.begin(), var.end())
#define RSORT(var) SORT(var); REVERSE(var)
#define OPTIMIZE_STDIO ios::sync_with_stdio(false); cin.tie(0); cout.precision(10); cout << fixed
#define endl '\n'

const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;
using P = pair<int, int>;

void solve(istream& cin, ostream& cout) {
  int n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(n - 1));
  REP(i, n) {
    REP(j, n - 1) {
      cin >> a[i][j];
      a[i][j]--;
    }
    REVERSE(a[i]);
  }
  vector<P> que;
  auto check = [&](int i) {
    if (a[i].size() == 0) return;
    int j = a[i].back();
    if (a[j].back() == i) {
      if (i > j) que.push_back(P(j, i));
      else
        que.push_back(P(i, j));
    }
  };
  REP(i, n) {
    check(i);
  }
  int day = 0;
  while (que.size() > 0) {
    day++;
    SORT(que);
    que.erase(unique(que.begin(), que.end()), que.end());
    vector<P> prevQ;
    swap(prevQ, que);
    EACH(p, prevQ) {
      int i = p.first;
      int j = p.second;
      a[i].pop_back();
      a[j].pop_back();
    }
    EACH(p, prevQ) {
      int i = p.first;
      int j = p.second;
      check(i);
      check(j);
    }
  }
  REP(i, n) {
    if (a[i].size() != 0) {
      cout << -1 << endl;
      return;
    }
  }
  cout << day << endl;
}

#ifndef TEST
int main() {
  OPTIMIZE_STDIO;
  solve(cin, cout);
  return 0;
}
#endif
