#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using P = pair<ll, ll>;
using edge = pair<ll, P>;
#define rep(i, n) for(ll i=0;i<(ll)(n);i++)
#define rep2(i, m, n) for(ll i=m;i<(ll)(n);i++)
#define rrep(i, n, m) for(ll i=n;i>=(ll)(m);i--)
using Graph = vector<vector<ll>>;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int ddx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll MOD = 1000000007;
const ll INF = 1000000000000000000L;
#ifdef __DEBUG

#include "cpp-pyprint/pyprint.h"

#endif

int id[1005][1005];

int toId(int x, int y) {
    if (x > y) swap(x, y);
    return id[x][y];
}

class DAG {
    int N;
    Graph graph;
    vector<int> visited;

    void dfs(int v) {
        if (visited[v] == 2) {
            is_acyclic = false;
            return;
        }
        if (!visited[v]) {
            visited[v] = 2;
            for (int u : graph[v]) {
                dfs(u);
            }
            visited[v] = 1;
            sorted.push_back(v);
        }
    }

public:
    vector<int> sorted;

    DAG(int N) : N(N), graph(N), visited(N) {}

    DAG(Graph &graph) : N(graph.size()), graph(graph), visited(graph.size()) {}

    bool is_acyclic = true;

    void add_edge(int a, int b) {
        graph[a].push_back(b);
    }

    void topological_sort() {
        for (int i = 0; i < N; ++i) {
            if (!visited[i]) {
                dfs(i);
            }
        }
        reverse(sorted.begin(), sorted.end());
    }
};

int longest_path(const Graph &graph) {
    int N = graph.size();

    Graph inv(N);
    for (int i = 0; i < N; ++i) {
        for (int v: graph[i]) {
            inv[v].push_back(i);
        }
    }
    vector<int> path_len(N, -1);
    function<void(int)> set_len = [&](int v) {
        if (path_len[v] != -1) {
            return;
        }
        if (inv[v].empty()) {
            path_len[v] = 0;
            return;
        }
        int max_num = 0;
        for (int tar : inv[v]) {
            set_len(tar);
            max_num = max(max_num, path_len[tar]);
        }
        path_len[v] = max_num + 1;

    };
    for (int i = 0; i < N; ++i) {
        set_len(i);
    }
    return *max_element(path_len.begin(), path_len.end());
}

vector<int> topological_sort(const Graph &graph) {
    int N = graph.size();
    vector<int> in_cnt(N, 0);
    for (int i = 0; i < N; ++i) {
        for (int v : graph[i]) {
            in_cnt[v]++;
        }
    }
    queue<int> S;
    for (int i = 0; i < N; ++i) {
        if (in_cnt[i] == 0) S.push(i);
    }
    vector<int> res;
    while (!S.empty()) {
        int u = S.front();
        S.pop();
        res.emplace_back(u);
        for (int v : graph[u]) {
            in_cnt[v]--;
            if (in_cnt[v] == 0) {
                S.push(v);
            }
        }
    }
    return res;
}

void Main() {
    int N;
    cin >> N;
    int MAX_V = (1005 - 1) * 1005 / 2;
    int cnt = 0;
    rep(i, 1005) rep(j, 1005) {
            if (i < j) {
                id[i][j] = cnt++;
            }
        }
    Graph graph(MAX_V, vector<ll>());
    rep(i, N) {
        vector<int> A(N - 1);
        rep(j, N - 1) {
            cin >> A[j];
        }
        rep(j, N - 2) {
            graph[toId(i, A[j] - 1)].push_back(toId(i, A[j + 1] - 1));
        }
    }

    DAG dag(graph);
    dag.topological_sort();
    if (!dag.is_acyclic) {
        cout << -1 << endl;
    } else {
        cout << longest_path(graph) + 1 << endl;
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    Main();
}


Measured memory_bytes: 92532