import std.stdio;
import std.conv, std.array, std.algorithm, std.string;
import std.math, std.random, std.range, std.datetime;
import std.bigint;

void main(){
	int h, w;
	{
		int[] tmp = readln.chomp.split.map!(to!int).array;
		h = tmp[0], w = tmp[1];
		}
	char[][] css;
	for(int i = 0; i < h; i ++){
		css ~= readln.chomp.to!(char[]);
		}
	debug css.writeln;
	
	ulong ans = 0;
	for(int k = 0; k < w - 1; k ++){
		
		int[][] friction;
		// friction[i][j]はa[0..i]とb[0..j]で右揃えにしたとき一致してる個数
		// friction[i][j] = friction[i-1][j-1] + (a[i]==b[i]? 1: 0)
		for(int i = 0; i <= h; i ++){
			friction ~= [0];
			friction[i].length = h + 1;
			}
		friction[0].fill(0);
		for(int i = 1; i <= h; i ++){
			friction[i][0] = 0;
			for(int j = 1; j <= h; j ++){
				friction[i][j] = friction[i - 1][j - 1]
						+ ((css[i - 1][k] == css[j - 1][k + 1])? 1: 0);
				debug write(css[i - 1][k], " ", css[j - 1][k+1], " ");
				debug friction.writeln;
				}
			}
		debug friction.writeln;
		
		int[][] xs;
		for(int i = 0; i <= h; i ++){
			xs ~= [0];
			xs[i].length = h + 1;
			}
		xs[0].fill(0);
		
		for(int i = 1; i <= h; i ++){
			xs[i][0] = 0;
			for(int j = 1; j <= h; j ++){
				xs[i][j] = min(xs[i][j - 1], xs[i - 1][j]) + friction[i][j];
				debug xs.writeln;
				}
			}
		debug xs.writeln;
		
		ans += xs[h][h];
		
		}
	
	ans.writeln;
	
	}


/*


隣接する2列だけで考えればよい
それの総和

*/