#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 1001001001
#define LINF 1001001001001001001
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define bit(n) (1LL<<(n))
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> LLP;

bool check(int N, int M, vector<vector<int>> a, int x) {
    vector<deque<int>> list(M);
    vector<bool> playable(M, true);
    vector<deque<int>> A(N);
    rep(i,N) rep(j,M) A[i].push_back(a[i][j]);
    rep(i,N) {
        int k = A[i].front(); A[i].pop_front();
        list[k].push_back(i);
    }
    while (true) {
        int flag = -1;
        int max_count = x;
        rep(i,M) {
            if (list[i].size() > max_count) {
                flag = i;
                max_count = list[i].size();
            }
        }
        if (flag < 0) {
            return true;
        }
        playable[flag] = false;

        while (!list[flag].empty()) {
            int i = list[flag].front(); list[flag].pop_front();
            while (true) {
                if (A[i].empty()) return false;
                int k = A[i].front(); A[i].pop_front();
                if (playable[k]) {
                    list[k].push_back(i);
                    break;
                }
            }
        }
    }
}

int main() {

    int N, M;
    cin >> N >> M;
    vector<vector<int>> A(N, vector<int>(M));
    rep(i,N) rep(j,M) {
        cin >> A[i][j];
        A[i][j]--;
    }

    for (int i = 1; i <= N; i++) {
        if (check(N, M, A, i)) {
            cout << i << endl;
            return 0;
        }
    }
    
    return 0;
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
#define INF (2e9)
const int maxv=10000+10;
const int maxe=100000+10;
int V,E;
int d[maxv];
struct Edge
{
    int from,to,cost;
};
Edge es[maxe];

int p[maxv];
int rank[maxv];

bool cmp(const Edge& a,const Edge& b)
{
    return a.cost<b.cost;
}


void init(int n)
{
    for(int i=0; i<n; i++)
    {
        p[i]=i;
        rank[i]=0;
    }
}
int fnd(int x)
{
    if(x==p[x]) return x;
    return fnd(p[x]);

}
bool is_same(int x,int y)
{
    return fnd(x)==fnd(y);

}
void unite(int x,int y)
{
    x=fnd(x);
    y=fnd(y);
    if(x==y) return;
    if(rank[x]>rank[y])
    {
        p[y]=x;
    }
    else
    {
        p[x]=y;
        if(rank[x]==rank[y]) rank[y]++;
    }
}
void kruskal()
{
    sort(es,es+E,cmp);
    init(V);
    int res=0;
    for(int i=0; i<E; i++)
    {
        Edge &e=es[i];
        if(!is_same(e.from,e.to))
        {
            unite(e.from,e.to);
            res+=e.cost;
        }
    }
    printf("%d\n",res);
}
int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d%d",&V,&E);
    int u,v,cost;
    for(int i=0; i<E; i++)
    {
        scanf("%d%d%d",&u,&v,&cost);
        es[i].from=u;
        es[i].to=v;
        es[i].cost=cost;
    }
    kruskal();
    return 0;
}