#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=186,INF=1<<29;

short dp[16][MAX][MAX][MAX][2];

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int H,W;cin>>H>>W;
    vector<string> S(H);
    for(int i=0;i<H;i++){
        cin>>S[i];
    }
    
    for(int w=0;w<W;w++){
        for(int u=0;u<H;u++){
            int now=w;
            while(now<W&&S[u][now]==S[u][w]) now++;
            dp[0][w][u][u][0]=now-1;
        }
    }
    
    for(int w=0;w<W;w++){
        for(int u=0;u<H;u++){
            for(int d=u+1;d<H;d++){
                if(S[u][w]!=S[d][w]) dp[0][w][u][d][0]=w-1;
                else dp[0][w][u][d][0]=min(dp[0][w][u][d-1][0],dp[0][w][d][d][0]);
            }
        }
    }
    
    for(int h=0;h<H;h++){
        for(int l=0;l<W;l++){
            int now=h;
            while(now<H&&S[now][l]==S[h][l]) now++;
            dp[0][h][l][l][1]=now-1;
        }
    }
    
    for(int h=0;h<H;h++){
        for(int l=0;l<W;l++){
            for(int r=l+1;r<W;r++){
                if(S[h][l]!=S[h][r]) dp[0][h][l][r][1]=h-1;
                else dp[0][h][l][r][1]=min(dp[0][h][l][r-1][1],dp[0][h][r][r][1]);
            }
        }
    }
    
    for(int t=0;t<15;t++){
        
        for(int u=0;u<H;u++){
            for(int d=u;d<H;d++){
                int r1=0;
                for(int w=0;w<W;w++){
                    int can=dp[t][w][u][d][0];
                    if(can<W-1) dp[t+1][w][u][d][0]=dp[t][can+1][u][d][0];
                    else dp[t+1][w][u][d][0]=can;
                    
                    if(dp[t+1][w][u][d][0]>=0) chmax(dp[t+1][u][w][dp[t+1][w][u][d][0]][1],short(d));
                    
                    while(r1<W){
                        int can=dp[t][u][w][r1][1],to;
                        if(can<H-1) to=dp[t][can+1][w][r1][1];
                        else to=can;
                        
                        if(to>=d) r1++;
                        else break;
                    }
                    
                    chmax(dp[t+1][w][u][d][0],short(r1-1));
                    
                    chmax(r1,w+1);
                }
            }
        }
        
        ///
        
        for(int l=0;l<W;l++){
            for(int r=l;r<W;r++){
                int d1=0;
                for(int h=0;h<H;h++){
                    int can=dp[t][h][l][r][1];
                    if(can<H-1) dp[t+1][h][l][r][1]=dp[t][can+1][l][r][1];
                    else dp[t+1][h][l][r][1]=can;
                    
                    if(dp[t+1][h][l][r][1]>=0) chmax(dp[t+1][l][h][dp[t+1][h][l][r][1]][0],short(r));
                    
                    while(d1<H){
                        int can=dp[t][l][h][d1][0],to;
                        if(can<W-1) to=dp[t][can+1][h][d1][0];
                        else to=can;
                        
                        if(to>=r) d1++;
                        else break;
                    }
                    
                    chmax(dp[t+1][h][l][r][1],short(d1-1));
                    
                    chmax(d1,h+1);
                }
            }
        }
    }
    
    for(int t=0;t<=15;t++){
        if(dp[t][0][0][H-1][0]==W-1||dp[t][0][0][W-1][1]==H-1){
            cout<<t<<endl;
            return 0;
        }
    }
    
    cout<<16<<endl;
    
}




Measured memory_bytes: 402304