#include <bits/stdc++.h>
using namespace std;
const int INF = 1 << 20;
const double EPS = 1e-7;
namespace KuhnMunkres {
const int MAX_N = 5000;
const int BASE = 1000;
int n;
int graph[MAX_N][MAX_N];
bool usedX[MAX_N];
bool usedY[MAX_N];
int linkTo[MAX_N];
int labelX[MAX_N];
int labelY[MAX_N];
bool findPath(int i) {
  usedX[i] = true;
  for (int j = 0; j < n; j++)
    if (!usedY[j] && labelX[i] + labelY[j] == graph[i][j] && linkTo[j] == -1) {
      usedY[j] = true;
      linkTo[j] = i;
      return true;
    }
  for (int j = 0; j < n; j++)
    if (!usedY[j] && labelX[i] + labelY[j] == graph[i][j]) {
      usedY[j] = true;
      if (linkTo[j] == -1 || findPath(linkTo[j])) {
        linkTo[j] = i;
        return true;
      }
    }
  return false;
}
int KuhnMunkres() {
  memset(linkTo, -1, sizeof(linkTo));
  memset(labelX, 0, sizeof(labelX));
  memset(labelY, 0, sizeof(labelY));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) labelX[i] = max(labelX[i], graph[i][j]);
  for (int k = 0; k < n; k++)
    while (true) {
      memset(usedX, 0, sizeof(usedX));
      memset(usedY, 0, sizeof(usedY));
      if (findPath(k)) break;
      int delta = INF;
      for (int i = 0; i < n; i++)
        if (usedX[i])
          for (int j = 0; j < n; j++)
            if (!usedY[j])
              delta = min(delta, labelX[i] + labelY[j] - graph[i][j]);
      if (delta == 0 || delta == INF) break;
      for (int i = 0; i < n; i++)
        if (usedX[i]) labelX[i] -= delta;
      for (int i = 0; i < n; i++)
        if (usedY[i]) labelY[i] += delta;
    }
  int minTotal = BASE * n;
  for (int i = 0; i < n; i++) minTotal -= labelX[i] + labelY[i];
  int maxTotal = 0;
  for (int i = 0; i < n; i++) maxTotal += labelX[i] + labelY[i];
  return maxTotal;
}
};  // namespace KuhnMunkres
void addEdge(int u, int v, int cost) { KuhnMunkres::graph[u][v] = cost; }
const int MAXN = 100;
int M[MAXN][MAXN];
int id[MAXN][MAXN];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int main() {
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  KuhnMunkres::n = n * m / 2;
  int w = 0, b = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      cin >> M[i][j];
      if ((i + j) % 2)
        id[i][j] = w++;
      else
        id[i][j] = b++;
    }
  for (int i = 0; i < b; i++)
    for (int j = 0; j < w; j++) KuhnMunkres::graph[i][j] = -INF;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      for (int q = 0; q < 4; q++) {
        int ni = i + dx[q];
        int nj = j + dy[q];
        if (ni >= 0 && nj >= 0 && ni < n && nj < m) {
          int c = 0;
          if (M[i][j] == M[ni][nj]) c = 1;
          if ((i + j) % 2)
            KuhnMunkres::graph[id[i][j]][id[ni][nj]] = c;
          else
            KuhnMunkres::graph[id[ni][nj]][id[i][j]] = c;
        }
      }
    }
  cout << n * m / 2 - (KuhnMunkres::KuhnMunkres()) << endl;
  return 0;
}
