#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
#include <cstring>
#include <stack>
#include <algorithm>

const long long int INFTY = 1e9;

long long int maximum_path(long long int N, std::vector<std::vector<long long int> > &G, std::vector<long long int> &dp_table, /*std::vector<long long int> &reached_table, */long long int start, long long int original_start);
long long int game_id(long long int N, long long int player1, long long int player2);

int topological_sort(std::vector<std::vector<long long int> > &G, long long int V, std::vector<long long int> &sorted_index);


int main(){
  
  // read problem
  long long int N, tmp1, tmp2;
  scanf("%lld", &N);
  std::vector<std::vector<long long int> > G(N*N);
  
  for(long long int i = 0; i < N; i++){
    scanf("%lld", &tmp1);
    for(long long int j = 0; j < N-2; j++){
      tmp2 = tmp1;
      scanf("%lld", &tmp1);
      G[game_id(N, i, tmp2-1)].push_back(game_id(N, i, tmp1-1));
      //std::cerr << "edge from " << game_id(N, i, tmp2-1) << " to " << game_id(N, i, tmp1-1) << std::endl;
    }
  }
  
  // check closed loop
  std::vector<long long int> sorted_index;
  int result = topological_sort(G, N*N, sorted_index);
  if(result == 1){
    std::cout << -1 << std::endl;
    return 0;
  }
  
  
  // solve problem
  std::vector<long long int> dp_table/*, reached_table*/;
  for(long long int i = 0; i < N*N; i++){
    dp_table.push_back(-1);
    //reached_table.push_back(-1);
  }
  
  long long int ans = 0;
  for(long long int i = 0; i < N*N; i++){
    ans = std::max(ans, maximum_path(N*N, G, dp_table, /*reached_table,*/ i, i));
    //std::cerr << "ahaha" << i << " "<< ans  << std::endl;
  }
  
  std::cerr << "Answer: " << std::endl;
  if(ans >= INFTY){
    std::cout << "-1" << std::endl;
  }
  else{
    std::cout << ans+1 << std::endl;
  }
  
  return 0;
}

long long int maximum_path(long long int N, std::vector<std::vector<long long int> > &G, std::vector<long long int> &dp_table, /*std::vector<long long int> &reached_table, */long long int start, long long int original_start){
  
  // if the point have been already tested
  if(dp_table[start] >= 0){
    return dp_table[start];
  }
  // if there is no path starting from start
  if(G[start].size() == 0){
    dp_table[start] = 0;
    return 0;
  }
  // if there are edges starting from start
  else{
    long long int tmp = 0;
    for(long long int i = 0; i < G[start].size(); i++){
      if(G[start][i] == original_start){
        dp_table[start] = INFTY;
        return INFTY;
      }
      else{
        tmp = std::max(tmp, maximum_path(N, G, dp_table, /*reached_table,*/ G[start][i],original_start)+1);
      }
    }
    dp_table[start] = tmp;
    return tmp;
  }
}

long long int game_id(long long int N, long long int player1, long long int player2){
  if(player1 < player2){
    return player1*N + player2;
  }
  else{
    return player2*N + player1;
  }
}

int topological_sort(std::vector<std::vector<long long int> > &G, long long int V, std::vector<long long int> &sorted_index){
  
  // clear sorted_index
  sorted_index.clear();
  
  // calculate in_degree
  std::vector<long long int> in_degree(V);

  for(long long int i = 0; i < V; i++){
    for(long long int j = 0; j < G[i].size(); j++){
      in_degree[G[i][j]]++;
    }
  }
  
  // calculate topological sort
  std::stack<long long int> stack;
  for(long long int i = 0; i < V; i++){
    if(in_degree[i] == 0){
      stack.push(i);
    }
  }
  
  long long int tmp_vertex;
  while(!stack.empty()){
    // get vertex with zero in-degree
    tmp_vertex = stack.top();
    stack.pop();
    // push vertex to sorted_index
    sorted_index.push_back(tmp_vertex);
    // update state
    for(long long int i = 0; i < G[tmp_vertex].size(); i++){
      in_degree[G[tmp_vertex][i]]--;
      if(in_degree[G[tmp_vertex][i]] == 0){
        stack.push(G[tmp_vertex][i]);
      }
    }
  }
  
  // check topological sort
  // if topological sort is carried out successfully (the given graph is DAG)
  if(sorted_index.size() == V){
    return 0;
  }
  // if topological sort failed (the given graph is NOT DAG)
  else{
    return 1;
  }
}


Measured memory_bytes: 63580