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: Time Limit Exceeded)

#include "bits/stdc++.h"
 
using namespace std;
typedef long long int ll;
typedef pair<ll, ll > pi;  
typedef pair<pair<ll, ll >, ll > pii;  
typedef pair<pair<ll, ll >, char > piic;  
vector<ll > vec;
vector<vector<ll > > vec2;
ll MOD = 1000000007;
ll INF = 1145141919454519;
 
ll N, M;
 
ll dx[4] = {1, -1, 0, 0};
ll dy[4] = {0,  0, 1,-1};
 
vector<string > G;

//黒で始まって白で終わる組を探す
//なお黒->白->黒みたいに交互にマス目をまたがないと駄目
//黒1->白1->黒2->の途中で通った黒2は黒1と同じような場所に行けるっぽい
//ので答えが同じになる

//黒毎に答えを管理する
map<pi, ll> ans;

void bfs(ll y, ll x){
    //準備
    vector<vector<ll > > dist(N, vector<ll >(M, -1));
    queue<pii> que;
    //初期化
    dist[y][x] = 0;
    que.push(make_pair(make_pair(y, x), '#'));
    //途中に発見した黒座標の管理
    vector<pi > B;
    B.push_back(make_pair(y, x));

    ll cn = 0;
    while(!que.empty()){
        ll from_y = que.front().first.first;
        ll from_x = que.front().first.second;
        ll color = que.front().second;
        que.pop();
 
        for(ll i = 0; i < 4; i++){
            if(from_y + dy[i] >= 0 && from_y + dy[i] < N && from_x + dx[i] >= 0 && from_x + dx[i] < M){
                ll to_y = from_y + dy[i];
                ll to_x = from_x + dx[i];
                //もう訪れている時
                if(dist[to_y][to_x] != -1) continue;
                //黒->黒 白->白のとき
                if(color == G[to_y][to_x]) continue;
 
                dist[to_y][to_x] = dist[from_y][from_x] + 1;
                que.push(make_pair(make_pair(to_y, to_x), G[to_y][to_x]));
                if(G[to_y][to_x] == '.'){
                    cn++;
                }else{
                    B.push_back(make_pair(to_y, to_x));
                }
            }
        }
    }

    //更新
    for(ll i = 0; i < B.size(); i++){
        ans[B[i]] = cn;
    }
}
 
int main() {
 
    cin >> N >> M;
 
    for(ll row = 0; row < N; row++){
        string s;
        cin >> s;
        G.push_back(s);
    }
 
    ll mx = -1;
    for(ll row = 0; row < N; row++){
        for(ll col = 0; col < M; col++){
            if(G[row][col] == '.' || ans[make_pair(row, col)] > 0) continue;
            //cout << row << " " << col << endl;
            bfs(row, col);
        }
    }
 
    //集計
    ll sum = 0;

    auto begin = ans.begin(), end = ans.end();
    for (auto iter = begin; iter != end; iter++) {
        sum += iter -> second;
    }
 
    cout << sum << endl;
 
}