#include <cstdint>
#include <cstdio>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cassert>
#include <stack>
#include <cstring>
#include <set>
#include <sstream>
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef long long Long;

int ID;
int MAT[310][310];
int mem[310][310];
int CH[310][310][310];
int dp(int i,int j,int N){
	if(i==N || j==N)return 0;
	if(mem[i][j] != -1)return mem[i][j];
	int p1 = dp(i+1,j,N);
	int p2 = dp(i,j+1,N);
	if(p1 <= p2){
		CH[i][j][ID] = 0;
	}else{
		CH[i][j][ID] = 1;
	}
	return mem[i][j] = MAT[i][j] + min(p1,p2);
}
int solve2(string A,string B){
	int N = A.size();
	for(int i = N-1; i >= 0; --i){
		for(int j = N-1; j >= 0; --j){
			int s = A[N-1-i] == B[N-1-j];
			if(i+1 < N && j+1 < N)
				s += MAT[i+1][j+1];
			MAT[i][j] = s;
		}
	}
	memset(mem,-1,sizeof(mem));
	int t = dp(0,0,N), t2 = 0;
//	cout << A << endl;
//	cout << B << endl;
//	{
//		int i = 0, j = 0;
//		while(i<N && j<N){
//			int c = CH[i][j][ID];
//			int a = MAT[i][j];
//			for(int k = 0; k < A.size(); ++k){
//				if(A[k] == ' ' || B[k] == ' ')continue;
//				t2 += A[k] == B[k];
//			}
//			if(c == 0){
//				A = " " + A.substr(0,A.size()-1);
//				i++;
//			}else{
//				B = " " + B.substr(0,B.size()-1);
//				j++;
//			}
//			cout << endl;
//			cout << a << endl;
//			cout << A << endl;
//			cout << B << endl;
//		}
//		cout << t << " " << t2 << endl;
//		cout <<string(20,'-')<< endl;
//	}
	return t;
}

int solve(string A, string B){
	cout << A << " " << B << endl;
	int H = A.size();
	int st = 0;
	int mi = 1000000000;
	for(int j = 0; j < H; ++j){
		int f = 0 , s = 0, nst = 0;
		for(int k = 0; k+j < H; ++k){
			if(A[k] == B[j+k]){
				nst++;
				f += (H-(k+j));
			}
		}
		for(int k = 0; k+j < H; ++k){
			if(j+k == 0)continue;
			if(A[k] == B[j+k-1]){
				s += (H-(k+j));
			}
		}
		mi = min(mi, st+f+s);
		cout << "\t" << (st+f+s) <<"\t" << st << " " << f << " " << s << endl;
		st += nst;
	}
	cout << "\t" << st << endl;
	mi = min(mi, st);
	cout << mi << endl;
	return mi;
}

int advance(vector<string> &V, int j){
	int s = 0;
	for(int i = V.size()-1; i >= 0; --i){
		if(j > 0 && V[i][j] != ' ')
			s += (V[i][j] == V[i][j-1]);
		if(j+1 < V[i].size() && V[i][j] != ' ')
			s += (V[i][j] == V[i][j+1]);
		if(i > 0)
			V[i][j] = V[i-1][j];
		else
			V[i][j] = ' ';
	}
	return s;
}

int main()
{
	int H,W;
	cin >> H >> W;
	vector<string> V(H);
	for (int i = 0; i < H; ++i) {
		cin >> V[i];
	}
	int s = 0;
	for (int i = 1; i < W; ++i) {
		string A,B;
		for (int j = 0; j < H; ++j) {
			A += V[j][i-1];
			B += V[j][i];
		}
		ID = i;
		s += solve2(A,B);
	}
//	VI I(W);
//	int AA = 0;
//	for(int i = 0; i < H*W; ++i){
//		int pc1 = -1;
//		int t = 0;
//		for(int j = 1; j < W; ++j){
//			if(I[j] == H && I[j-1] == H){
//				continue;
//			}
//			int c1 = -1;
//			if(I[j] == H){
//				c1 = 0;
//			}else if(I[j-1] == H){
//				c1 = 1;
//			}else{
//				c1 = CH[ I[j-1] ][ I[j] ][j];
//			}
//			if(c1 == 0 && pc1 == -1){
//				t = advance(V,0);
//				I[0]++;
//				break;
//			}else if(c1 == 1 && j == W-1){
//				t = advance(V,j);
//				I[j]++;
//				break;
//			}else if(pc1 == 1 && c1 == 0){
//				t = advance(V,j-1);
//				I[j-1]++;
//				break;
//			}
//			pc1 = c1;
//		}
//		cout << t << endl;
//		for (int j = 0; j < H; ++j) {
//			cout << V[j] << endl;
//		}
//		cout << endl;
//		AA += t;
//	}
	cout << s << endl;
	
	
}
/*
   ]
xcccccx
xcxxxcx





 */



Measured memory_bytes: 111360