Problem:
Score : 500 points

Problem Statement

N players will participate in a tennis tournament. We will call them Player 1, Player 2, \ldots, Player N.

The tournament is round-robin format, and there will be N(N-1)/2 matches in total.
Is it possible to schedule these matches so that all of the following conditions are satisfied? If the answer is yes, also find the minimum number of days required.

Each player plays at most one matches in a day.

Each player i (1 \leq i \leq N) plays one match against Player A_{i, 1}, A_{i, 2}, \ldots, A_{i, N-1} in this order.

Constraints

3 \leq N \leq 1000

1 \leq A_{i, j} \leq N

A_{i, j} \neq i

A_{i, 1}, A_{i, 2}, \ldots, A_{i, N-1} are all different.

Input

Input is given from Standard Input in the following format:

N
A_{1, 1} A_{1, 2} \ldots A_{1, N-1}
A_{2, 1} A_{2, 2} \ldots A_{2, N-1}
:
A_{N, 1} A_{N, 2} \ldots A_{N, N-1}

Output

If it is possible to schedule all the matches so that all of the conditions are satisfied, print the minimum number of days required; if it is impossible, print -1.

Sample Input 1

3
2 3
1 3
1 2

Sample Output 1

3

All the conditions can be satisfied if the matches are scheduled for three days as follows:

Day 1: Player 1 vs Player 2

Day 2: Player 1 vs Player 3

Day 3: Player 2 vs Player 3

This is the minimum number of days required.

Sample Input 2

4
2 3 4
1 3 4
4 1 2
3 1 2

Sample Output 2

4

All the conditions can be satisfied if the matches are scheduled for four days as follows:

Day 1: Player 1 vs Player 2, Player 3 vs Player 4

Day 2: Player 1 vs Player 3

Day 3: Player 1 vs Player 4, Player 2 vs Player 3

Day 4: Player 2 vs Player 4

This is the minimum number of days required.

Sample Input 3

3
2 3
3 1
1 2

Sample Output 3

-1

Any scheduling of the matches violates some condition.

Solution in Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(deprecated)]

use std::cell::{Cell, Ref, RefCell, RefMut};
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Formatter, Write as FmtWrite};
use std::io::{stderr, stdin, BufRead, Write};
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;
use std::usize;

const MOD_10_9_7: u64 = 1_000_000_007;
const INF: i64 = 1_000_000_000_000;
const MIN_INF: i64 = -1_000_000_000_000;

/// FYI: https://github.com/vain0x/scan-bench
#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($t:ty) =>
        (rl().parse::<$t>().unwrap());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

fn rl() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_owned()
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

fn a() {
    let s = read!(String);
    let t = read!(String);

    let c_s: Vec<char> = s.chars().collect::<Vec<char>>();
    let t_s: Vec<char> = t.chars().collect::<Vec<char>>();
    let mut ans = 0;
    for i in 0..c_s.len() {
        if c_s[i] == t_s[i] {
            ans += 1;
        }
    }
    println!("{}", ans);
}

fn b() {
    let (a, b) = read!(usize, usize);
    if b == 1 {
        println!("0");
        return;
    }
    let mut ans = 1;
    let mut cnt = a;
    while cnt < b {
        ans += 1;
        cnt += a - 1;
    }
    println!("{}", ans);
}

fn c() {
    let n = read!(usize);
    let h: Vec<usize> = read![[usize]];

    // 最長部分減少列（ただし連続）の長さを求める その長さ-1が答え
    let mut max_len = 0;
    let mut len = 0;
    let mut prev_h = 0;
    for i in 0..n {
        if prev_h >= h[i] {
            prev_h = h[i];
            len += 1;
        } else {
            prev_h = h[i];
            if max_len < len {
                max_len = len;
            }
            len = 1;
        }
    }
    if max_len < len {
        max_len = len;
    }
    println!("{}", max_len - 1);
}

fn d() {
    let n = read!(usize);

    let ans = (n * (n - 1)) / 2;
    println!("{}", ans);
}

fn e() {
    let n = read!(usize);
    let mut a: Vec<VecDeque<usize>> = Vec::with_capacity(n);
    for i in 0..n {
        let v: Vec<usize> = read![[usize]];
        a.push(v.into_iter().map(|x| x - 1).collect());
    }

    let mut days = 0;
    // 対戦があるかを調べなければならないプレイヤーの番号。
    // 初日は当然全プレイヤーを調べなければならないが、2日目以降は「前日に対戦があって試合を消化したプレイヤー」のみを調べていく
    let mut player_for_search: Vec<usize> = (0..n).collect();

    while a.iter().any(|v| v.len() > 0) {
        days += 1;
        let mut combo = Vec::with_capacity(1000);
        'p1: for &i in player_for_search.iter().filter(|&&x| !a[x].is_empty()) {
            let opponent = a[i][0];
            let op_of_op = a[opponent][0];
            if i != op_of_op {
                continue 'p1;
            }
            let tup = if i <= opponent {
                (i, opponent)
            } else {
                (opponent, i)
            };
            if !combo.contains(&tup) {
                combo.push(tup);
            }
        }

        if combo.len() == 0 {
            println!("-1");
            return;
        }

        player_for_search.clear();

        for (p1, p2) in combo {
            a[p1].pop_front();
            a[p2].pop_front();
            player_for_search.push(p1);
            player_for_search.push(p2);
        }
    }
    println!("{}", days);
}

fn f() {
    unimplemented!();
}

fn main() {
    e();
}