#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()

const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007; // 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
/*-------------------------------------------------*/
int hei[2][185][185][185], wid[2][185][185][185];

int main() {
  cin.tie(0); ios::sync_with_stdio(false);
  // freopen("input.txt", "r", stdin);

  memset(hei, -1, sizeof(hei));
  memset(wid, -1, sizeof(wid));
  int h, w; cin >> h >> w;
  vector<vector<char> > a(h, vector<char>(w)); REP(i, h) REP(j, w) cin >> a[i][j];

  vector<vector<int> > sum(h + 1, vector<int>(w + 1, 0));
  REP(i, h) REP(j, w) sum[i + 1][j + 1] = sum[i + 1][j] + (a[i][j] == '#' ? 1 : 0);
  FOR(j, 1, w + 1) FOR(i, 1, h) sum[i + 1][j] += sum[i][j];
  REP(r1, h) FOR(r2, r1, h) {
    int mx = 0;
    REP(c1, w) {
      mx = max(mx, c1);
      while (mx < w) {
        int cnt = sum[r2+1][mx+1] - sum[r2+1][c1] - sum[r1][mx+1] + sum[r1][c1];
        if (a[r1][c1] == '.') {
          if (cnt == 0) ++mx;
          else break;
        } else {
          if (cnt == (r2-r1+1) * (mx-c1+1)) ++mx;
          else break;
        }
      }
      hei[0][r1][r2][c1] = mx-1;
    }
  }
  REP(c1, w) FOR(c2, c1, w) {
    int mx = 0;
    REP(r1, h) {
      mx = max(mx, r1);
      while (mx < h) {
        int cnt = sum[mx+1][c2+1] - sum[mx+1][c1] - sum[r1][c2+1] + sum[r1][c1];
        if (a[r1][c1] == '.') {
          if (cnt == 0) ++mx;
          else break;
        } else {
          if (cnt == (mx-r1+1) * (c2-c1+1)) ++mx;
          else break;
        }
      }
      wid[0][r1][c1][c2] = mx-1;
    }
  }
  if (hei[0][0][h-1][0] == w-1) {
    cout << 0 << '\n';
    return 0;
  }

  REP(com, 16) {
    REP(r1, h) FOR(r2, r1, h) {
      REP(c1, w) {
        int tmp = hei[com%2][r1][r2][c1];
        if (tmp+1 < w) tmp = hei[com%2][r1][r2][tmp+1];
        hei[(com+1)%2][r1][r2][c1] = max(hei[(com+1)%2][r1][r2][c1], tmp);
      }
      int mx = 0;
      REP(c1, w) {
        mx = max(mx, c1);
        while (mx < w) {
          int tmp = wid[com%2][r1][c1][mx];
          if (tmp+1 < h) tmp = wid[com%2][tmp+1][c1][mx];
          if (tmp < r2) break;
          else ++mx;
        }
        hei[(com+1)%2][r1][r2][c1] = max(hei[(com+1)%2][r1][r2][c1], mx-1);
      }
    }
    REP(c1, w) FOR(c2, c1, w) {
      REP(r1, h) {
        int tmp = wid[com%2][r1][c1][c2];
        if (tmp+1 < h) tmp = wid[com%2][tmp+1][c1][c2];
        wid[(com+1)%2][r1][c1][c2] = max(wid[(com+1)%2][r1][c1][c2], tmp);
      }
      int mx = 0;
      REP(r1, h) {
        mx = max(mx, r1);
        while (mx < h) {
          int tmp = hei[com%2][r1][mx][c1];
          if (tmp+1 < w) tmp = hei[com%2][r1][mx][tmp+1];
          if (tmp < c2) break;
          else ++mx;
        }
        wid[(com+1)%2][r1][c1][c2] = max(wid[(com+1)%2][r1][c1][c2], mx-1);
      }
    }
    // cout << hei[(com+1)%2][0][h-1][0] << '\n';
    if (hei[(com+1)%2][0][h-1][0] == w-1) {
      cout << com+1 << '\n';
      return 0;
    }
    memset(hei[com%2], -1, sizeof(hei[com%2]));
    memset(wid[com%2], -1, sizeof(wid[com%2]));
  }
}


Measured memory_bytes: 99456