#include<bits/stdc++.h>
#define MST(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define rep(i,a,b) for(int i = a ; i < b ; ++i)
#define per(i,a,b) for(int i = a ; i > b ; --i)
#define ALL(v) v.begin(),v.end()
#define ft first
#define sd second
using namespace std;

typedef long long LL;
typedef pair<int,int> pii;
template<class T> void show(T *x,int len,int s = 0) {for(int i = s ; i < s+len-1 ; ++i) cout << x[i] << ' ';cout << x[s+len-1] << endl;}
void debug() {cout << endl;}
template <typename T, typename... Args> void debug(T x,Args... args) {cout << x << ' ';debug(args...);}

namespace fast_IO{
    const int maxbuff = 1<<17;
    char ibuff[maxbuff],obuff[maxbuff];
    inline char Getchar(){
        static char *p1=ibuff,*p2=ibuff;
        if(p1 == p2) {
            p1 = ibuff;
            p2 = ibuff+fread(ibuff,1,maxbuff,stdin);
            if(p1 == p2) return -1;
        }
        return *p1++;
    }

    int optr = 0;
    inline void Putchar(char c) {
        if(optr == maxbuff) {fwrite(obuff,1,optr,stdout);optr = 0;}
        obuff[optr++] = c;
    }

    inline void Flush() {
        fwrite(obuff,1,optr,stdout);
    }

    template<class T>
    inline int read(T &x) {
        x = 0;
        char c = Getchar();
        if(c == EOF) return -1;
        for( ; (c < '0' || c > '9') && c != EOF ; c = Getchar());
        if(c == EOF) return -1;
        for( ; c >= '0' && c <= '9' ; c = Getchar()) x = x*10+c-'0';
        return 0;
    }

    template<class T>
    inline void write(const T &x,int tag = 0) {
        if(!x) {
            if(!tag) Putchar(x+'0');
            return ;
        }
        write(x/10,1);
        Putchar(x%10+'0');
    }

    template<class T>
    inline void writeln(const T &x) {
        write(x);Putchar('\n');
    }

    template<class T>
    inline void writesp(const T &x) {
        write(x);Putchar(' ');
    }
}
template<class T>
inline void cmin(T &A,const T &B) {A = (A<B?A:B);}
template<class T>
inline void cmax(T &A,const T &B) {A = (A>B?A:B);}

const int N = 185+19;
int D;
int f[2][N][N][N],g[2][N][N][N],sum[N][N],n,m,mp[N][N],ans;

namespace solution{

    void show(int w) {
        int t = w & 1;
        debug("f");
            for (int i = 1; i <= n; ++i)
                for (int j = i ; j <= n ; ++j)
                    for(int k = 1 ; k <= m ; ++k)
                        debug(i,j,k,w,f[t][i][j][k]);
        debug();
        debug('g');
            for (int i = 1; i <= m; ++i)
                for (int j = i ; j <= m ; ++j)
                    for(int k = 1 ; k <= n ; ++k)
                        debug(i,j,k,w,g[t][i][j][k]);
        debug();
    }

