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: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CF2016C_C2
{
    class Program
    {
        static int H, W;
        static int Min = int.MaxValue;

        static void Main(string[] args)
        {
            var t = scan;

            H = t[0]; W = t[1];
            var C = new char[H, W];
            for (int i = 0; i < H; i++)
            {
                var k = Console.ReadLine();
                for (int j = 0; j < W; j++)
                {
                    C[i, j] = k[j];
                }
            }
            dfs(C, 0);
            Console.WriteLine(Min);
        }
        static void dfs(char[,] C, int cost)
        {
            if (C[H - 1, 0] == 'J' || (C[H - 1, 1] == 'J' && C[H - 1, 2] == 'J'))
            {
                Min = Math.Min(Min, cost);
                return;
            }
            if (C[H - 1, 1] != 'J') mode1(C, cost);
            if (C[H - 1, 0] != 'J') mode2(C, cost);
            if (C[H - 1, 2] != 'J') mode3(C, cost);

        }
        static void mode1(char[,] C, int cost)
        {

            for (int i = 0; i < H; i++)
            {
                if (C[i, 1] == 'J') continue;
                if (C[i, 1] == C[i, 0])
                {
                    cost++;
                }
                if (C[i, 1] == C[i, 2])
                {
                    cost++;
                }
            }
            for (int i = H - 1; i >= 1; i--)
            {
                C[i, 1] = C[i - 1, 1];
            }
            C[0, 1] = 'J';
            dfs(C, cost);
        }
        static void mode2(char[,] C, int cost)
        {
            for (int i = 0; i < H; i++)
            {
                if (C[i, 0] == 'J') continue;
                if (C[i, 1] == C[i, 0])
                {
                    cost++;
                }

            }
            for (int i = H - 1; i >= 1; i--)
            {
                C[i, 0] = C[i - 1, 0];
            }
            C[0, 0] = 'J';
            dfs(C, cost);
        }
        static void mode3(char[,] C, int cost)
        {
            for (int i = 0; i < H; i++)
            {
                if (C[i, 2] == 'J') continue;
                if (C[i, 1] == C[i, 2])
                {
                    cost++;
                }

            }
            for (int i = H - 1; i >= 1; i--)
            {
                C[i, 2] = C[i - 1, 2];
            }
            C[0, 2] = 'J';
            dfs(C, cost);
        }

        static int[] scan { get { return Array.ConvertAll(Console.ReadLine().Split(), int.Parse); } }

    }

      
}