package main

import (
	"bufio"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

var (
	readString func() string
	readBytes  func() []byte
	stdout     *bufio.Writer
)

func init() {
	readString, readBytes = newReadString(os.Stdin)
	stdout = bufio.NewWriter(os.Stdout)
}

func newReadString(ior io.Reader) (func() string, func() []byte) {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), math.MaxInt32)
	r.Split(bufio.ScanWords)

	f1 := func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
	f2 := func() []byte {
		return []byte(f1())
	}
	return f1, f2
}

func readInt() int {
	return int(readInt64())
}

func readInt64() int64 {
	i, err := strconv.ParseInt(readString(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(readString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(stdout, f, args...)
}

func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(stdout, args...)
}

func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func min64(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func max64(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func abs64(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

func gcd(a, b int) int {
	if b == 0 {
		return a
	}
	return gcd(b, a%b)
}

func gcd64(a, b int64) int64 {
	if b == 0 {
		return a
	}
	return gcd64(b, a%b)
}

// readString() string
// readInt() int
// readInt64() int64
// readFloat64() float64

// -----------------------------------------------------------------------------

func appendEdge(G [][][][2]int, x, y, a, b int) {
	if b < a {
		a, b = b, a
	}

	G[x][y] = append(G[x][y], [2]int{a, b})
	G[y][x] = append(G[y][x], [2]int{a, b})
}

func main() {
	defer stdout.Flush()

	N := readInt()
	A := make([][]int, N)
	for i := range A {
		A[i] = make([]int, N-1)
		for j := range A[i] {
			A[i][j] = readInt() - 1
		}
	}

	G := make([][][][2]int, N)
	for i := range G {
		G[i] = make([][][2]int, N)
	}

	for i := range A {
		for j := 0; j < len(A[i])-1; j++ {
			appendEdge(G, i, A[i][j], i, A[i][j+1])
		}
	}

	H := make([][]int, N)
	for i := range H {
		H[i] = make([]int, N)
	}

	var ans int
	for i := range A {
		x, y := i, A[i][0]
		h, ok := dfs(G, H, x, y, 0)
		if !ok {
			println(-1)
			return
		}
		ans = max(ans, h)
	}

	println(ans)
}

func dfs(G [][][][2]int, H [][]int, a, b, count int) (int, bool) {
	if len(G)*len(G) < count {
		return 0, false
	}
	if b < a {
		a, b = b, a
	}
	if 0 < H[a][b] {
		return H[a][b], true
	}

	v := 0
	for _, p := range G[a][b] {
		h, ok := dfs(G, H, p[0], p[1], count+1)
		if !ok {
			return 0, false
		}
		v = max(v, h)
	}
	H[a][b] = v + 1
	return v + 1, true
}

// -----------------------------------------------------------------------------


Measured memory_bytes: 573824