#include <bits/stdc++.h>
using namespace std;
template <int N, typename T>
struct MinCost {
  int l[N], tot, p[N], u, v, src, sink;
  T d[N];
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      Q;
  bool inq[N];
  const T inf = 1e9;
  struct Edge {
    int v, x, cap;
    T w;
  } E[555555];
  void addedge(int u, int v, int cap, T w) {
    E[tot] = (Edge){v, l[u], cap, w};
    l[u] = tot++;
    E[tot] = (Edge){u, l[v], 0, -w};
    l[v] = tot++;
  }
  void init() {
    memset(l, -1, sizeof l);
    tot = 0;
  }
  void mcmf(int _src, int _sink, int& flow, T& cost, bool MaxFlow) {
    src = _src, sink = _sink;
    flow = cost = 0;
    while (true) {
      fill(d, d + _sink + 1, inf);
      d[src] = 0;
      while (!Q.empty()) Q.pop();
      Q.push({0, src});
      while (!Q.empty()) {
        pair<int, int> x = Q.top();
        Q.pop();
        u = x.second;
        if (d[u] < x.first) continue;
        if (u == sink) break;
        for (int i = l[u]; ~i; i = E[i].x) {
          int v = E[i].v;
          if (E[i].cap && d[v] > d[u] + E[i].w) {
            d[v] = d[u] + E[i].w;
            p[v] = i;
            Q.push({d[v], v});
          }
        }
      }
      if (MaxFlow) {
        if (d[sink] == inf) break;
      } else {
        if (d[sink] >= 0) break;
      }
      int c = inf;
      for (int v = sink; v != src; v = E[p[v] ^ 1].v) {
        c = min(c, E[p[v]].cap);
      }
      flow += c;
      cost += c * d[sink];
      for (int v = sink; v != src; v = E[p[v] ^ 1].v) {
        E[p[v]].cap -= c;
        E[p[v] ^ 1].cap += c;
      }
    }
  }
};
const int N = 80;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
int field[N][N];
MinCost<N * N + 3, int> F;
int n, m;
inline bool In(int i, int j) { return i >= 0 && i < n && j >= 0 && j < m; }
int main() {
  scanf("%d%d", &n, &m);
  int src = n * m, sink = src + 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", field[i] + j);
    }
  }
  F.init();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (i + j & 1) {
        F.addedge(src, i * m + j, 1, 0);
        for (int _ = 0; _ < 4; _++) {
          int ii = i + dx[_];
          int jj = j + dy[_];
          if (In(ii, jj)) {
            F.addedge(i * m + j, ii * m + jj, 1,
                      field[i][j] == field[ii][jj] ? 0 : 1);
          }
        }
      } else
        F.addedge(i * m + j, sink, 1, 0);
    }
  }
  int flow, cost;
  F.mcmf(src, sink, flow, cost, true);
  printf("%d\n", cost);
  return 0;
}
