#undef NDEBUG
#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()

using li = long long;
using ld = long double;

void solve(bool);

int main() {
#ifdef YA
    auto s = clock();
    assert(freopen("input.txt", "r", stdin));
#else
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#endif

    cout << fixed << setprecision(20);

    solve(true);

#ifdef YA1
    while (true) solve(false);
#endif

#ifdef YA
    cout << endl << endl << "time = " << (clock() - s) / (double)CLOCKS_PER_SEC << endl;
#endif

    return 0;
}

const int maxn = 189;
const int maxval = 19;

int n, m;
short dh[maxn][maxn][maxn][maxval], dv[maxn][maxn][maxn][maxval];
bool a[maxn][maxn];

void init() {
    int mx = maxn;
    for (int i = 0; i < mx; ++i) {
        for (int j = 0; j < mx; ++j) {
            for (int k = 0; k < mx; ++k) {
                for (int v = 0; v < maxval; ++v) {
                    dh[i][j][k][v] = i - 1;
                }
            }
        }
    }
    for (int i = 0; i < mx; ++i) {
        for (int j = 0; j < mx; ++j) {
            for (int k = 0; k < mx; ++k) {
                for (int v = 0; v < maxval; ++v) {
                    dv[i][j][k][v] = i - 1;
                }
            }
        }
    }

    for (int l = m - 1; l >= 0; --l) {
        for (int d = 0; d < n; ++d) {
            for (int u = d; u < n; ++u) {
                if (d == u) {
                    if (l + 1 < m && a[d][l] == a[d][l + 1])
                        dh[l][d][u][0] = dh[l + 1][d][u][0];
                    else
                        dh[l][d][u][0] = l;
                    continue;
                }
                if (dh[l][d][u - 1][0] == l - 1 || a[u][l] != a[u - 1][l]) {
                    dh[l][d][u][0] = l - 1;
                    continue;
                }
                if (l + 1 < m && a[d][l] == a[d][l + 1])
                    dh[l][d][u][0] = dh[l + 1][d][u][0];
                else
                    dh[l][d][u][0] = l;
            }
        }
    }

    for (int l = n - 1; l >= 0; --l) {
        for (int d = 0; d < m; ++d) {
            for (int u = d; u < m; ++u) {
                if (d == u) {
                    if (l + 1 < n && a[l][d] == a[l + 1][d])
                        dv[l][d][u][0] = dv[l + 1][d][u][0];
                    else
                        dv[l][d][u][0] = l;
                    continue;
                }
                if (dv[l][d][u - 1][0] == l - 1 || a[l][u] != a[l][u - 1]) {
                    dv[l][d][u][0] = l - 1;
                    continue;
                }
                if (l + 1 < n && a[l][d] == a[l + 1][d])
                    dv[l][d][u][0] = dv[l + 1][d][u][0];
                else
                    dv[l][d][u][0] = l;
            }
        }
    }
}

void solve(bool __attribute__((unused)) read) {
    // srand(time(0));
    // read = false;
    if (read) {
        cin >> n >> m;
    } else {
        n = m = 185;
    }
    for (int i = 0; i < n; ++i) {
        string s;
        if (read) {
            cin >> s;
        } else {
            s = "";
            for (int j = 0; j < m; ++j) {
                if (rand() & 1)
                    s += '#';
                else
                    s += '.';
            }
        }
        // cout << s << endl;
        for (int j = 0; j < m; ++j) {
            a[i][j] = (s[j] == '#');
        }
    }
    init();

    for (int v = 1; v < maxval; ++v) {
        for (int l = m - 1; l >= 0; --l) {
            for (int d = 0; d < n; ++d) {
                for (int u = d; u < n; ++u) {
                    dh[l][d][u][v] = max(dh[l][d][u][v], dh[l][d][u][v - 1]);
                    if (dh[l][d][u][v - 1] == m - 1 || dh[l][d][u][v - 1] == l - 1)
                        continue;
                    int l1 = dh[l][d][u][v - 1] + 1;
                    dh[l][d][u][v] = max(dh[l1][d][u][v - 1], dh[l][d][u][v]);

                    dv[d][l][dh[l][d][u][v]][v] = max(u, (int)dv[d][l][dh[l][d][u][v]][v]);
                }
            }
        }

        for (int l = n - 1; l >= 0; --l) {
            for (int d = 0; d < m; ++d) {
                for (int u = d; u < m; ++u) {
                    dv[l][d][u][v] = max(dv[l][d][u][v], dv[l][d][u][v - 1]);

                    dv[l][d][u][v] = max(dv[l][d][u][v], dv[l][d][u + 1][v]);
                    if (l > 0)
                        dv[l][d][u][v] = max(dv[l][d][u][v], dv[l - 1][d][u][v]);
                    if (d > 0)
                        dv[l][d][u][v] = max(dv[l][d][u][v], dv[l][d - 1][u][v]);

                    if (dv[l][d][u][v - 1] == n - 1 || dv[l][d][u][v - 1] == l - 1)
                        continue;
                    int l1 = dv[l][d][u][v - 1] + 1;
                    dv[l][d][u][v] = max(dv[l1][d][u][v - 1], dv[l][d][u][v]);


                    dh[d][l][dv[l][d][u][v]][v] = max(u, (int)dh[d][l][dv[l][d][u][v]][v]);
                }
            }
        }

        for (int l = m - 1; l >= 0; --l) {
            for (int d = 0; d < n; ++d) {
                for (int u = n - 1; u >= d; --u) {
                    dh[l][d][u][v] = max(dh[l][d][u][v], dh[l][d][u + 1][v]);
                    if (l > 0)
                        dh[l][d][u][v] = max(dh[l][d][u][v], dh[l - 1][d][u][v]);
                    if (d > 0)
                        dh[l][d][u][v] = max(dh[l][d][u][v], dh[l][d - 1][u][v]);
                }
            }
        }



        for (int l = n - 1; l >= 0; --l) {
            for (int d = 0; d < m; ++d) {
                for (int u = m - 1; u >= d; --u) {

                    dv[l][d][u][v] = max(dv[l][d][u][v], dv[l][d][u + 1][v]);
                    if (l > 0)
                        dv[l][d][u][v] = max(dv[l][d][u][v], dv[l - 1][d][u][v]);
                    if (d > 0)
                        dv[l][d][u][v] = max(dv[l][d][u][v], dv[l][d - 1][u][v]);
                }
            }
        }

    }

/*
    cout << dh[1][0][2][1] << endl;
    for (int v = 0; v < maxval; ++v) {
        cout << v << " = " << dv[0][1][1][v] << endl; 
    }
    cout << endl;
*/

    for (int v = 0; v < maxval; ++v) {
        // cout << "val = " << v << " " << dh[0][0][n - 1][v] << endl;
        if (dh[0][0][n - 1][v] == m - 1) {
            cout << v << "\n";
            return;
        }
    }



    // cout << "FUCK" << endl;
    assert(false);
}

Measured memory_bytes: 501376