#include <bits/stdc++.h>
using namespace std;
const int MAXN = 85 * 85;
const int MAXM = 85 * 85 * 8;
const long long C_INF = (long long)1e18;
const int F_INF = 1e9;
int fst[MAXN], nxt[MAXM], to[MAXM];
int cap[MAXM];
long long cost[MAXM];
int V, E;
inline void init(int n = MAXN) {
  memset(fst, -1, sizeof(int) * n);
  V = E = 0;
}
inline int add_node() {
  V++;
  return V - 1;
}
inline void add_edge(int u, int v, int f, long long w) {
  to[E] = v, cap[E] = f, cost[E] = w, nxt[E] = fst[u], fst[u] = E++;
  to[E] = u, cap[E] = 0, cost[E] = -w, nxt[E] = fst[v], fst[v] = E++;
}
int prv[MAXN], q[MAXN], chk[MAXN];
long long dis[MAXN];
void SSSP(int S, int T, int n) {
  int h = 0, t = 0;
  for (int j = 0; j < n; j++) dis[j] = C_INF;
  memset(prv, -1, sizeof(int) * n);
  dis[S] = 0, q[t++] = S, chk[S] = 1;
  while (h != t) {
    int u = q[h++];
    chk[u] = 0;
    if (h == MAXN) h = 0;
    for (int j = fst[u]; ~j; j = nxt[j])
      if (cap[j]) {
        int v = to[j];
        if (dis[v] > dis[u] + cost[j]) {
          dis[v] = dis[u] + cost[j], prv[v] = j;
          if (!chk[v]) {
            q[t++] = v;
            chk[v] = 1;
            if (t == MAXN) t = 0;
          }
        }
      }
  }
}
int ans;
long long solve(int S, int T, int n = V) {
  long long ret = 0;
  while (1) {
    SSSP(S, T, n);
    if (!~prv[T]) break;
    int flw = F_INF;
    for (int u = T; u != S; u = to[prv[u] ^ 1]) flw = min(flw, cap[prv[u]]);
    ret += dis[T] * flw;
    ans += flw;
    for (int u = T; u != S; u = to[prv[u] ^ 1])
      cap[prv[u]] -= flw, cap[prv[u] ^ 1] += flw;
  }
  return ret;
}
int a[85][85];
int dx[] = {0, -1, 0, 1}, dy[] = {1, 0, -1, 0};
int main() {
  int n, m, S, T;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> a[i][j];
    }
  }
  S = 0, T = n * m + 1;
  init();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if ((i + j) % 2) {
        add_edge(i * m + j + 1, T, 1, 0);
        continue;
      }
      for (int k = 0; k < 4; k++) {
        int nwx = i + dx[k], nwy = j + dy[k];
        if (nwx < 0 || nwx >= n || nwy < 0 || nwy >= m) continue;
        if (a[i][j] == a[nwx][nwy]) {
          add_edge(i * m + j + 1, nwx * m + nwy + 1, 1, 0);
        } else {
          add_edge(i * m + j + 1, nwx * m + nwy + 1, 1, 1);
        }
      }
      add_edge(S, i * m + j + 1, 1, 0);
    }
  }
  cout << solve(S, T, n * m + 2) << '\n';
  return 0;
}
