// AtCoder My Practice
    // author: Leonardone @ NEETSDKASU
    package main
     
    import (
    	"bufio"; "fmt"; "os"; "strconv"; "strings"
    )
     
    func atoi(s string) int { v, _ := strconv.Atoi(s); return v }
    func atou(s string) uint64 { v, _ := strconv.ParseUint(s, 10, 64); return v }
    func atof(s string) float64 { v, _ := strconv.ParseFloat(s, 64); return v }
    func max(a, b int) int { if a > b { return a }; return b }
    func min(a, b int) int { if a < b { return a }; return b }
     
    var (_ = fmt.Println; _red = bufio.NewScanner(os.Stdin); _tok []string)
    func init() { _red.Buffer(make([]byte, 1e7), 1e7) }
    func gettok() (t string, e bool) {
    	if len(_tok) == 0 { if !_red.Scan() { return }; _tok = strings.Split(_red.Text(), " ") }
    	t = _tok[0]; _tok = _tok[1:]; e = len(_tok) == 0; return
    }
    func read(vs ...interface{}) {
    	for _, v := range vs {
    		switch v := v.(type) {
    		case *int: t, _ := gettok(); *v = atoi(t)
    		case *int64: t, _ := gettok(); *v = int64(atou(t))
    		case *uint64: t, _ := gettok(); *v = atou(t)
    		case *float64: t, _ := gettok(); *v = atof(t)
    		case *string: *v, _ = gettok()
    		case *[]int:
    			if len(*v) == 0 { for { t, e := gettok(); *v = append(*v, atoi(t)); if e { break } }
    			} else { for j := range *v { t, _ := gettok(); (*v)[j] = atoi(t) } }
    		case *[]int64:
    			if len(*v) == 0 { for { t, e := gettok(); *v = append(*v, int64(atou(t))); if e { break } }
    			} else { for j := range *v { t, _ := gettok(); (*v)[j] = int64(atou(t)) } }
    		case *[]uint64:
    			if len(*v) == 0 { for { t, e := gettok(); *v = append(*v, atou(t)); if e { break } }
    			} else { for j := range *v { t, _ := gettok(); (*v)[j] = atou(t) } }
    		case *[]float64:
    			if len(*v) == 0 { for { t, e := gettok(); *v = append(*v, atof(t)); if e { break } }
    			} else { for j := range *v { t, _ := gettok(); (*v)[j] = atof(t) } }
    		case *[]string:
    			if len(*v) == 0 { *v = append(*v, _tok...); _tok = _tok[:0]
    			} else { for j := range *v { (*v)[j], _ = gettok() } }
    		}
    	}
    }
     
    func solve(n, m int, xxs [][]int) int {
        cn := make([]int, m + 1)
        et := make([]bool, m + 1)
        tb := make([][]int, n)
        pr := make([]int, n)
        for i := range tb {
            tb[i] = make([]int, m + 1)
            for j, x := range xxs[i] {
                tb[i][x] = j
            }
            cn[xxs[i][0]]++
        }
        for i := range et { et[i] = true }
        mx, ix := 0, 0
        for i, c := range cn {
            if c > mx { mx = c; ix = i }
        }
        for tt := 1; tt < m; tt++ {
            et[ix] = false
            for i := 0; i < n; i++ {
                if pr[i] < tb[i][ix] {
                    continue
                }
                for j := pr[i]; j < m; j++ {
                    x := xxs[i][j]
                    if !et[x] { continue }
                    pr[i] = tb[i][x]
                    cn[x]++
                    break
                }
            }
            cn[ix] = 0
            mmx := 0
            for i, c := range cn {
                if c > mmx { mmx = c; ix = i }
            }
            if mmx < mx {
                mx = mmx
            }
        }
        return mx
    }
     
    func main() {
        var n, m int
        read(&n, &m)
        xxs := make([][]int, n)
        for i := range xxs {
            xxs[i] = make([]int, m)
            read(&xxs[i])
        }
        ans := solve(n, m, xxs)
        fmt.Println(ans)
    }

Measured memory_bytes: 6272