/********************************************************************************
	
	Code by a weak man who named CYJian, and he hopes the code can get more points.

	Algorithm: 

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

//{{{ FAST IO AND SOME FUNCTIONS
const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
#define ri read_int()
#define rl read_ll()
#define ra read_alpha()
#define FILE(s) freopen(s"in", "r", stdin), freopen(s"out", "w", stdout)

template<typename T>
inline void read(T &x) {
	char ch, t = 0; x = 0;
	while(!isdigit(ch = ge)) t |= ch == '-';
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = ge;
	x = t ? -x : x;
}
inline char read_alpha() { char c = ge; while(!isalpha(c) && c != EOF) c = ge; return c; }
inline int read_int() { int x; return read(x), x; }
inline ll read_ll() { ll x; return read(x), x; }

template<typename T> inline void chkmin(T&a, T b) { a = a < b ? a : b; }
template<typename T> inline void chkmax(T&a, T b) { a = a > b ? a : b; }
//}}}

short R[200][200][200];
short D[200][200][200];
char s[200][200];
int S[200][200];

inline int Sum(int lx, int rx, int ly, int ry) {
	return S[rx][ry] - S[lx - 1][ry] - S[rx][ly - 1] + S[lx - 1][ly - 1];
}

inline int chk(int lx, int rx, int ly, int ry) {
	int s = Sum(lx, rx, ly, ry);
	return !s || s == (rx - lx + 1) * (ry - ly + 1);
}

int main() {
#ifdef LOCAL
	FILE("");
#endif
	int n, m;
	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 = 1; j <= m; j++)
			S[i][j] = s[i][j] == '#';
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			S[i][j] += S[i - 1][j];
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			S[i][j] += S[i][j - 1];
	for(int l = 1; l <= m; l++)
		for(int r = l; r <= m; r++)
			for(int i = n; i >= 1; i--)
				if(D[l][r][i + 1] && chk(i, D[l][r][i + 1], l, r))
					D[l][r][i] = D[l][r][i + 1];
				else if(chk(i, i, l, r))
					D[l][r][i] = i;
	for(int l = 1; l <= n; l++)
		for(int r = l; r <= n; r++)
			for(int i = m; i >= 1; i--)
				if(R[l][r][i + 1] && chk(l, r, i, R[l][r][i + 1]))
					R[l][r][i] = R[l][r][i + 1];
				else if(chk(l, r, i, i))
					R[l][r][i] = i;
	for(int res = 0;; res++) {
		if(D[1][m][1] == n) return cout << res << endl, 0;
		for(int l = 1; l <= m; l++)
			for(int r = l; r <= m; r++)
				for(int i = 1; i <= n; i++)
					if(D[l][r][D[l][r][i] + 1])
						D[l][r][i] = D[l][r][D[l][r][i] + 1];
		for(int l = 1; l <= n; l++)
			for(int r = l; r <= n; r++)
				for(int i = 1; i <= m; i++)
					if(R[l][r][R[l][r][i] + 1])
						R[l][r][i] = R[l][r][R[l][r][i] + 1];
		for(int x = 1; x <= n; x++)
			for(int y = 1; y <= m; y++) {
				for(int X = n, Y = y; Y <= m; Y++) {
					while(X >= x && R[x][X][y] < Y) --X;
					if(X < x) break;
					chkmax(D[y][Y][x], short(X));
				}
				for(int X = x, Y = m; X <= n; X++) {
					while(Y >= y && D[y][Y][x] < X) --Y;
					if(Y < y) break;
					chkmax(R[x][X][y], short(Y));
				}
			}
	}
	return 0;
}

Measured memory_bytes: 30720