#include <bits/stdc++.h>
using namespace std;
const int maxn = 100;
const int maxe = 111110;
int head[maxn], e, pre[maxn];
int dist[maxn];
bool inq[maxn];
struct Pool {
  int cap, next, v, cost;
} edge[maxe];
int s, t;
int flow, cost;
void add(int u, int v, int cap, int cost) {
  edge[e].v = v;
  edge[e].cap = cap;
  edge[e].cost = cost;
  edge[e].next = head[u];
  head[u] = e++;
}
bool spfa() {
  memset(dist, 0x3f, sizeof(dist));
  memset(inq, 0, sizeof(inq));
  dist[s] = 0;
  inq[s] = 1;
  pre[s] = 0;
  queue<int> q;
  q.push(s);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    inq[u] = 0;
    for (int i = head[u]; i != -1; i = edge[i].next) {
      int v = edge[i].v;
      if (edge[i].cap && dist[u] < dist[v] - edge[i].cost) {
        dist[v] = dist[u] + edge[i].cost;
        pre[v] = i;
        if (!inq[v]) {
          inq[v] = 1;
          q.push(v);
        }
      }
    }
  }
  if (dist[t] == 0x3f3f3f3f) return 0;
  return 1;
}
void cal() {
  int sum = 0x3f3f3f3f, p;
  for (int u = t; u != s; u = edge[p ^ 1].v) {
    p = pre[u];
    sum = min(sum, edge[p].cap);
  }
  flow += sum;
  for (int u = t; u != s; u = edge[p ^ 1].v) {
    p = pre[u];
    edge[p].cap -= sum;
    edge[p ^ 1].cap += sum;
    cost += edge[p].cost * sum;
  }
}
void init() {
  memset(head, -1, sizeof(head));
  memset(edge, 0, sizeof(edge));
  e = 0;
}
int ma[maxn][maxn];
int main() {
  int n, m;
  while (~scanf("%d%d", &n, &m)) {
    init();
    memset(ma, 0, sizeof(ma));
    s = 0, t = n * m + 1;
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++) scanf("%d", &ma[i][j]);
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++) {
        if ((i + j) & 1)
          add(s, i * m + j - m, 1, 0), add(i * m + j - m, s, 0, 0);
        else
          add(i * m + j - m, t, 1, 0), add(t, i * m + j - m, 0, 0);
        if (j < m) {
          if ((i + j) & 1)
            add(i * m + j - m, i * m + j - m + 1, 1, ma[i][j] != ma[i][j + 1]),
                add(i * m + j - m + 1, i * m + j - m, 0,
                    -(ma[i][j] != ma[i][j + 1]));
          else
            add(i * m + j - m + 1, i * m + j - m, 1, ma[i][j] != ma[i][j + 1]),
                add(i * m + j - m, i * m + j - m + 1, 0,
                    -(ma[i][j] != ma[i][j + 1]));
        }
        if (i < n) {
          if ((i + j) & 1)
            add(i * m + j - m, i * m + j, 1, ma[i][j] != ma[i + 1][j]),
                add(i * m + j, i * m + j - m, 0, -(ma[i][j] != ma[i + 1][j]));
          else
            add(i * m + j, i * m + j - m, 1, ma[i][j] != ma[i + 1][j]),
                add(i * m + j - m, i * m + j, 0, -(ma[i][j] != ma[i + 1][j]));
        }
      }
    flow = cost = 0;
    while (spfa()) cal();
    printf("%d\n", cost);
  }
  return 0;
}
