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 <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#include <string>

#define REP(i,n) for(auto i=0;i<n;++i)
#define REPR(i,n) for(auto i=n;i>=0;--i)
#define REPI(itr,v) for(auto itr=v.begin();itr!=v.end();++itr)
#define REPIR(itr,v) for(auto itr=v.rbegin();itr!=v.rend();++itr)
#define FOR(i,a,b) for(auto i=a;i<b;++i)
#define SORT(v,n) sort(v, v+n)
#define SORTV(v) sort(v.begin(), v.end())
#define ALL(v) v.begin(),v.end()
#define llong long long
#define ll long long
#define INF 999999999
#define MOD 1000000007
#define pb push_back
#define pf push_front
#define MP make_pair
#define SV(n,v) {int tmp;for(int i=0;i<n;++i){scanf("%d",&tmp);v.push_back(tmp);}}

int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};

using namespace std;

#define MAX 160000

typedef pair<int,int> pii;

int par1[MAX], rank1[MAX];
void init(int par[], int V){
  for(int i = 0; i < V; ++i)
    par[i] = i;
}

int find(int x, int par[]){
  if(par[x] == x){
    return x;
  }else{
    return par[x] = find(par[x], par);
  }
}

void unite(int x, int y, int par[], int rank[]){
  x = find(x, par);
  y = find(y, par);

  if(x == y)
    return;

  if(rank[x] > rank[y]){
    par[y] = x;
  }else{
    par[x] = y;
    if(rank[x] == rank[y])
      rank[y]++;
  }
}

int same(int x, int y, int par[]){
  return find(x, par) == find(y, par);
}

int main(){

  llong h, w;
  cin >> h >> w;

  string s[400];
  REP(i,h){
    cin >> s[i];
  }

  init(par1, h*w);

  REP(i,h){
    REP(j,w){
      REP(k,4){
        if(i + dy[k] >= 0 && i + dy[k] < h && j + dx[k] >= 0 && j + dx[k] < w){
          if((s[i][j] == '.' && s[i+dy[k]][j+dx[k]] == '#') || (s[i][j] == '#' && s[i+dy[k]][j+dx[k]] == '.')){
            unite(i*w+j, (i+dy[k])*w+(j+dx[k]), par1, rank1);

          }
        }
      }
    }
  }
  REP(i,h){
    REP(j,w){
      for(int ii = i; ii < h; ++ii){
        for(int jj=j; jj < w; ++jj){
          same(i*w+j, ii*w+jj, par1);
        }
      }
    }
  }


  map<int, pair<int, int>> mp;
  REP(i,h){
    REP(j,w){
      int key = par1[i*w+j];
      /*
      if(mp.find(key) == mp.end()){
        cout << key << endl;
        mp[key] = MP(0, 0);
        if(s[i][j] == '.'){
          mp[key].first++;
        }else{
          mp[key].second++;
        }
      }else{
      */
        if(s[i][j] == '.'){
          mp[key].first++;
        }else{
          mp[key].second++;
        }
    }
  }

  llong ans = 0;
  REPI(itr, mp){
    ans += itr->second.first * itr->second.second;
  }

  cout << ans << endl;
  return 0;
}