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 C (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>

int main(){
  int h,w;
  scanf("%d%d",&h,&w);
  char s[h][w+1];
  int i=0;
  for(i=0;i<h;i++){
    scanf("%s",s[i]);
  }
  int count[h][w];
  int j=0;
  for(i=0;i<w;i++){
    for(j=0;j<h;j++){
      count[j][i] = 0;
    }
  }
  int count_num = h * w;
  long long int ans = 0;
  for(i=0;i<h;i++){
    for(j=0;j<w;j++){
      if(count_num == 0){
        break;
      }
      if(count[i][j] == 0){
        //printf("(%d,%d) %c\n",i,j,s[i][j]);
        count[i][j] = 1;
        int tmp[h*w][2];
        int tmp_num = 1;
        tmp[0][0] = i;
        tmp[0][1] = j;
        int black = 0;
        int white = 0;
        if(s[i][j]=='#'){
          black++;
        }else{
          white++;
        }
        while(tmp_num > 0){
          tmp_num--;
          int tmp_i = tmp[tmp_num][0];
          int tmp_j = tmp[tmp_num][1];
          //printf("(%d %d) %c ",tmp_i,tmp_j,s[tmp_i][tmp_j]);
          if(tmp_i > 0 && count[tmp_i-1][tmp_j] == 0 && (s[tmp_i-1][tmp_j] != s[tmp_i][tmp_j])){
            if(s[tmp_i-1][tmp_j]=='#'){
              black++;
            }else{
              white++;
            }
            count[tmp_i-1][tmp_j] = 1;
            tmp[tmp_num][0] = tmp_i-1;
            tmp[tmp_num][1] = tmp_j;
            tmp_num++;
          }
          if(tmp_j > 0 && count[tmp_i][tmp_j-1] == 0 && (s[tmp_i][tmp_j-1] != s[tmp_i][tmp_j])){
            if(s[tmp_i][tmp_j-1]=='#'){
              black++;
            }else{
              white++;
            }
            count[tmp_i][tmp_j-1] = 1;
            tmp[tmp_num][0] = tmp_i;
            tmp[tmp_num][1] = tmp_j-1;
            tmp_num++;
          }
          if(tmp_i < h-1 && count[tmp_i+1][tmp_j] == 0 && (s[tmp_i+1][tmp_j] != s[tmp_i][tmp_j])){
            if(s[tmp_i+1][tmp_j]=='#'){
              black++;
            }else{
              white++;
            }
            count[tmp_i+1][tmp_j] = 1;
            tmp[tmp_num][0] = tmp_i+1;
            tmp[tmp_num][1] = tmp_j;
            tmp_num++;
          }
          if(tmp_j < w-1 && count[tmp_i][tmp_j+1] == 0 && (s[tmp_i][tmp_j+1] != s[tmp_i][tmp_j])){
            if(s[tmp_i][tmp_j+1]=='#'){
              black++;
            }else{
              white++;
            }
            count[tmp_i][tmp_j+1] = 1;
            tmp[tmp_num][0] = tmp_i;
            tmp[tmp_num][1] = tmp_j+1;
            tmp_num++;
          }
        }
        ans += (long long int) black * white;
        //printf("black %d white %d\n", black,white);
      }
    }
  }
  printf("%lld",ans);
  return 0;
}