// I need some holiday
// But I don't wish that everyday is holiday
// Because I didn't bear the pain
// Because it wasn't a true freedom
//         ——『イヤホンと蝉時雨』·Orangestar

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef unsigned int UI;
typedef pair<int, int> pii;

#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define MP make_pair
#define fst first
#define snd second
#define SZ(u) ((int) (u).size())
#define ALL(u) (u).begin(), (u).end()

inline void proc_status()
{
	ifstream t("/proc/self/status");
	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}

template<typename T> inline int chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline int chkmax(T &a, const T &b) { return b > a ? a = b, 1 : 0; }
template<typename T> inline T sqr(const T &val) { return val * val; }

namespace fastIO
{
	const int MAX_BUFFER_SIZE = 1 << 16;

	char buffer[MAX_BUFFER_SIZE], *cur = buffer, *ed = buffer;

	inline char getc() { return cur == ed && (ed = (cur = buffer) + fread(buffer, 1, MAX_BUFFER_SIZE, stdin), cur == ed) ? EOF : *cur++; }
}
using fastIO::getc;

template<typename T> inline T read()
{
	register T sum(0), fg(1);
	register char ch(getc());
	for(; !isdigit(ch); ch = getc()) if(ch == '-') fg = -1;
	for(;  isdigit(ch); ch = getc()) sum = sum * 10 - '0' + ch;
	return sum * fg;
}

// END tpl.

inline char safe_getc()
{
	register char ch(getc());
	while(!isgraph(ch)) ch = getc();
	return ch;
}

const int MAXN = 200;

int n, m;

int a[MAXN + 5][MAXN + 5];

inline void input()
{
	n = read<int>(), m = read<int>();
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j)
			a[i][j] = safe_getc() == '.';
}


inline void solve()
{
	static int sum[MAXN + 5][MAXN + 5];
	for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) sum[i][j] = a[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];

	auto chk = [] (int x0, int y0, int x1, int y1) -> int
	{
		if(x0 > x1 || y0 > y1) return 1;
		int S = sum[x1][y1] - sum[x0 - 1][y1] - sum[x1][y0 - 1] + sum[x0 - 1][y0 - 1];
		return S == 0 || S == (x1 - x0 + 1) * (y1 - y0 + 1);
	};

	static int f[2][MAXN + 5][MAXN + 5][MAXN + 5];

	for(int i = 1; i <= n; ++i)
		for(int j1 = 1; j1 <= m; ++j1)
			for(int j2 = j1; j2 <= m; ++j2)
			{
				int l = i - 1, r = n;
				while(l < r)
				{
					int mid = (l + r + 1) / 2;
					if(chk(i, j1, mid, j2)) l = mid;
					else r = mid - 1;
				}
				f[0][i][j1][j2] = l;
			}

	if(f[0][1][1][m] == n) { puts("0"); return; }

	const int LIM = 16;

	for(int t = 1; t <= LIM; ++t)
	{
		int v = (t - 1) & 1, u = t & 1;
		for(int i = 1; i <= n; ++i)
			for(int j1 = 1; j1 <= m; ++j1)
				for(int j2 = j1; j2 <= m; ++j2)
				{
					int res = f[v][f[v][i][j1][j2] + 1][j1][j2];
					if(f[v][i][j1][j2] == n) { f[u][i][j1][j2] = n; continue; }

					int l = j1, r = j2 - 1;
					while(l <= r)
					{
						int mid = (l + r) / 2;
						int t1 = f[v][i][j1][mid], t2 = f[v][i][mid + 1][j2];
						chkmax(res, min(t1, t2));
						if(t1 >= t2) l = mid + 1;
						else r = mid - 1;
					}
					f[u][i][j1][j2] = res;
				}

		if(f[u][1][1][m] == n) { printf("%d\n", t); return; }
	}
	puts("-1");
}

int main()
{
#ifdef K_ON
	freopen("D.in", "r", stdin);
	freopen("D.out", "w", stdout);
#endif

	input();
	solve();

	return 0;
}




Measured memory_bytes: 67584