using System;
using System.Collections.Generic;
using System.Linq;

public class S
{

    private const long DP_INIT_MINUS1 = -1;
    private const double DP_INIT_DOUBLE_MINUS1 = -1.0;
	private const long MOD = 1000000007;


    //s
    private const int FIRST_WIN = 1;
    private const int SECOND_WIN = 0;

    private static long[,] dp;
    private static long[] cSum;


    public static void Main()
	{
		/*
        var input = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
        var N = input[0];
        var M = input[1];
        */

        var input = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
        var N = input[0];
        solver(N);
        //solver(N,Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse));
    }

    public static void solver(int N){

        /*
            ABC 139 E "League"
            マッチングするときは必ずお見合いになっているはず。
            あと、逆順で見ると必ずフラットで済む。そこから積み上げていけばいい。
            次の対戦相手を列挙した配列の捜査1回が1日にあたって、
            このときの最悪計算回数は…N^2?

            追記：1件だけTLEが出る。とどのつまり、巡回しているやつは落としたいということでは？
            削れそうなところは何？
            マッチング順は保持されなければならない
            例えば4人のときに、
            1番：2,3,4
            2番：1,4,3
            3番：1,4,3
            4番：1,2,3
            だと、3回,2回,1回の全走査が必要で、
            N^2logNに近い何かをしている気がする。1000のときはlogNは大体10なので、
            10000000、確かに怪しいね。

        
         */

        var players = new List<int>[N+1];
        var currentPointer = new int[N+1];
        var currentPlans = new int[N+1];

        int dead = N;
        int day = 0;
        int clear = 0;

        var ch = new List<int>();

        for(int i = 1; i <= N; i++){
            players[i] = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse).OfType<int>().ToList();
            currentPointer[i] = players[i].Count() -1;
            currentPlans[i] = players[i][currentPointer[i]];
        }

        while(dead > 0){
            ch.Clear();
            day++;
            clear = 0;
            for(int i = 1; i <= N; i++){
                if(currentPlans[i] != -1){
                    if(currentPlans[currentPlans[i]] == i){
                        ch.Add(i);
                        ch.Add(currentPlans[i]);
                        clear++;
                        currentPointer[i]--;
                        currentPointer[currentPlans[i]]--;
                        currentPlans[currentPlans[i]] = -1;
                        currentPlans[i] = -1;
                    }
                }
            }
            if(clear == 0){
                day = -1;
                break;
            }
            foreach(var x in ch){
                if(currentPointer[x] == -1){
                    currentPlans[x] = -1;
                    dead--;
                }else{
                    currentPlans[x] = players[x][currentPointer[x]];
                }
            }
            /*
            for(int i = 1; i <= N; i++){
                if(currentPointer[i] == -2) continue;
                if(currentPointer[i] == -1){
                    dead--;
                    currentPlans[i] = -1;
                    currentPointer[i] = -2;
                    continue;
                }
                currentPlans[i] = players[i][currentPointer[i]];
            }
            */

        }
        
        Console.WriteLine(day);


    }

}

Measured memory_bytes: 39684