/**
 *    author:  tourist
 *    created: 04.05.2019 15:47:55       
**/
#include <bits/stdc++.h>
 
using namespace std;

template<typename T>
ostream& operator<<(ostream& os, vector<T> v) {
  os << "[";
  for (T &i: v) os << i << ",";
  os << "]";
  return os;
}

template<class TH> void _dbg(const char *sdbg, TH h){ cout<<sdbg<<'='<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cout<<*sdbg++;
  cout<<'='<<h<<','; _dbg(sdbg+1, a...);
}

#ifdef __DJKIM613
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (__VA_ARGS__)
#endif

const int N = 188;
 
int dpr[N][N][N];
int dpd[N][N][N];
int new_dpr[N][N][N];
int new_dpd[N][N][N];
 
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int h, w;
  cin >> h >> w;
  vector<string> grid(h);
  for (int i = 0; i < h; i++) {
    cin >> grid[i];
  }
  vector<vector<int>> pref(h + 1, vector<int>(w + 1, 0));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      pref[i + 1][j + 1] = pref[i + 1][j] + pref[i][j + 1] - pref[i][j] + (int) (grid[i][j] == '.');
    }
  }
  auto GetSum = [&](int i1, int j1, int i2, int j2) {
    return pref[i2 + 1][j2 + 1] - pref[i2 + 1][j1] - pref[i1][j2 + 1] + pref[i1][j1];
  };
  auto IsMono = [&](int i1, int j1, int i2, int j2) {
    int sum = GetSum(i1, j1, i2, j2);
    int area = (i2 - i1 + 1) * (j2 - j1 + 1);
    return (sum == 0 || sum == area);
  };
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      for (int i1 = i; i1 < h; i1++) {
        int low = j - 1, high = w - 1;
        while (low < high) {
          int mid = (low + high + 1) >> 1;
          if (IsMono(i, j, i1, mid)) {
            low = mid;
          } else {
            high = mid - 1;
          }
        }
        dpr[i][j][i1] = low;
      }
      for (int j1 = j; j1 < w; j1++) {
        int low = i - 1, high = h - 1;
        while (low < high) {
          int mid = (low + high + 1) >> 1;
          if (IsMono(i, j, mid, j1)) {
            low = mid;
          } else {
            high = mid - 1;
          }
        }
        dpd[i][j][j1] = low;
      }
    }
  }
  for (int it = 0; ; it++) {
    if (dpr[0][0][h - 1] == w - 1) {
      cout << it << '\n';
      break;
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (int i1 = i; i1 < h; i1++) {
          int j1 = dpr[i][j][i1];
          if (j1 < w - 1) {
            j1 = dpr[i][j1 + 1][i1];
          }
          new_dpr[i][j][i1] = j1;
        }
        for (int j1 = j; j1 < w; j1++) {
          int i1 = dpd[i][j][j1];
          if (i1 < h - 1) {
            i1 = dpd[i1 + 1][j][j1];
          }
          new_dpd[i][j][j1] = i1;
        }
      }
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (int i1 = i; i1 < h; i1++) {
          int j1 = new_dpr[i][j][i1];
          while (j1 < w - 1 && new_dpd[i][j][j1 + 1] >= i1) {
            debug(it, i, j, i1);
            ++j1;
          }
          dpr[i][j][i1] = j1;
        }
        for (int j1 = j; j1 < w; j1++) {
          int i1 = new_dpd[i][j][j1];
          while (i1 < h - 1 && new_dpr[i][j][i1 + 1] >= j1) {
            ++i1;
          }
          dpd[i][j][j1] = i1;
        }
      }
    }
  }
  return 0;
}

Measured memory_bytes: 103808