#include <bits/stdc++.h>
using namespace std;
const int NM_MAX = 82;
const int U_MAX = 6404;
int U;
vector<int> edges[U_MAX];
short int C[U_MAX][U_MAX];
short int R[U_MAX][U_MAX];
short int F[U_MAX][U_MAX];
int dist[U_MAX];
int parent[U_MAX];
queue<int> q;
bool BellmanFord() {
  for (int i = 1; i <= U; i++) {
    dist[i] = INT_MAX;
    parent[i] = -1;
  }
  parent[1] = 0;
  dist[1] = 0;
  q.push(1);
  while (q.empty() == false) {
    int u = q.front();
    q.pop();
    for (int v : edges[u])
      if (R[u][v] > 0 && dist[u] + C[u][v] < dist[v]) {
        dist[v] = dist[u] + C[u][v];
        parent[v] = u;
        q.push(v);
      }
  }
  return (parent[U] != -1);
}
void pushFlow(int u, int v, int flow) {
  R[u][v] -= flow;
  R[v][u] += flow;
  F[u][v] += flow;
  F[v][u] -= flow;
}
int minCostMaxFlow() {
  while (BellmanFord() == true) {
    int u;
    u = U;
    int flow = INT_MAX;
    while (u != 1) {
      flow = min(flow, (int)R[parent[u]][u]);
      u = parent[u];
    }
    u = U;
    while (u != 1) {
      pushFlow(parent[u], u, flow);
      u = parent[u];
    }
  }
  int ans = 0;
  for (int i = 1; i <= U; i++)
    for (int j = 1; j <= U; j++) ans += C[i][j] * F[i][j];
  return ans;
}
int n, m;
int ma[NM_MAX][NM_MAX];
int da[] = {-1, 0, 1, 0}, db[] = {0, 1, 0, -1};
bool inside(int a, int b) { return (1 <= a && a <= n && 1 <= b && b <= m); }
int codif(int a, int b) { return (a - 1) * m + b + 1; }
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) cin >> ma[i][j];
  U = 1 + n * m + 1;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      for (int d = 0; d < 4; d++) {
        int i1 = i + da[d], j1 = j + db[d];
        if (inside(i1, j1)) {
          int u = codif(i, j), v = codif(i1, j1);
          if ((i + j) & 1) swap(u, v);
          edges[u].push_back(v);
          edges[v].push_back(u);
          C[u][v] = (ma[i][j] != ma[i1][j1]);
          R[u][v] = 1;
          F[u][v] = 0;
          C[v][u] = -(ma[i][j] != ma[i1][j1]);
          R[v][u] = 0;
          F[v][u] = 0;
        }
      }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if ((i + j) & 1) {
        int u = codif(i, j);
        edges[u].push_back(U);
        edges[U].push_back(u);
        C[u][U] = 0;
        R[u][U] = 1;
        F[u][U] = 0;
        C[U][u] = 0;
        R[U][u] = 0;
        F[U][u] = 0;
      } else {
        int u = codif(i, j);
        edges[1].push_back(u);
        edges[u].push_back(1);
        C[1][u] = 0;
        R[1][u] = 1;
        F[1][u] = 0;
        C[u][1] = 0;
        R[u][1] = 0;
        F[u][1] = 0;
      }
  cout << minCostMaxFlow() / 2 << "\n";
  return 0;
}
