#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
typedef double db;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pct __builtin_popcount

#define N 185
int n, m;
string a[N];
int f[N][N][N]; // (xl, xr, yl)
int g[N][N][N]; // (yl, yr, xl)
int f1[N][N][N];
int g1[N][N][N];
int d[N][N], r[N][N];

int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++) cin >> a[i];

	for (int i = 0; i < n; i ++) {
		r[i][m-1] = m-1;
		for (int j = m-2; j >= 0; j--) {
			if (a[i][j] == a[i][j+1]) r[i][j] = r[i][j+1];
			else r[i][j] = j;
		}
	}

	for (int j = 0; j < m; j ++) {
		d[n-1][j] = n-1;
		for (int i = n-2; i >= 0; i--) {
			if (a[i][j] == a[i+1][j]) d[i][j] = d[i+1][j];
			else d[i][j] = i;
		}
	}

	for (int xl = 0; xl < n; xl ++)
		for (int xr = xl; xr < n; xr ++) {
			if (d[xl][m-1] >= xr) f[xl][xr][m-1] = m-1;
			else f[xl][xr][m-1] = -1;
			for (int yl = m-2; yl >= 0; yl--) {
				if (d[xl][yl] >= xr) {
					if (a[xl][yl] == a[xl][yl+1]) f[xl][xr][yl] = max(yl, f[xl][xr][yl+1]);
					else f[xl][xr][yl] = yl;
				} else f[xl][xr][yl] = -1;
			}
		}
	
	for (int yl = 0; yl < m; yl++) 
		for (int yr = yl; yr < m; yr++) {
			if (r[n-1][yl] >= yr) g[yl][yr][n-1] = n-1;
			else g[yl][yr][n-1] = -1;
			for (int xl = n-2; xl >= 0; xl--) {
				if (r[xl][yl] >= yr) {
					if (a[xl][yl] == a[xl+1][yl]) g[yl][yr][xl] = max(xl, g[yl][yr][xl+1]);
					else g[yl][yr][xl] = xl;
				} else g[yl][yr][xl] = -1;
			}
		}

	for (int t = 0; ; t ++) {
		if (f[0][n-1][0] == m-1) {
			printf("%d\n", t);
			break;
		}

		for (int i = 0; i < n; i ++)
			for (int j = 0; j < m; j ++) {
				if (d[i][j] != n-1) d[i][j] = d[d[i][j]+1][j];
				if (r[i][j] != m-1) r[i][j] = r[i][r[i][j]+1];
			}

		memcpy(f1, f, sizeof f);
		memcpy(g1, g, sizeof g);
		// use f1 and g1 to update f and g

		for (int xl = 0; xl < n; xl ++)
			for (int xr = xl; xr < n; xr ++) {
				for (int yl = 0; yl < m; yl ++) {
					if (d[xl][yl] >= xr) f[xl][xr][yl] = max(f[xl][xr][yl], yl);
					if (f1[xl][xr][yl] != -1 && f1[xl][xr][yl] != m-1) {
						f[xl][xr][yl] = max(f[xl][xr][yl], f1[xl][xr][f1[xl][xr][yl]+1]);
					}
					if (f[xl][xr][yl] != -1) {
						g[yl][f[xl][xr][yl]][xl] = max(g[yl][f[xl][xr][yl]][xl], xr);
					}
				}
			}
		
		for (int yl = 0; yl < m; yl++)
			for (int yr = 0; yr < m; yr++) {
				for (int xl = 0; xl < n; xl++) {
					if (r[xl][yl] >= yr) g[yl][yr][xl] = max(g[yl][yr][xl], xl);
					if (g1[yl][yr][xl] != 1 && g1[yl][yr][xl] != n-1) {
						g[yl][yr][xl] = max(g[yl][yr][xl], g1[yl][yr][g1[yl][yr][xl]+1]);
					}
					if (g[yl][yr][xl] != -1) {
						f[xl][g[yl][yr][xl]][yl] = max(f[xl][g[yl][yr][xl]][yl], yr);
					}
				}
			}
		for (int xl = 0; xl < n; xl ++)
			for (int xr = n-1; xr >= xl; xr --) {
				for (int yl = 0; yl < m; yl ++) {
					if (xr+1 < n) f[xl][xr][yl] = max(f[xl][xr][yl], f[xl][xr+1][yl]);
					if (xl > 0) f[xl][xr][yl] = max(f[xl][xr][yl], f[xl-1][xr][yl]);
				}
			}
		for (int yl = 0; yl < m; yl++)
			for (int yr = m-1; yr >= yl; yr--) {
				for (int xl = 0; xl < n; xl++) {
					if (yr+1 < m) g[yl][yr][xl] = max(g[yl][yr][xl], g[yl][yr+1][xl]);
					if (yl > 0) g[yl][yr][xl] = max(g[yl][yr][xl], g[yl-1][yr][xl]);
				}
			}
	}
	return 0;
}


Measured memory_bytes: 98816