#include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <iomanip>
#include <numeric>
#include <tuple>
#include <bitset>
#include <complex>
#include <unistd.h>
#include <cassert>
#include <cctype>
#include <random>
#include <time.h>
#define _USE_MATH_DEFINES
#define _GLIBCXX_DEBUG
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> plglg;
typedef pair<double, ll> pdlg;
typedef tuple<int, int, int> tiii;
typedef tuple<ll, ll, ll> tlglglg;
typedef tuple<double, double, double> tddd;
typedef complex<double> xy_t;
typedef vector<ll> vll;
typedef vector< vector<ll> > matrix;
#define REP(i, x, y) for(ll i = (ll)x; i < (ll)y; i++)
#define DREP(i, x, y, d) for(ll i = (ll)x; i < (ll)y; i += (ll)d)
#define PER(i, x, y) for(ll i = (ll)x; i > (ll)y; i--)
#define DPER(i, x, y, d) for(ll i = (ll)x; i > (ll)y; i -= (ll)d)
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
double pi = 3.141592653589793;
ll mod = 1000000007;
int intmax = 2147483647;
int intmin = -2147483648;
ll llmax = 9223372036854775807;
ll llmin = -9223372036854775807;
int iinf = intmax / 8;
ll inf = llmax / 8;
double eps = 1e-12;

bool bo[200][200];

short dpw[17][186][186][186];
short dph[17][186][186][186];

short max(short a, short b) {
    if (a < b) {
        return b;
    } else {
        return a;
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    short H, W;
    cin >> H >> W;
    REP(i, 0, H) {
        string s;
        cin >> s;
        REP(j, 0, W) {
            if (s[j] == '#') {
                bo[i][j] = true;
            } else {
                bo[i][j] = false;
            }
        }
    }
    // REP(i, 0, 17) {
    //     REP(j, 0, 200) {
    //         REP(k, 0, 200) {
    //             fishort(dpw[i][j][k], dpw[i][j][k] + 200, -1);
    //             fishort(dph[i][j][k], dph[i][j][k] + 200, -1);
    //         }
    //     }
    // }
    REP(i, 0, H) {
        bool base = !bo[i][0];
        REP(j, 0, W) {
            bool now = bo[i][j];
            if (now == base) {
                dpw[0][i][i + 1][j] = dpw[0][i][i + 1][j - 1] - 1;
            } else {
                short tmp = 1;
                REP(k, j + 1, W) {
                    if (bo[i][k] != now) {
                        break;
                    }
                    tmp++;
                }
                dpw[0][i][i + 1][j] = tmp;
                base = now;
            }
        }
    }
    REP(i, 1, H) {
        REP(j, 0, H - i) {
            REP(k, 0, W) {
                if (bo[j][k] == bo[j + i][k]) {
                    short num = min(dpw[0][j][j + i][k], dpw[0][j + i][j + i + 1][k]);
                    dpw[0][j][j + i + 1][k] = num;
                } else {
                    dpw[0][j][j + i + 1][k] = 0;
                }
            }
        }
    }
    REP(i, 0, W) {
        bool base = !bo[0][i];
        REP(j, 0, H) {
            bool now = bo[j][i];
            if (now == base) {
                dph[0][i][i + 1][j] = dph[0][i][i + 1][j - 1] - 1;
            } else {
                short tmp = 1;
                REP(k, j + 1, H) {
                    if (bo[k][i] != now) {
                        break;
                    }
                    tmp++;
                }
                dph[0][i][i + 1][j] = tmp;
                base = now;
            }
        }
    }
    REP(i, 1, W) {
        REP(j, 0, W - i) {
            REP(k, 0, H) {
                if (bo[k][j] == bo[k][j + i]) {
                    short num = min(dph[0][j][j + i][k], dph[0][j + i][j + i + 1][k]);
                    dph[0][j][j + i + 1][k] = num;
                } else {
                    dph[0][j][j + i + 1][k] = 0;
                }
            }
        }
    }
    REP(i, 0, 16) {
        REP(j, 0, H) {
            REP(k, 0, W) {
                REP(l, k + 1, W + 1) {
                    short x = dph[i][k][l][j];
                    dph[i + 1][k][l][j] = max(dph[i + 1][k][l][j], x + dph[i][k][l][j + x]);
                    dpw[i + 1][j][j + dph[i + 1][k][l][j]][k]
                        = max(dpw[i + 1][j][j + dph[i + 1][k][l][j]][k], (short)(l - k));
                }
                REP(l, j + 1, H + 1) {
                    short x = dpw[i][j][l][k];
                    dpw[i + 1][j][l][k] = max(dpw[i + 1][j][l][k], x + dpw[i][j][l][k + x]);
                    dph[i + 1][k][k + dpw[i + 1][j][l][k]][j]
                        = max(dph[i + 1][k][k + dpw[i + 1][j][l][k]][j], (short)(l - j));
                }
            }
        }
        REP(j, 0, H) {
            PER(len, W, 0) {
                REP(k, 0, W - len + 1) {
                    short l = k + len;
                    if (k > 0) {
                        dph[i + 1][k][l][j] = max(dph[i + 1][k][l][j], dph[i + 1][k - 1][l][j]);
                    }
                    if (l < W) {
                        dph[i + 1][k][l][j] = max(dph[i + 1][k][l][j], dph[i + 1][k][l + 1][j]);
                    }
                }
            }
        }
        REP(j, 0, W) {
            PER(len, H, 0) {
                REP(k, 0, H - len + 1) {
                    short l = k + len;
                    if (k > 0) {
                        dpw[i + 1][k][l][j] = max(dpw[i + 1][k][l][j], dpw[i + 1][k - 1][l][j]);
                    }
                    if (l < W) {
                        dpw[i + 1][k][l][j] = max(dpw[i + 1][k][l][j], dpw[i + 1][k][l + 1][j]);
                    }
                }
            }
        }
    }
    REP(i, 0, 17) {
        if (dph[i][0][W][0] == H) {
            cout << i << endl;
            return 0;
        }
    }
}


Measured memory_bytes: 426496