#include typedef struct List { struct List *next; int v, flag, id; } list; int DFS(list *adj[], int par[], int u) { int w; for (; adj[u] != NULL; adj[u] = adj[u]->next) { w = adj[u]->v; if (par[w] == -2) { par[w] = adj[u]->id; return w; } else if (par[w] >= 0) continue; par[w] = adj[u]->id; w = DFS(adj, par, w); if (w > 0) return w; } return 0; } int bipartite_matching(int N1, int N2, list *adj[], list e[], int mu[]) { int i, j, u, w, ans = 0, par[1001], q[1001], head, tail; list *aux[1001] = {}, *p; static list f[500001]; while (1) { for (u = 1; u <= N1; u++) par[u] = -1; for (w = N1 + 1; w <= N1 + N2; w++) par[w] = (mu[w] == 0)? -2: -1; for (u = 1, i = 0; u <= N1 + N2; u++) { for (p = adj[u], aux[u] = NULL; p != NULL; p = p->next) { if (p->flag == 0) continue; w = p->v; f[i].v = w; f[i].id = p->id; f[i].next = aux[u]; aux[u] = &(f[i++]); } } for (u = 1, tail = 0; u <= N1; u++) { if (mu[u] > 0) continue; else par[u] = 0; w = DFS(aux, par, u); if (w > 0) q[tail++] = w; } if (tail == 0) break; else ans += tail; for (head = 0; head < tail; head++) { w = q[head]; i = par[w] * 2; u = e[i+1].v; for (i = par[w] * 2, u = e[i+1].v; par[u] != 0; w = e[par[u]*2].v, i = par[w] * 2, u = e[i+1].v) { j = par[u] * 2; mu[u] = w; mu[w] = u; e[i].flag = 0; e[i+1].flag = 1; e[j].flag = 1; e[j+1].flag = 0; } mu[u] = w; mu[w] = u; e[i].flag = 0; e[i+1].flag = 1; } } return ans; } int main() { int i, j, H, W, A[501][501]; scanf("%d %d", &H, &W); for (i = 1; i <= H; i++) for (j = 1; j <= W; j++) scanf("%d", &(A[i][j])); int k, u, w, N = H + W, count[500001] = {}, ans = 0, mu[1001]; list *appear[500001] = {}, d[250001], *adj[1001], e[500001], *p; for (i = 1, k = 0; i <= H; i++) { for (j = 1; j <= W; j++) { if (A[i][j] == 0) continue; else count[A[i][j]]++; d[k].v = i; d[k].id = j; d[k].next = appear[A[i][j]]; appear[A[i][j]] = &(d[k++]); } } for (i = 1; i <= 500000; i++) { if (count[i] <= 1) { if (count[i] == 1) ans++; continue; } for (u = 1; u <= N; u++) { adj[u] = NULL; mu[u] = 0; } for (p = appear[i], k = 0; p != NULL; p = p->next) { u = p->v; w = p->id + H; e[k].v = w; e[k].flag = 1; e[k].id = k / 2; e[k].next = adj[u]; adj[u] = &(e[k++]); e[k].v = u; e[k].flag = 0; e[k].id = k / 2; e[k].next = adj[w]; adj[w] = &(e[k++]); } ans += bipartite_matching(H, W, adj, e, mu); } printf("%d\n", ans); fflush(stdout); return 0; }