#include <bits/stdc++.h>
using namespace std;
const int INF = 111111111;
const int maxn = 100;
const int maxx = 11111;
int tot;
int a[maxn][maxn], ty[maxn][maxn], head[maxx];
int vis[maxx], pre[maxx], dist[maxx], path[maxx];
struct {
  int v, next, w, c;
} edge[maxx << 2];
queue<int> q;
void init() {
  tot = 0;
  memset(head, -1, sizeof(head));
}
void add(int u, int v, int c, int w) {
  edge[tot].v = v;
  edge[tot].next = head[u];
  edge[tot].w = w;
  edge[tot].c = c;
  head[u] = tot++;
}
bool spfa(int n, int m) {
  int i, u, v;
  while (!q.empty()) q.pop();
  for (i = 0; i <= (n + 1) * m; i++) vis[i] = 0, dist[i] = INF;
  vis[0] = 1;
  dist[0] = 0;
  q.push(0);
  while (!q.empty()) {
    u = q.front();
    q.pop();
    vis[u] = 0;
    for (i = head[u]; i != -1; i = edge[i].next) {
      v = edge[i].v;
      if (edge[i].c > 0 && dist[v] > dist[u] + edge[i].w) {
        dist[v] = dist[u] + edge[i].w;
        pre[v] = u;
        path[v] = i;
        if (vis[v] == 0) {
          q.push(v);
          vis[v] = 1;
        }
      }
    }
  }
  if (dist[1] != INF)
    return true;
  else
    return 0;
}
void work(int n, int m) {
  int ans = 0;
  while (spfa(n, m)) {
    int aug = INF;
    int u = 1;
    while (u != 0) {
      aug = min(aug, edge[path[u]].c);
      u = pre[u];
    }
    u = 1;
    while (u != 0) {
      edge[path[u]].c -= aug;
      edge[path[u] ^ 1].c += aug;
      u = pre[u];
    }
    ans += dist[1] * aug;
  }
  printf("%d\n", ans);
}
int main() {
  int i, j, n, m, k;
  while (scanf("%d%d", &n, &m) != EOF) {
    init();
    for (i = 1; i <= n; i++)
      for (j = 1; j <= m; j++) {
        scanf("%d", &a[i][j]);
        ty[i][j] = (i + j) & 1;
      }
    for (i = 1; i <= n; i++)
      for (j = 1; j <= m; j++)
        if (ty[i][j] == 0) {
          if (i != 1) {
            k = a[i][j] == a[i - 1][j] ? 0 : 1;
            add(i * m + j, i * m + j - m, 1, k);
            add(i * m + j - m, i * m + j, 0, -k);
          }
          if (i != n) {
            k = a[i][j] == a[i + 1][j] ? 0 : 1;
            add(i * m + j, i * m + j + m, 1, k);
            add(i * m + j + m, i * m + j, 0, -k);
          }
          if (j != 1) {
            k = a[i][j] == a[i][j - 1] ? 0 : 1;
            add(i * m + j, i * m + j - 1, 1, k);
            add(i * m + j - 1, i * m + j, 0, -k);
          }
          if (j != m) {
            k = a[i][j] == a[i][j + 1] ? 0 : 1;
            add(i * m + j, i * m + j + 1, 1, k);
            add(i * m + j + 1, i * m + j, 0, -k);
          }
        }
    for (i = 1; i <= n; i++)
      for (j = 1; j <= m; j++)
        if (ty[i][j] == 0) {
          add(0, i * m + j, 1, 0);
          add(i * m + j, 0, 0, 0);
        } else {
          add(i * m + j, 1, 1, 0);
          add(1, i * m + j, 0, 0);
        }
    work(n, m);
  }
  return 0;
}
