#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mit map<int,int>::iterator
#define sit set<int>::iterator
#define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
#define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
#define ltype int
#define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
#define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
#define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
#define pii pair<int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
#define fastio ios::sync_with_stdio(false)
const int inf=0x3f3f3f3f,mod=1000000007;
const double pi=3.1415926535897932,eps=1e-6;
int h,w;char g[190][190];int dp[190][190][190][18],lim,pre[190][190];
int query(int l,int r,int d,int u){
    return pre[u][r]-pre[d-1][r]-pre[u][l-1]+pre[d-1][l-1];
}
int dfs(int i,int l,int r,int k){
    int &res=dp[i][l][r][k];
    if(res!=-1) return res;
    int aa=query(l,r,i,h);
    if(aa==0||aa==(r-l+1)*(h-i+1)) return res=0;
    res=max(res,dfs(dfs(i,l,r,k-1)+1,l,r,k-1));
    int dl=l,dr=r-1;
    while(dl<dr){
        int mid=(dl+dr)>>1;
        if(dfs(i,l,mid,k)<dfs(i,mid+1,r,k)) l=mid+1;
        else r=mid;
    }
    res=max(res,min(dp[i][l][dl][k],dp[i][dl+1][r][k]));
    if(dl!=l) res=max(res,min(dp[i][l][dl-1][k],dp[i][dl][r][k]));
    return res;
}
int logg(int x){
    int res=0;
    while(x) res++,x>>=1;
    return res;
}
int main()
{
    //freopen("data.in","r",stdin);
	//freopen("ans1.out","w",stdout);
    scanf("%d%d",&h,&w);
    rep(i,1,h) scanf("%s",g[i]+1);
    lim=logg(h-1)+logg(w-1);
    rep(i,1,h) rep(j,1,w) rep(k,1,h) rep(m,0,lim) dp[i][j][k][m]=-1;
    rep(i,1,h) rep(j,1,w) pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+(g[i][j]=='#');
    per(i,h,1) rep(k,0,lim)
    rep(len,1,w)
    rep(l,1,w){
        int r=l+len-1;if(r>w) break;
        int &res=dp[i][l][r][k];
        //if(res!=-1) continue;
        res=i-1;
        int dl=i,dr=h;
        while(dl<dr){
            int mid=(dl+dr+1)>>1;
            int x=query(l,r,i,mid);
            if((x==0)||(x==(r-l+1)*(mid-i+1))) dl=mid;
            else dr=mid-1;
        }
        int x=query(l,r,i,i);
        if(!(x==0||x==r-l+1)) dl=i-1;
        res=dl;
        if(k) {
            //printf("%d %d %d %d is going\n",i,l,r,k);
            int nxt=dp[i][l][r][k-1]+1;if(nxt>h) res=h;
            else res=max(res,dp[nxt][l][r][k-1]);
            //rap(w,l,r) printf("%d %d\n",dp[i][l][w][k-1],dp[i][w+1][r][k-1]);
            int dl=l,dr=r-1;
            while(dl<dr){
                int mid=(dl+dr)>>1;
                if(dp[i][l][mid][k-1]>dp[i][mid+1][r][k-1]) dl=mid+1;
                else dr=mid;
            }
            //printf("%d\n",dl);
            if(dl>l) res=max(res,min(dp[i][l][dl-1][k-1],dp[i][dl][r][k-1]));
            if(dl<r) res=max(res,min(dp[i][l][dl+1][k-1],dp[i][dl+2][r][k-1]));
            res=max(res,min(dp[i][l][dl][k-1],dp[i][dl+1][r][k-1]));
            //printf("! %d %d",dp[i][l][dl][k-1],dp[i][dl+1][r][k-1]);
            //if(dl>l) printf(" %d %d",dp[i][l][dl-1][k-1],dp[i][dl][r][k-1]);
            //putchar('\n');
        }
    }
    rep(i,0,lim) if(dp[1][1][w][i]==h) {
        printf("%d\n",i);
        return 0;
    }
    return 0;
}

Measured memory_bytes: 471424