#include <bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define ford(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)

using namespace std;

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn = 190, K = 20;
int a[maxn][maxn], s[maxn][maxn];
int h, w;
int H[2][maxn][maxn][maxn], V[2][maxn][maxn][maxn];

struct TQ {
    deque<pii> q;
    int l, r;

    TQ()
        : q()
        , l(0)
        , r(0)
    {
    }

    void push(int x) {
        pii p = {x, r++};
        while (!q.empty() && q.back().fi < p.fi) q.pop_back();
        q.pb(p);
    }

    void pop() {
        if (!q.empty() && q.front().se == l) q.pop_front();
        ++l;
    }

    int get_max() {
        if (q.empty()) {
            assert(l >= r);
            return -1e9;
        }
        return q.front().fi;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.precision(10);
    cout << fixed;
#ifdef LOCAL_DEFINE
    freopen("input.txt", "rt", stdin);
#endif

    cin >> h >> w;
    forn(i, h) forn(j, w) {
        char c;
        cin >> c;
        a[i][j] = int(c == '#');
        s[i + 1][j + 1] = a[i][j];
    }

    forn(i, h) forn(j, w + 1) s[i + 1][j] += s[i][j];
    forn(i, h + 1) forn(j, w) s[i][j + 1] += s[i][j];

    forn(i2, h + 1) forn(i1, i2) forn(j, w + 1) V[0][i1][i2][j] = j;
    forn(j2, w + 1) forn(j1, j2) forn(i, h + 1) H[0][j1][j2][i] = i;

    forn(i2, h + 1) forn(i1, i2) forn(j1, w + 1) fore(j2, j1 + 1, w) {
        int S = s[i2][j2] - s[i1][j2] - s[i2][j1] + s[i1][j1];
        if (S != 0 && S != (i2 - i1) * (j2 - j1)) break;
        uax(V[0][i1][i2][j1], j2);
        uax(H[0][j1][j2][i1], i2);
    }

    int ans = 0;
    while (V[0][0][h][0] < w) {
//        cerr << V[0][0][h][0] << '\n';
        ++ans;
        forn(i2, h + 1) forn(i1, i2) forn(j, w + 1) V[1][i1][i2][j] = V[0][i1][i2][j];
        forn(j2, w + 1) forn(j1, j2) forn(i, h + 1) H[1][j1][j2][i] = H[0][j1][j2][i];
        forn(i2, h + 1) forn(i1, i2) {
            TQ q;
            int r = 0;
            forn(l, w + 1) {
                while (r <= V[0][i1][i2][l]) q.push(V[0][i1][i2][r++]);
                V[1][i1][i2][l] = q.get_max();
                q.pop();
            }
        }

        forn(j2, w + 1) forn(j1, j2) {
            TQ q;
            int r = 0;
            forn(l, h + 1) {
                while (r <= H[0][j1][j2][l]) q.push(H[0][j1][j2][r++]);
                H[1][j1][j2][l] = q.get_max();
                q.pop();
            }
        }

        bool ch = true;
        while (ch) {
            ch = false;
            forn(i2, h + 1) forn(i1, i2) forn(j, w + 1) {
                fore(m, V[0][i1][i2][j] + 1, V[1][i1][i2][j]) ch |= uax(H[1][j][m][i1], i2);
                V[0][i1][i2][j] = V[1][i1][i2][j];
            }
            forn(j2, w + 1) forn(j1, j2) forn(i, h + 1) {
                fore(m, H[0][j1][j2][i] + 1, H[1][j1][j2][i]) ch |= uax(V[1][i][m][j1], j2);
                H[0][j1][j2][i] = H[1][j1][j2][i];
            }
        }
    }

    cout << ans << '\n';

#ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
    return 0;
}


Measured memory_bytes: 107008