#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const double EPS = 1e-8;
const long long INF = 1000000000 + 5;
const int MAXN2 = 200 + 2;
int b[MAXN2][MAXN2];
bool visited[MAXN2][MAXN2];
int id[MAXN2][MAXN2];
struct edge {
  int v, to;
  int p;
  long long f, cn, cs;
};
edge a[MAXN];
vector<int> g[MAXN];
int cnt = 0;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int p[MAXN];
int d[MAXN];
int phi[MAXN];
void add_edge(int v, int to, int cn, int cs) {
  a[cnt].v = v;
  a[cnt].to = to;
  a[cnt].f = 0;
  a[cnt].cn = cn;
  a[cnt].cs = cs;
  a[cnt].p = cnt + 1;
  g[v].push_back(cnt);
  cnt++;
  a[cnt].v = to;
  a[cnt].to = v;
  a[cnt].f = 0;
  a[cnt].p = cnt - 1;
  a[cnt].cn = 0;
  a[cnt].cs = -cs;
  g[to].push_back(cnt);
  cnt++;
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &b[i][j]);
    }
  }
  int c1 = 1, c2 = 2;
  int sr = 0, sk = n * m + 1;
  int n2 = n * m + 2;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if ((i + j) % 2 == 0) {
        add_edge(sr, c1, 1, 0);
        id[i][j] = c1;
        c1 += 2;
      } else {
        add_edge(c2, sk, 1, 0);
        id[i][j] = c2;
        c2 += 2;
      }
    }
  }
  int v, to, sz, num, cost;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if ((i + j) % 2 == 0) {
        v = id[i][j];
        for (int h = 0; h < 4; h++) {
          int xn = i + dx[h];
          int yn = j + dy[h];
          if (xn >= 0 && xn < n && yn >= 0 && yn < m) {
            to = id[xn][yn];
            cost = 0;
            if (b[i][j] != b[xn][yn]) cost++;
            add_edge(v, to, 1, cost);
          }
        }
      }
    }
  }
  for (int i = 0; i < n2; i++) d[i] = INF;
  d[sr] = 0;
  for (int i = 0; i < n2; i++) {
    for (int j = 0; j < cnt; j++) {
      if (d[a[j].v] < INF && a[j].cn - a[j].f > 0) {
        if (d[a[j].to] > d[a[j].v] + a[j].cs) {
          d[a[j].to] = d[a[j].v] + a[j].cs;
        }
      }
    }
  }
  for (int i = 0; i < n2; i++) phi[i] = d[i];
  p[sr] = -1;
  long long ans = 0;
  for (;;) {
    for (int i = 0; i < n2; i++) d[i] = INF;
    set<pair<int, int> > q;
    q.insert(make_pair(0, sr));
    d[sr] = 0;
    while (!q.empty()) {
      v = q.begin()->second;
      q.erase(q.begin());
      sz = g[v].size();
      for (int i = 0; i < sz; i++) {
        num = g[v][i];
        to = a[num].to;
        cost = a[num].cs;
        cost += phi[v] - phi[to];
        if (a[num].cn - a[num].f > 0) {
          if (d[to] > d[v] + cost) {
            q.erase(make_pair(d[to], to));
            d[to] = d[v] + cost;
            p[to] = num;
            q.insert(make_pair(d[to], to));
          }
        }
      }
    }
    if (d[sk] == INF) break;
    v = sk;
    long long ds = INF;
    while (p[v] != -1) {
      num = p[v];
      ds = min(ds, a[num].cn - a[num].f);
      v = a[num].v;
    }
    v = sk;
    while (p[v] != -1) {
      num = p[v];
      a[num].f += ds;
      a[a[num].p].f -= ds;
      v = a[num].v;
    }
  }
  for (int i = 0; i < cnt; i++) {
    if (a[i].f > 0) {
      ans += a[i].f * a[i].cs;
    }
  }
  cout << ans;
  return 0;
}
