#include <bits/stdc++.h>
const int inf = 0x3f3f3f3f;
const int maxe = 19040;
const int maxv = 6405;
struct edge {
  int t, nxt, c, w;
} es[maxe << 1];
int h[maxv], cnt;
inline void ins(int s, int t, int c, int w) {
  es[cnt] = (edge){t, h[s], c, w};
  h[s] = cnt++;
  es[cnt] = (edge){s, h[t], 0, -w};
  h[t] = cnt++;
}
int dis[maxv], iter[maxv], q[maxv], he, ta, S, T, cost, flow;
bool vis[maxv];
inline bool SPFA() {
  memset(dis, 0x3f, sizeof(dis));
  vis[T] = ta = 1;
  dis[T] = he = 0;
  q[he] = T;
  while (he != ta) {
    register int v = q[he++];
    he %= maxv;
    for (register int i = h[v]; ~i; i = es[i].nxt)
      if (es[i ^ 1].c && dis[es[i].t] > dis[v] + es[i ^ 1].w) {
        dis[es[i].t] = dis[v] + es[i ^ 1].w;
        if (!vis[es[i].t]) {
          vis[es[i].t] = 1;
          if (dis[es[i].t] < dis[q[he]])
            he = (he - 1 + maxv) % maxv, q[he] = es[i].t;
          else
            q[ta++] = es[i].t, ta %= maxv;
        }
      }
    vis[v] = 0;
  }
  memcpy(iter, h, sizeof(h));
  return dis[S] != inf;
}
inline int dfs(int v, int f) {
  vis[v] = 1;
  if (v == T) return f;
  register int used = 0;
  for (register int &i = iter[v]; ~i; i = es[i].nxt)
    if (es[i].c && !vis[es[i].t] && dis[es[i].t] == dis[v] - es[i].w) {
      register int w = dfs(es[i].t, ((f) < (es[i].c) ? (f) : (es[i].c)));
      if (w) {
        es[i].c -= w;
        es[i ^ 1].c += w;
        used += w;
        cost += es[i].w * w;
        if (used == f) return f;
      }
    }
  return used;
}
int n, m, mp[81][81];
int main() {
  memset(h, -1, sizeof(h));
  scanf("%d%d", &n, &m);
  T = n * m + 1;
  for (register int i = 1; i <= n; i++)
    for (register int j = 1; j <= m; j++) scanf("%d", &mp[i][j]);
  for (register int i = 1; i <= n; i++)
    for (register int j = 1; j <= m; j++)
      if ((i + j) & 1) {
        ins(S, ((i)*m - m + (j)), 1, 0);
        if (i > 1)
          ins(((i)*m - m + (j)), ((i - 1) * m - m + (j)), 1,
              mp[i][j] != mp[i - 1][j]);
        if (j > 1)
          ins(((i)*m - m + (j)), ((i)*m - m + (j - 1)), 1,
              mp[i][j] != mp[i][j - 1]);
        if (i < n)
          ins(((i)*m - m + (j)), ((i + 1) * m - m + (j)), 1,
              mp[i][j] != mp[i + 1][j]);
        if (j < m)
          ins(((i)*m - m + (j)), ((i)*m - m + (j + 1)), 1,
              mp[i][j] != mp[i][j + 1]);
      } else
        ins(((i)*m - m + (j)), T, 1, 0);
  while (SPFA()) do {
      memset(vis, 0, sizeof(vis));
      flow += dfs(S, inf);
    } while (vis[T]);
  printf("%d\n", cost);
  return 0;
}
