Problem:
Score : 300 points

Problem Statement

There is a grid with H rows and W columns, where each square is painted black or white.

You are given H strings S_1, S_2, ..., S_H, each of length W.
If the square at the i-th row from the top and the j-th column from the left is painted black, the j-th character in the string S_i is #; if that square is painted white, the j-th character in the string S_i is ..

Find the number of pairs of a black square c_1 and a white square c_2 that satisfy the following condition:

There is a path from the square c_1 to the square c_2 where we repeatedly move to a vertically or horizontally adjacent square through an alternating sequence of black and white squares: black, white, black, white...

Constraints

1 \leq H, W \leq 400

|S_i| = W (1 \leq i \leq H)

For each i (1 \leq i \leq H), the string S_i consists of characters # and ..

Input

Input is given from Standard Input in the following format:

H W
S_1
S_2
:
S_H

Output

Print the answer.

Sample Input 1

3 3
.#.
..#
#..

Sample Output 1

10

Some of the pairs satisfying the condition are ((1, 2), (3, 3)) and ((3, 1), (3, 2)), where (i, j) denotes the square at the i-th row from the top and the j-th column from the left.

Sample Input 2

2 4
....
....

Sample Output 2

0

Sample Input 3

4 3
###
###
...
###

Sample Output 3

6

Solution in JavaScript (node.js v5.12) (judge verdict: Time Limit Exceeded)

function Main(input) {
  input = input.split("\n");
  var H = parseInt(input[0].split(" ")[0]);
  var W = parseInt(input[0].split(" ")[1]);
  S = new Array(H);
  for(var i=0;i<H;i++){
    S[i]=input[i+1].split("");
  }
  var ans=0;
  queue=new Array();
  list=new Array();
  for(var i=0;i<H;i++){
    for(var j=0;j<W;j++){
      if(S[i][j]=="#"){
        if(i<H-1){
        queue.push([i+1,j,S[i][j]]);
        }
        if(j<W-1){
        queue.push([i,j+1,S[i][j]]);
        }
        if(i>0){
        queue.push([i-1,j,S[i][j]]);
        }
        if(j>0){
          queue.push([i,j-1,S[i][j]]);
        }
      }
      while(queue.length!=0){
        if(S[queue[0][0]][queue[0][1]]!=queue[0][2]){
          var flag=0;
          for(var k=0;k<list.length;k++){
            if(list[k][0]==queue[0][0]&&list[k][1]==queue[0][1]){
              flag=1;
            }
          }
          if(flag==0){
            if(queue[0][2]=="#"){
            ans++;
            }
            if(queue[0][0]<H-1){
              queue.push([queue[0][0]+1,queue[0][1],S[queue[0][0]][queue[0][1]]]);
            }
            if(queue[0][1]<W-1){
              queue.push([queue[0][0],queue[0][1]+1,S[queue[0][0]][queue[0][1]]]);
            }
            if(queue[0][0]>0){
              queue.push([queue[0][0]-1,queue[0][1],S[queue[0][0]][queue[0][1]]]);
            }
            if(queue[0][1]>0){
              queue.push([queue[0][0],queue[0][1]-1,S[queue[0][0]][queue[0][1]]]);
            }
          }
          list.push([queue[0][0],queue[0][1]]);

        }
        queue.shift();
      }
      list=new Array();
    }
  }


  console.log('%s', ans);
}
  
// "実行する"ボタンを押した時に実行される関数 (デバッグ用)
function debug(){
  var input = document.getElementById("input").value;
  Main(input);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));