Problem:
Score : 800 points

Problem Statement

Mr. Takahashi has in his room an art object with H rows and W columns, made up of H \times W blocks.
Each block has a color represented by a lowercase English letter (a-z).
The color of the block at the i-th row and j-th column is c_{i,j}.

Mr. Takahashi would like to dismantle the object, finding it a bit kitschy for his tastes.
The dismantling is processed by repeating the following operation:

Choose one of the W columns and push down that column one row.
The block at the bottom of that column disappears.

Each time the operation is performed, a cost is incurred.
Since blocks of the same color have a property to draw each other together, the cost of the operation is the number of the pairs of blocks (p, q) such that:

The block p is in the selected column.

The two blocks p and q are horizontally adjacent (before pushing down the column).

The two blocks p and q have the same color.

Mr. Takahashi dismantles the object by repeating the operation H \times W times to get rid of all the blocks.
Compute the minimum total cost to dismantle the object.

Constraints

1 ≤ H ≤ 300

2 ≤ W ≤ 300

All characters c_{i,j} are lowercase English letters (a-z).

Partial Score

In test cases worth 300 points, W = 3.

Input

The input is given from Standard Input in the following format:

H W
c_{1,1}c_{1,2}..c_{1,W}
c_{2,1}c_{2,2}..c_{2,W}
:
c_{H,1}c_{H,2}..c_{H,W}

Output

Print the minimum total cost to dismantle the object.

Sample Input 1

2 3
rrr
brg

Sample Output 1

2

For example, the total cost of 2 can be achieved by performing the operation as follows and this is the minimum value.

Sample Input 2

6 3
xya
xya
ayz
ayz
xaz
xaz

Sample Output 2

0

The total cost of 0 can be achieved by first pushing down all blocks of the middle column, then all of the left column, and all of the right column.

Sample Input 3

4 2
ay
xa
xy
ay

Sample Output 3

0

The total cost of 0 can be achieved by the following operations:

pushing down the right column one row;

pushing down the left column one row;

pushing down all of the right column;

and pushing down all of the left column.

Sample Input 4

5 5
aaaaa
abbba
ababa
abbba
aaaaa

Sample Output 4

24

Sample Input 5

7 10
xxxxxxxxxx
ccccxxffff
cxxcxxfxxx
cxxxxxffff
cxxcxxfxxx
ccccxxfxxx
xxxxxxxxxx

Sample Output 5

130

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <limits.h>
#include <math.h>
#include <functional>
#include <bitset>

#define repeat(i,n) for (long long i = 0; (i) < (n); ++ (i))
#define debug(x) cerr << #x << ": " << x << '\n'
#define debugArray(x,n) for(long long i = 0; (i) < (n); ++ (i)) cerr << #x << "[" << i << "]: " << x[i] << '\n'
#define debugArrayP(x,n) for(long long i = 0; (i) < (n); ++ (i)) cerr << #x << "[" << i << "]: " << x[i].first<< " " << x[i].second << '\n'

using namespace std;

typedef long long ll;
typedef pair<int,int> Pii;
typedef vector<int> vint;
typedef vector<ll> vll;
const ll INF = LLONG_MAX/10;
const ll MOD = 1e9+7;

int main(){
  int H,W;cin>>H>>W;
  vector<string> c(W,string(H,'?'));
  repeat(i,H){
    repeat(j,W){
      cin >> c[j][H-1-i];
    }
  }
  ll ans = 0;
  repeat(i,W-1){
    vector<vll> dp(H+2,vll(H+2,INF));
    dp[0][0]=0;
    vector<vll> cost(H+1,vll(H+1,0));
    repeat(dif,H+1){
      repeat(j,H-dif){
        cost[0][dif] += c[i][j]==c[i+1][j+dif];
      }
      repeat(k,H-dif){
        cost[k+1][k+1+dif] = cost[k][k+dif]-(c[i][k]==c[i+1][k+dif]);
      }
    }
    //debugArray(cost[0],H+1);
    repeat(dif,H+1){
      if(dif==0)continue;
      repeat(j,H-dif){
        cost[dif][0] += c[i][j+dif]==c[i+1][j];
      }
      repeat(k,H-dif){
        cost[k+1+dif][k+1] = cost[k+dif][k]-(c[i][k+dif]==c[i+1][k]);
      }
    }
    repeat(j,H+1){
      repeat(k,H+1){
        dp[j+1][k] = min(dp[j+1][k],dp[j][k]+cost[j][k]);
        dp[j][k+1] = min(dp[j][k+1],dp[j][k]+cost[j][k]);
      }
    }
    ans += dp[H][H];
    //sdebug(ans);
  }
  cout << ans << endl;
  return 0;
}