    void init() {
        for(int i = 1 ; i <= n ; ++i)
            for(int j = 1 ; j <= m ; ++j)
                sum[i][j] = mp[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    }

    bool same_color(int x1,int y1,int x2,int y2) {
        int num = sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
        return !num || num == (x2-x1+1)*(y2-y1+1);
    }

    void calc0() {
        for(int i = 1 ; i <= n ; ++i)
            for(int j = i ; j <= n ; ++j)
                for(int k = 1 ; k <= m ; ++k) {
                    int l = k-1 , r = m+1;
                    for(int mid = l+r>>1 ; l < r-1 ; mid = l+r>>1)
                        if ( same_color(i,k,j,mid) )
                            l = mid;
                        else
                            r = mid;
                    f[0][i][j][k] = l;

                    //if(same_color(i,k,j,l)) {cout << "OK" << i << ' ' << j << ' ' << k << ' ' << l << endl;}
                    //else cerr << i << ' ' << j << ' ' << k << ' ' << l << endl;
                }
        for(int i = 1 ; i <= m ; ++i)
            for(int j = i ; j <= m ; ++j)
                for(int k = 1 ; k <= n ; ++k) {
                    int l = k-1 , r = n+1;
                    for(int mid = l+r>>1 ; l < r-1 ; mid = l+r>>1)
                        if ( same_color(k,i,mid,j) )
                            l = mid;
                        else
                            r = mid;
                    g[0][i][j][k] = l;

                    //if(same_color(k,i,l,j)) {cout << "OK" << i << ' ' << j << ' ' << k << ' ' << l << endl;}
                    //else cerr << i << ' ' << j << ' ' << k << ' ' << l << endl;
                }
        //show(0);

    }

    void calc_row(int &val,int i,int j,int k,int w) {
        int l = k-1 , r = m+1;
        for(int mid = l+r >> 1 ; l < r-1 ; mid = l+r>>1) {
            int p = g[w^1][k][mid][i];
            if(p >= j) {
                l = mid;
                continue;
            }
            p = g[w^1][k][mid][p+1];
            if(p >= j) {
                l = mid;
                continue;
            }
            r = mid;
        }
        val = max(val,l);
    }

    void calc_col(int &val,int i,int j,int k,int w) {
        int l = k-1 , r = n+1;
        for(int mid = l+r >> 1 ; l < r-1 ; mid = l+r>>1) {
            int p = f[w^1][k][mid][i];
            if(p >= j) {
                l = mid;
                continue;
            }
            p = f[w^1][k][mid][p+1];
            if(p >= j) {
                l = mid;
                continue;
            }
            r = mid;
        }
        val = max(val,l);
    }

    void calc() {
        for(int w = 1 ; w < D ; ++w) {
            int t = w & 1;
            MST(f[t], 0);
            for (int i = 1; i <= n; ++i)
                for (int j = i; j <= n; ++j) {
                    int pos = 0;
                    for (int k = 1; k <= m; ++k) {
                        pos = max(pos,k-1);
                        int p = f[t ^ 1][i][j][k];
                        if (p == m) {
                            f[t][i][j][k] = m;
                            continue;
                        }
                        p = f[t^1][i][j][p+1];
                        f[t][i][j][k] = max(f[t][i][j][k],p);
                        int c = pos+1;
                        while(1) {
                            if(c == m+1) break;
                            int pp = g[t^1][k][c][i];
                            if(pp >= j) {
                                ++c;
                                continue;
                            }
                            pp = g[t^1][k][c][pp+1];
                            if(pp >= j) {
                                ++c;
                                continue;
                            }
                            break;
                        }
                        pos = c-1;
                        f[t][i][j][k] = max(f[t][i][j][k],pos);

                    }
                }

            for(int i = 1 ; i <= m ; ++i)
                for (int j = i; j <= m; ++j) {
                    int pos = 0;
                    for (int k = 1; k <= n; ++k) {
                        pos = max(pos,k-1);
                        int p = g[t ^ 1][i][j][k];
                        if (p == n) {
                            g[t][i][j][k] = n;
                            continue;
                        }
                        p = g[t^1][i][j][p+1];
                        g[t][i][j][k] = max(g[t][i][j][k],p);
                        int c = pos+1;
                        while(1) {
                            if(c == n+1) break;
                            int pp = f[t^1][k][c][i];
                            if(pp >= j) {
                                ++c;
                                continue;
                            }
                            pp = f[t^1][k][c][pp+1];
                            if(pp >= j) {
                                ++c;
                                continue;
                            }
                            break;
                        }
                        pos = c-1;
                        g[t][i][j][k] = max(g[t][i][j][k],pos);

                    }
                }
            //show(w);
            if(f[t][1][n][1] == m || g[t][1][m][1] == n) {
                ans = w;
                return ;
            }

        }
    }

}


int main() {
#ifdef LOCAL
    freopen("input","r",stdin);
	freopen("output","w",stdout);
#endif
//	srand((int)time(0));
//	cout << 185 << ' ' << 185 << endl;
//	for(int i = 1 ; i <= 185 ; ++i) {
//        for (int j = 1; j <= 185; ++j)
//            cout << (rand() % 2 ? '.' : '#');
//        cout << endl;
//    }
//	return 0;
    cin >> n >> m;

    D = log(n*m)/log(2) + 2.5;
    for(int i = 1 ; i <= n ; ++i) {
        string s;
        cin >> s;
        for(int j = 0 ; j < m ; ++j)
            if(s[j] == '.')
                mp[i][j+1] = 0;
            else
                mp[i][j+1] = 1;
    }

    solution::init();
    solution::calc0();
    if(f[0][1][n][1] == m || g[0][1][m][1] == n) {
        cout << 0 << endl;
        return 0;
    }
    solution::calc();
    cout << ans << endl;
    //solution::show();
    return 0;
}


Measured memory_bytes: 131072