#include <bits/stdc++.h>
        #include<iostream>
        #include<cstdio>
        #include<vector>
        #include<queue>
        #include<map>
        #include<cstring>
        #include<string>
        #include <math.h>
        #include<algorithm>
    //    #include <boost/multiprecision/cpp_int.hpp>
        #include<functional>
      #define int long long
        #define inf  1000000007
        #define pa pair<int,int>
#define ll long long
        #define pal pair<ll,ll>
        #define ppa pair<int,pa>
        #define  mp make_pair
        #define EPS (1e-10)
        #define equals(a,b) (fabs((a)-(b))<EPS)

        using namespace std;

        class Point{
        	public:
        	double x,y;
        	Point(double x=0,double y=0):x(x),y(y) {}
        	Point operator + (Point p) {return Point(x+p.x,y+p.y);}
        	Point operator - (Point p) {return Point(x-p.x,y-p.y);}
        	Point operator * (double a) {return Point(x*a,y*a);}
        	Point operator / (double a) {return Point(x/a,y/a);}
        	double absv() {return sqrt(norm());}
        	double norm() {return x*x+y*y;}
        	bool operator < (const Point &p) const{
        		return x != p.x ? x<p.x: y<p.y;
        	}
        	bool operator == (const Point &p) const{
        		return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
        	}
        };
        typedef Point Vector;

        struct Segment{
        Point p1,p2;
        };

    double hen(Vector a){
    if(fabs(a.x)<EPS && a.y>0) return acos(0);
    else if(fabs(a.x)<EPS && a.y<0) return 3*acos(0);
    else if(fabs(a.y)<EPS && a.x<0) return 2*acos(0);
    else if(fabs(a.y)<EPS && a.x>0) return 0.0;
    else if(a.y>0) return acos(a.x/a.absv());
    else return 2*acos(0)+acos(-a.x/a.absv());

    }

        double dot(Vector a,Vector b){
        	return a.x*b.x+a.y*b.y;
        }
        double cross(Vector a,Vector b){
        	return a.x*b.y-a.y*b.x;
        }
        int dx[4] = {1, 0, -1, 0};
        int dy[4] = {0, 1, 0, -1};
        //----------------kokomade temple------------
int a[400][400]={0};

int dp[310][310];

int rui[310][310][310]={0};
signed main(){
string s;

	int h,w;
	cin>>h>>w;
//	if(w!=3) return 0;
	for(int i=1;i<=h;i++){
		cin>>s;
		for(int j=0;j<w;j++){
			a[i][j+1]=1+(s[j]-'a');
	//		cout<<a[i][j+1]<<" ";
		}
	//	cout<<endl;
	}
	
	
	for(int s=1;s<=w-1;s++){
	
	for(int i=h;i>=0;i--){
		int ii=i,jj=h;
		rui[s][ii][jj]=0;
		while(ii!=0){
			ii--;
			jj--;
			rui[s][ii][jj]=rui[s][ii+1][jj+1];
			if(a[h-ii][s]==a[h-jj][s+1])rui[s][ii][jj]++;
		//	cout<<h-ii+1<<" "<<h-jj+1<<endl;
		}
		
	}
	

	
	for(int j=h-1;j>=0;j--){
		int jj=j,ii=h;
		rui[s][ii][jj]=0;
		while(jj!=0){
			jj--,ii--;
			rui[s][ii][jj]=rui[s][ii+1][jj+1];
			if(a[h-ii][s]==a[h-jj][s+1] ) rui[s][ii][jj]++;
			
		}
		
		
	}
	}
	/*
	for(int i=0;i<=h;i++) for(int j=0;j<=h;j++){
		cout<<i<<" "<<j<<" "<<rui[i][j]<<endl;
	}
	for(int i=0;i<=h;i++) for(int j=0;j<=h;j++){
		cout<<i<<" "<<j<<" "<<rui2[i][j]<<endl;
	}
	*/
	int ans=0;
	for(int s=1;s<w;s++){
	for(int i=0;i<=304;i++)for(int j=0;j<=304;j++) dp[i][j]=inf;
	dp[0][0]=0;
	
	for(int i=0;i<=h;i++)for(int j=0;j<=h;j++) {
		if(i==0&& j==0) continue;
		
		if(i!=0){
			int u=0;
			/*
			for(int l=max(1ll,j-i+1);l<=h+1-i;l++){
				if(a[l][1]==a[l+(i-j)-1][2])u++;
			}
			*/
			u=rui[s][i-1][j];
			dp[i][j] =min(dp[i][j],u+dp[i-1][j]);
			
		}
		
		if(j!=0){
			int u=0;
	
			u=rui[s][i][j-1];
			
			dp[i][j] =min(dp[i][j],u+dp[i][j-1]);
			
		}
	//	cout<<i<<j<<k<<" "<<dp[i][j][k]<<endl;
	}
		ans += dp[h][h];
	}
	cout<<ans<<endl;
	
//	cout<<ans<<endl;
	return 0;
}

//printf("%.10f\n",ans);


Measured memory_bytes: 221056