#include <bits/stdc++.h>
using namespace std;
int vv[100100], nxt[100100], flow[100100], cc[100100], h[10000], e;
int vis[10000], d[10000], pre[10000];
void add(int u, int v, int f, int c) {
  vv[e] = v, flow[e] = f, cc[e] = c, nxt[e] = h[u], h[u] = e++;
  vv[e] = u, flow[e] = 0, cc[e] = -c, nxt[e] = h[v], h[v] = e++;
}
bool spfa(int s, int t) {
  for (int i = 0; i < 10000; ++i) vis[i] = 0, d[i] = (1 << 30);
  queue<int> q;
  q.push(s);
  d[s] = 0;
  int u, v;
  while (!q.empty()) {
    u = q.front(), q.pop();
    vis[u] = 0;
    for (int i = h[u]; i + 1; i = nxt[i]) {
      v = vv[i];
      if (flow[i] && d[v] > d[u] + cc[i]) {
        d[v] = d[u] + cc[i];
        pre[v] = i;
        if (!vis[v]) vis[v] = 1, q.push(v);
      }
    }
  }
  return d[t] != (1 << 30);
}
int maxFlow(int s, int t) {
  int ans = 0, mi;
  int u, v;
  while (spfa(s, t)) {
    mi = (1 << 30);
    u = t;
    while (u - s) {
      v = pre[u];
      mi = min(mi, flow[v]);
      u = vv[v ^ 1];
    }
    ans += mi * d[t];
    u = t;
    while (u - s) {
      v = pre[u];
      flow[v] -= mi;
      flow[v ^ 1] += mi;
      u = vv[v ^ 1];
    }
  }
  return ans;
}
int a[100][100], id[100][100];
int dir[][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int n, m;
bool inside(int x, int y) { return x >= 0 && y >= 0 && x < n && y < m; }
int main() {
  int s, t, u, v, x, y, cnt = 0;
  scanf("%d%d", &n, &m);
  memset(h, -1, sizeof(h));
  e = 0;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) scanf("%d", &a[i][j]), id[i][j] = ++cnt;
  s = 0, t = n * m + 1;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      if ((i + j) % 2) {
        u = i * m + j + 1;
        for (int k = 0; k < 4; ++k) {
          x = i + dir[k][0];
          y = j + dir[k][1];
          if (!inside(x, y)) continue;
          v = x * m + y + 1;
          add(id[i][j], id[x][y], 1, a[i][j] != a[x][y]);
        }
        add(s, id[i][j], 1, 0);
      } else {
        u = i * m + j + 1;
        add(id[i][j], t, 1, 0);
      }
  printf("%d\n", maxFlow(s, t));
}
