#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <queue>

const int kN = 185 + 5;
int n, m;
char s[kN][kN];
int dp[kN][kN][kN];

int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++ i) {
    scanf("%s", s[i] + 1);
  }
  for (int i = 1; i <= n; ++ i) {
    for (int j = m; j >= 1; -- j) {
      dp[i][j][j] = s[i][j] == s[i - 1][j] ? dp[i - 1][j][j] + 1 : 1;
      for (int k = j + 1; k <= m; ++ k) {
        dp[i][j][k] = s[i][k] == s[i][k - 1] ? std::min(dp[i][j][k - 1], dp[i][j + 1][k]) : 0;
      }
    }
  }
  if (dp[n][1][m] == n) return puts("0"), 0;

  for (int depth = 1; ; ++ depth) {
    for (int i = n; i >= 1; -- i) {
      for (int j = 1; j <= m; ++ j) {
        std::vector<int> tmp(m + 1);
        for (int k = j + 1, p = j; k <= m; ++ k) {
          while (p + 2 < k && dp[i][j][p] > dp[i][p + 1][k] && dp[i][j][p + 1] > dp[i][p + 2][k]) {
            tmp[k] = std::max(tmp[k], dp[i][p + 1][k]);
            ++ p;
          }
          tmp[k] = std::max(tmp[k], std::min(dp[i][j][p], dp[i][p + 1][k]));
          if (p + 2 <= k) {
            tmp[k] = std::max(tmp[k], std::min(dp[i][j][p + 1], dp[i][p + 2][k]));
          }
        }
        for (int k = j; k <= m; ++ k) {
          dp[i][j][k] = std::max(dp[i - dp[i][j][k]][j][k] + dp[i][j][k], tmp[k]);
        }
      }
    }
    if (dp[n][1][m] == n) {
      printf("%d\n", depth);
      break;
    }
  }
}
