#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <map>
#include <set>
#include <list>
#include <random>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <limits>
#include <climits>
#include <cstdint>
#include <chrono>

using namespace std;

using i64 = int64_t;
using P = pair<i64, i64>;

struct edge {
    i64 from, to, cost;
    edge(i64 from, i64 to) : from(from), to(to), cost(1) {}
    edge(i64 from, i64 to, i64 cost) : from(from), to(to), cost(cost) {}
};
using Graph = vector<vector<edge>>;

constexpr i64 INF = std::numeric_limits<i64>::max();
constexpr i64 SINF = std::numeric_limits<i64>::max() / 10;
const i64 dx[4] = { 0,1,0,-1 }, dy[4] = { -1,0,1,0 };
//const i64 dx[5] = {-1,0,0,0,1}, dy[5] = {0,-1,0,1,0};
//const i64 dx[8] = {-1,0,1,1,1,0,-1,-1}, dy[8] = {1,1,1,0,-1,-1,-1,0};
//const i64 dx[9] = {-1,0,1,1,1,0,-1,-1,0}, dy[9] = {1,1,1,0,-1,-1,-1,0,0};

// http://beet-aizu.hatenablog.com/entry/2018/04/08/145516
template<typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }

template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template<typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T& t, const V& v) { t = v; }

template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T& t, const V& v) {
    for (auto& e : t) fill_v(e, v);
}

struct IoSetup {
    IoSetup() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(10);
        cerr << fixed << setprecision(10);
    }
} iosetup;

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

using mint = modint<1000000007>;

int main(){
  i64 n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(n));
  for(int i = 0; i < n; ++i){
    for(int j = 0; j < n - 1; ++j){
      cin >> a[i][j];
      --a[i][j];
    }
  }
  vector<i64> cnt(n, 0);
  queue<i64> now, next;
  for(int i = 0; i < n; ++i){
    if(i == a[a[i][0]][0] && a[i][0] < i) now.push(i);
  }
  if(now.empty()){
    cout << -1 << endl;
    return 0;
  }
  i64 ans = 0;
  while(!now.empty()){
    vector<bool> used(n, false);
    bool flag = true;
    while(!now.empty()){
      int t = now.front(); now.pop();
      int u = a[t][cnt[t]];
      if(used[t] || used[u]) continue;
      if(t == a[u][cnt[u]]){
        cnt[t]++;
        cnt[u]++;
        used[t] = used[u] = true;
        if(cnt[t] != n - 1) next.push(t);
        if(cnt[u] != n - 1) next.push(u);
        flag = false;
      }
    }
    if(flag){
      ans = -1;
      break;
    }else{
      ++ans;
      swap(now, next);
    }
  }
  bool flag = true;
  for(int i = 0; i < n; ++i){
    if(cnt[i] != n - 1) flag = false;
  }
  if(flag){
    cout << ans << endl;
  }else{
    cout << -1 << endl;
  }
}

// 1 2 1 2

Measured memory_bytes: 4224