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

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<stdlib.h>
#include<cassert>
#include<time.h>
#include<bitset>
using namespace std;
const long long mod=1000000007;
const long long inf=mod*mod;
const long long d2=(mod+1)/2;
const long double EPS=1e-9;
const long double PI=acos(-1.0);
int ABS(int a){return max(a,-a);}
long long ABS(long long a){return max(a,-a);}
long double ABS(long double a){return max(a,-a);}
int UF[200000];
int FIND(int a){
	if(UF[a]<0)return a;
	return UF[a]=FIND(UF[a]);
}
void UNION(int a,int b){
	a=FIND(a);b=FIND(b);if(a==b)return;UF[a]+=UF[b];UF[b]=a;
}
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
char in[410][410];
int W[210000];
int B[210000];
int main(){
	int a,b;scanf("%d%d",&a,&b);
	for(int i=0;i<200000;i++)UF[i]=-1;
	for(int i=0;i<a;i++){
		scanf("%s",in[i]);
	}
	for(int i=0;i<a;i++)for(int j=0;j<b;j++){
		for(int k=0;k<4;k++){
			int tx=i+dx[k];
			int ty=j+dy[k];
			if(tx<0||ty<0||tx>=a||ty>=b)continue;
			if(in[i][j]!=in[tx][ty])UNION(i*b+j,tx*b+ty);
		}
	}
	for(int i=0;i<a;i++){
		for(int j=0;j<b;j++){
			if(in[i][j]=='.'){
				W[FIND(i*b+j)]++;
			}else{
				B[FIND(i*b+j)]++;
			}
		}
	}
	long long ret=0;
	for(int i=0;i<210000;i++){
		ret+=(long long)W[i]*B[i];
	}
	printf("%lld\n",ret);
}