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# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public void Proc() {

        Reader.IsDebug = false;
        int[] inpt = Reader.ReadLine().Split(' ').Select(a=>int.Parse(a)).ToArray();

        int rowCount = inpt[0];
        int colCount = inpt[1];

        int[] osds = new int[colCount];

        for(int i=0; i<rowCount; i++) {
            string str = Reader.ReadLine();
            for(int j=0; j<colCount; j++) {
                if(i==0) {
                    OrgMap.Add(new char[rowCount]);
                }
                OrgMap[j][i] = str[j];
            }
        }
        long ans = this.GetAns(this.OrgMap, osds);
        Console.WriteLine(ans);
    }

    private Dictionary<string, long> dic = new Dictionary<string, long>();

    private long GetAns(List<char[]> map, int[] osds) {
        string key = string.Join("#", osds);
        if(dic.ContainsKey(key)) {
            return dic[key];
        }

        long ans = long.MaxValue;

        if(osds.Sum() >= map.Count * map[0].Length) {
            return 0;
        }

        for(int i=0; i<map.Count; i++) {
            if(osds[i] >= map[i].Length) {
                continue;
            }
            int cost = 0;
            for(int j=0; j<map[i].Length; j++) {
                if(j<osds[i]) {
                    continue;
                }
                if(i>0 && osds[i-1] <= j) {
                    if(map[i][j - osds[i]] == map[i-1][j-osds[i-1]]) {
                        cost++;
                    }
                }
                if(i<map.Count-1 && osds[i+1] <= j) {
                    if(map[i][j - osds[i]] == map[i+1][j-osds[i+1]]) {
                        cost++;
                    }
                }
            }
            int[] subOsds = osds.Select(a=>a).ToArray();
            subOsds[i]++;
            long ret = this.GetAns(map, subOsds);
            if(ret >= 0) {
                ans = Math.Min(ans, ret + cost);
            } 
        }
        if(ans == long.MaxValue) {
            ans = -1;
        }
        this.dic[key] = ans;
        return ans;
    }

    private List<char[]> OrgMap = new List<char[]>();

    


    


    public class Reader {
        public static bool IsDebug = true;
        private static System.IO.StringReader SReader;
        private static string InitText = @"


5 5
aaaaa
abbba
ababa
abbba
aaaaa




";
        public static string ReadLine() {
            if(IsDebug) {
                if(SReader == null) {
                    SReader = new System.IO.StringReader(InitText.Trim());
                }
                return SReader.ReadLine();
            } else {
                return Console.ReadLine();
            }
        }
    }
    public static void Main(string[] args)
    {
        Program prg = new Program();
        prg.Proc();
    }
}