#pragma GCC optimize("Ofast")
#pragma GCC target("avx")
//#undef LOCAL
#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

template<class T, class U> void chmin(T& t, const U& u) { if (t > u) t = u; }
template<class T, class U> void chmax(T& t, const U& u) { if (t < u) t = u; }

#ifdef LOCAL
#define show(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif

template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "P(" << p.first << ", " << p.second << ")";
}

template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[";
    for (auto d : v) os << d << ", ";
    return os << "]";
}

const int MN = 190; //20; // 190;
bool g[MN + 2][MN + 2];
int dpw[MN + 2][MN + 2][MN + 2];
int dph[MN + 2][MN + 2][MN + 2];

int ndpw[MN + 2][MN + 2][MN + 2];
int ndph[MN + 2][MN + 2][MN + 2];

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);

    int h, w;
    cin >> h >> w;
    for (int i = 0; i < h; i++) {
        string s;
        cin >> s;
        for (int j = 0; j < w; j++) {
            g[i][j] = (s[j] == '#');
        }
    }

    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            for (int k = j + 1; k <= MN; k++) {
                dpw[i][j][k] = dph[i][j][k] = i;
            }
        }
    }
    for (int i = MN - 2; i >= 0; i--) {
        for (int j = 0; j < MN; j++) {
            for (int k = j + 1; k <= MN; k++) {
                bool fw = true, fh = true;
                for (int l = j; l < k - 1; l++) {
                    if (g[l][i] != g[l + 1][i]) {
                        fw = false;
                        break;
                    }
                }
                for (int l = j; l < k - 1; l++) {
                    if (g[i][l] != g[i][l + 1]) {
                        fh = false;
                        break;
                    }
                }
                if (!fw) dpw[i][j][k] = i;
                else if (g[j][i] != g[j][i + 1]) {
                    dpw[i][j][k] = i + 1;
                } else {
                    dpw[i][j][k] = dpw[i + 1][j][k];
                }

                if (!fh) dph[i][j][k] = i;
                else if (g[i][j] != g[i + 1][j]) {
                    dph[i][j][k] = i + 1;
                } else {
                    dph[i][j][k] = dph[i + 1][j][k];
                }
            }
        }
    }

    for (int ph = 0;; ph++) {
        /*cout << ph << endl;
        for (int i = 0; i <= w; i++) {
            for (int j = 0; j < h; j++) {
                for (int k = 0; k <= h; k++) {
                    cout << dpw[i][j][k] << " ";
                }
                cout << endl;
            }
            cout << "#" << endl;
        }
        cout << "###" << endl;
        for (int i = 0; i <= h; i++) {
            for (int j = 0; j < w; j++) {
                for (int k = 0; k <= w; k++) {
                    cout << dph[i][j][k] << " ";
                }
                cout << endl;
            }
            cout << "#" << endl;
        }
        cout << "!!!!!!!!###" << endl;*/


        if (dpw[0][0][h] >= w) {
            cout << ph << endl;
            break;
        }

        for (int i = 0; i < MN; i++) {
            for (int j = 0; j < MN; j++) {
                for (int k = j + 1; k < MN; k++) {
                    ndpw[i][j][k] = dpw[i][j][k];
                    ndph[i][j][k] = dph[i][j][k];
                }
            }
        }

        for (int i = 0; i < MN; i++) {
            for (int j = 0; j < MN; j++) {
                for (int k = j + 1; k < MN; k++) {
                    int nxw = dpw[dpw[i][j][k]][j][k];
                    int nxh = dph[dph[i][j][k]][j][k];
                    chmax(ndpw[i][j][k], nxw);
                    chmax(ndph[i][j][k], nxh);

                    chmax(ndph[j][i][nxw], k);
                    chmax(ndpw[j][i][nxh], k);
                }
            }
        }


        for (int i = 0; i <= MN; i++) {
            for (int j = 0; j < MN; j++) {
                for (int k = j + 1; k <= MN; k++) {
                    dpw[i][j][k] = ndpw[i][j][k];
                    dph[i][j][k] = ndph[i][j][k];
                }
            }
        }

        for (int i = 0; i <= MN; i++) {
            for (int j = 0; j < MN; j++) {
                for (int k = MN; k >= j + 1; k--) {
                    chmax(dpw[i + 1][j][k], dpw[i][j][k]);
                    chmax(dph[i + 1][j][k], dph[i][j][k]);
                    if (j + 1 < k) {
                        chmax(dpw[i][j + 1][k], dpw[i][j][k]);
                        chmax(dph[i][j + 1][k], dph[i][j][k]);
                        chmax(dpw[i][j][k - 1], dpw[i][j][k]);
                        chmax(dph[i][j][k - 1], dph[i][j][k]);
                    }
                }
            }
        }
    }
    return 0;
}



Measured memory_bytes: 110848