#include <bits/stdc++.h>

#define reg register
#define pr std::pair<int, int>
#define fi first
#define se second
#define FIN(s) freopen(s, "r", stdin)
#define FOUT(s) freopen(s, "w", stdout)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define lep(i, l, r) for (int i = l; i < r; ++i)
#define irep(i, r, l) for (int i = r; i >= l; --i)
#define ilep(i, r, l) for (int i = r; i > l; --i)
#define Rep(i, n) rep(i, 1, n)
#define Lep(i, n) lep(i, 1, n)
#define IRep(i, n) irep(i, n, 1)
#define ILep(i, n) ilep(i, n, 1)
typedef long long ll;
typedef long double ld;

namespace modular {
    const int MOD = 1000000007;
    inline int add(int x, int y) { return (x += y) >= MOD ? x -= MOD : x; }
    inline void inc(int &x, int y) { (x += y) >= MOD ? x -= MOD : 0; }
    inline int mul(int x, int y) { return 1LL * x * y % MOD; }
    inline int qpow(int x, int y) {
        int ans = 1;
        for (; y; y >>= 1, x = mul(x, x))
            if (y & 1)
                ans = mul(ans, x);
        return ans;
    }
}; // namespace modular

namespace Base {
    template <typename Tp> inline Tp input() {
        Tp x = 0, y = 1;
        char c = getchar();
        while ((c < '0' || '9' < c) && c != EOF) {
            if (c == '-')
                y = -1;
            c = getchar();
        }
        if (c == EOF)
            return 0;
        while ('0' <= c && c <= '9')
            x = x * 10 + c - '0', c = getchar();
        return x *= y;
    }
    template <typename Tp> inline void read(Tp &x) { x = input<Tp>(); }
    template <typename Tp> inline void chmax(Tp &x, Tp y) { x < y ? x = y : 0; }
    template <typename Tp> inline void chmin(Tp &x, Tp y) { x > y ? x = y : 0; }
}; // namespace Base
using namespace Base;
/*----------------------------------------------------------------------------*/

#define MAX_N 227

int N, M;
int mp[MAX_N][MAX_N];
char s[MAX_N];
int f[2][MAX_N][MAX_N][MAX_N];
int cnt[MAX_N][MAX_N];

inline bool check(int i, int l, int r) {
    int tmp = cnt[i][r] - cnt[i][l - 1];
    return !tmp || (tmp == r - l + 1);
}

void solve() {
    Rep(l, M) {
        rep(r, l, M) {
            f[0][1][l][r] = check(1, l, r);
            int &cur = f[0][1][l][r];
            while (cur < N && check(cur + 1, l, r) && mp[cur + 1][l] == mp[cur][l]) cur++;
            rep(i, 2, N) {
                int &cur = f[0][i][l][r];
                if (check(i, l, r)) {
                    cur = std::max(i, f[0][i - 1][l][r]);
                    while (cur < N && check(cur + 1, l, r) && mp[cur + 1][l] == mp[cur][l]) cur++;
                } else cur = 0;
            }
        }
    }
    int k = 0, p = 0, q = 1;
    while (f[p][1][1][M] < N) {
        k++;
        Rep(i, N) {
            Rep(l, M) {
                int pos = l;
                rep(r, l, M) {
                    int &cur = f[q][i][l][r];
                    cur = f[p][i][l][r];
                    chmax(cur, f[p][f[p][i][l][r] + 1][l][r]);
                    while (pos < r - 1 && 
                            std::min(f[p][i][l][pos], f[p][i][pos + 1][r]) <=
                            std::min(f[p][i][l][pos + 1], f[p][i][pos + 2][r])) 
                        pos++;
                    if (pos < r) chmax(cur, std::min(f[p][i][l][pos], f[p][i][pos + 1][r]));
                }
            }
        }
        std::swap(p, q);
        // printf("--------------------%d-------------------\n", k);
        // Rep(i, N) {
        //     Rep(l, M) rep(r, l, M) printf("i%d l%d r%d %d\n", i, l, r, f[p][i][l][r]);
        // }
    }
    printf("%d\n", k);
}

int main() {
    read(N), read(M);
    Rep(i, N) {
        scanf("%s", s + 1);
        Rep(j, M) mp[i][j] = (s[j] == '#');
    }
    Rep(i, N) {
        Rep(j, M) cnt[i][j] = cnt[i][j - 1] + mp[i][j];
    }
    solve();
    return 0;
}


Measured memory_bytes: 77696