/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author izban
 */

#include <iostream>
#include <fstream>

#include <bits/stdc++.h>

using namespace std;


using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double dbl;

#ifdef HOME
#define db(x) { cerr << #x << " = " << x << endl; }
#define db2(x, y) { cerr << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")" << endl; }
#define db3(x, y, z) { cerr << "(" << #x << ", " << #y << ", " << #z << ") = (" << x << ", " << y << ", " << z << ")" << endl; }
#define dbv(a) { cerr << #a << " = "; for (auto xxx: a) cerr << xxx  << " "; cerr << endl; }
#else
#define db(x) ;
#define db3(x, y, z) ;
#define db2(x, y) ;
#define dbv(a) ;
#endif

#define sz(a)  (int)(a).size()
#define all(a) (a).begin(),a.end()
#define pw(x)  (1LL << (x))


const int N = 187;
const int LG = 18;

//typedef int mint;

const int INF = 1000;
short dpR[LG][N][N][N];
short dpD[LG][N][N][N];


class D {
public:
    int fast(vector<vector<int>> a) {
//        cerr << sizeof(dpR) + sizeof(dpD) << endl;
        int n = a.size();
        int m = a[0].size();

        vector<vector<int>> s(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i - 1][j - 1];
            }
        }

        auto ok = [&](int u, int d, int l, int r) {
            int cnt = s[d + 1][r + 1] - s[u][r + 1] - s[d + 1][l] + s[u][l];
            return cnt == 0 || cnt == (d - u + 1) * (r - l + 1);
        };

//        memset(dpR, 255, sizeof(dpR));
//        memset(dpD, 255, sizeof(dpD));
        for (int val = 0; val < LG; val++) {
            for (int u = 0; u < n; u++) {
                for (int l = 0; l < m; l++) {
                    for (int d = u; d < n; d++) {
                        int L = l - 1, R = m;
                        while (R - L > 1) {
                            int M = (L + R) >> 1;

                            bool good = 0;
                            if (val == 0) {
                                good = ok(u, d, l, M);
                            } else {
                                {
                                    int cov1 = dpR[val - 1][u][l][d];
                                    if (cov1 < m - 1) cov1 = dpR[val - 1][u][cov1 + 1][d];
                                    good |= cov1 >= M;
                                }
                                {
                                    int cov1 = dpD[val - 1][u][l][M];
                                    if (cov1 < n - 1) cov1 = dpD[val - 1][cov1 + 1][l][M];
                                    good |= cov1 >= d;
                                }
                            }
                            if (good) L = M;
                            else R = M;
                        }
                        dpR[val][u][l][d] = L;
                    }

                    for (int r = l; r < m; r++) {
                        int L = u - 1, R = n;
                        while (R - L > 1) {
                            int M = (L + R) >> 1;

                            bool good = 0;
                            if (val == 0) {
                                good = ok(u, M, l, r);
                            } else {
                                {
                                    int cov1 = dpD[val - 1][u][l][r];
                                    if (cov1 < n - 1) cov1 = dpD[val - 1][cov1 + 1][l][r];
                                    good |= cov1 >= M;
                                }
                                {
                                    int cov1 = dpR[val - 1][u][l][M];
                                    if (cov1 < m - 1) cov1 = dpR[val - 1][u][cov1 + 1][M];
                                    good |= cov1 >= r;
                                }
                            }
                            if (good) L = M;
                            else R = M;
                        }
                        dpD[val][u][l][r] = L;
                    }
                }
            }
        }
        int ans = 0;
        while (dpR[ans][0][0][n - 1] < m - 1) {
            ans++;
        }
        return ans;
    }

    void test() {
        int n = 185, m = 185;
        vector<vector<int>> a(n, vector<int>(m));
        for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = rand() % 2;
        cout << fast(a) << endl;
        cerr << clock() / (double) CLOCKS_PER_SEC << endl;
        exit(0);
    }

    void solve(std::istream &in, std::ostream &out) {
//        test();
        ios_base::sync_with_stdio(0);
        in.tie(0);

        int n, m;
        in >> n >> m;
        vector<string> s(n);
        for (int i = 0; i < n; i++) in >> s[i];

        vector<vector<int>> a(n, vector<int>(m));
        for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = s[i][j] == '#';

        out << fast(a) << endl;
    }
};


int main() {
    D solver;
    std::istream &in(std::cin);
    std::ostream &out(std::cout);
    solver.solve(in, out);
    return 0;
}


Measured memory_bytes: 460416