#include <bits/stdc++.h>
using namespace std;
int maxint = ~0U >> 1;
int flow, cost;
int pi[200001 + 1], v[200001 + 1];
int S, T;
struct etype {
  int t, c, u;
  etype* next;
  etype* pair;
  etype() { next = 0; }
  etype(int _t, int _c, int _u, etype* _n) {
    t = _t, c = _c, u = _u, next = _n;
  }
} * e[200001 + 1], *eb[200001 + 1], *Pe, *Pool;
int aug(int w, int lim) {
  int t;
  v[w] = 1;
  if (w == T) {
    flow += lim;
    cost += pi[1] * lim;
    return lim;
  }
  for (etype*& i = e[w]; i; i = i->next)
    if (i->c && !v[i->t] && pi[w] == pi[i->t] + i->u)
      if (t = aug(i->t, min(lim, i->c))) return i->c -= t, i->pair->c += t, t;
  return 0;
}
bool fix() {
  int t = maxint;
  for (int i = S; i <= T; i++)
    if (v[i]) {
      for (etype* j = eb[i]; j; j = j->next)
        if (j->c && !v[j->t]) t = min(t, pi[j->t] + j->u - pi[i]);
    }
  if (t == maxint) return 0;
  for (int i = S; i <= T; i++)
    if (v[i]) e[i] = eb[i], pi[i] += t;
  return 1;
}
void addedge(int s, int t, int c, int u) {
  ++Pe;
  Pe->t = t, Pe->c = c, Pe->u = u, Pe->next = e[s];
  e[s] = Pe;
  ++Pe;
  Pe->t = s, Pe->c = 0, Pe->u = -u, Pe->next = e[t];
  e[t] = Pe;
  e[s]->pair = e[t];
  e[t]->pair = e[s];
}
void prepare() {
  if (Pool == NULL) Pool = new etype[1000001];
  Pe = Pool;
  memset(e, 0, sizeof(e));
}
int MinCostMaxFlow() {
  flow = 0, cost = 0;
  memcpy(eb, e, sizeof(e));
  memset(pi, 0, sizeof(pi));
  do {
    do memset(v, 0, sizeof(v));
    while (aug(S, maxint));
  } while (fix());
  return cost;
}
int n, m;
int board[101][101];
int getID(int x, int y) { return 100 * x + y + 1; }
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int inBoard(int x, int y) {
  if (x <= 0 || x > n) return false;
  if (y <= 0 || y > m) return false;
  return true;
}
int MAIN() {
  while (cin >> n >> m) {
    prepare();
    S = 1, T = getID(101, 1);
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++) cin >> board[i][j];
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= m; j++)
        if ((i + j) % 2 == 0) {
          addedge(S, getID(i, j), 1, 0);
          for (int d = 0; d < 4; d++) {
            int nextI = i + dx[d];
            int nextJ = j + dy[d];
            if (inBoard(nextI, nextJ))
              addedge(getID(i, j), getID(nextI, nextJ), 1,
                      board[i][j] == board[nextI][nextJ] ? 0 : 1);
          }
        } else {
          addedge(getID(i, j), T, 1, 0);
        }
    cout << MinCostMaxFlow() << endl;
  }
  return 0;
}
int main() {
  ios ::sync_with_stdio(false);
  cout << fixed << setprecision(16);
  return MAIN();
}
