#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 210;
int dp1[2][maxn][maxn][maxn] = {0};//up down left
int dp2[2][maxn][maxn][maxn] = {0};//up left right
int n, m;
char s[maxn][maxn];
int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= m; j ++)
			cin >> s[i][j];
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= m; j ++)
		{
			int t = 1;
			for(; j + t <= m && s[i][j + t] == s[i][j]; t ++);
			dp1[0][i][i][j] = t;
			t = 1;
			for(; i + t <= n && s[i + t][j] == s[i][j]; t ++);
			dp2[0][i][j][j] = t;
		}
	for(int h = 1; h <= n; h ++)
		for(int up = 1; up + h <= n; up ++)
		{
			int down = up + h;
			for(int left = 1; left <= m; left ++)
				if(s[up][left] == s[down][left])
					dp1[0][up][down][left] = min(dp1[0][up][down - 1][left], dp1[0][down][down][left]);
		}
	for(int up = 1; up <= n; up ++)
		for(int len = 1; len <= m; len ++)
			for(int left = 1; left + len <= m; left ++)
			{
				int right = left + len;
				if(s[up][left] == s[up][right])
					dp2[0][up][left][right] = min(dp2[0][up][left][right - 1], dp2[0][up][right][right]);
			}
	bool asd = 0;
	for(int t = 0; t < 20; t ++)//////////////////////////////////////////////////TODO
	{
		//cerr << t << " --------------- " << endl;
		/*
		for(int up = 1; up <= n; up ++)
			for(int down = up; down <= n; down ++)
				for(int left = 1; left <= m; left ++)
					cout << "dp1 " << t << " " << up << " " << down << " " << left << " " << dp1[asd][up][down][left] << endl;
		for(int up = 1; up <= n; up ++)
			for(int left = 1; left <= m; left ++)
				for(int right = left; right <= m; right ++)
					cout << "dp2 " << t << " " << up << " " << left << " " << right << " " << dp2[asd][up][left][right] << endl;
			*/
		//cout << dp1[asd][1][n][1] << " " << dp2[asd][1][1][2] << endl;
		if(dp1[asd][1][n][1] >= m)
		{
			cout << t << endl;
			return 0;
		}
		for(int up = 1; up <= n; up ++)
			for(int down = up; down <= n; down ++)
				for(int left = 1; left <= m; left ++)
				{
					int a = dp1[asd][up][down][left];
					int b = dp1[asd][up][down][left + a];
					dp1[asd ^ 1][up][down][left] = max(dp1[asd ^ 1][up][down][left], a + b);
					dp2[asd ^ 1][up][left][left + a + b - 1] = max(dp2[asd ^ 1][up][left][left + a + b - 1], down - up + 1);
				}
		for(int up = 1; up <= n; up ++)
			for(int left = 1; left <= m; left ++)
				for(int right = 1; right <= m; right ++)
				{
					int a = dp2[asd][up][left][right];
					int b = dp2[asd][up + a][left][right];
					dp2[asd ^ 1][up][left][right] = max(dp2[asd ^ 1][up][left][right], a + b);
					dp1[asd ^ 1][up][up + a + b - 1][left] = max(dp1[asd ^ 1][up][up + a + b - 1][left], right - left + 1);
				}
		asd ^= 1;
		for(int up = 1; up <= n; up ++)
			for(int down = up; down <= n; down ++)
				for(int left = 1; left <= m; left ++)
					dp1[asd][up][down][left] = max(dp1[asd][up][down][left], dp1[asd][up - 1][down][left]);
		for(int up = 1; up <= n; up ++)
			for(int left = 1; left <= m; left ++)
				for(int right = 1; right <= m; right ++)
					dp2[asd][up][left][right] = max(dp2[asd][up][left][right], dp2[asd][up][left - 1][right]);
		for(int up = 1; up <= n; up ++)
			for(int down = n; down >= up; down --)
				for(int left = 1; left <= m; left ++)
					dp1[asd][up][down][left] = max(dp1[asd][up][down][left], dp1[asd][up][down + 1][left]);
		for(int up = 1; up <= n; up ++)
			for(int left = 1; left <= m; left ++)
				for(int right = m; right >= left; right --)
					dp2[asd][up][left][right] = max(dp2[asd][up][left][right], dp2[asd][up][left][right + 1]);
	}
	return 0;
}
/*
3 4
..##
##.#
#...
*/
/*
3 2
..
##
#.
*/

Measured memory_bytes: 133120