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)

#define _CRT_SECURE_NO_DEPRECATE
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <memory.h>
#include <set>
#include <ctime>
#include <map>
#include <cstring>
#include <iterator>
#include <queue>
#include <assert.h>
#include <bitset>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <functional>

//#pragma comment(linker, "/STACK:512000000")

using namespace std;

#define pb emplace_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define forn(i, n) for (int i = 0; i < (n); ++i)
#define forab(i, a, b) for (int i = (a); i < (b); ++i)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int infi = 1e9 + 7;
const ll infl = (ll)1e18 + (ll)7;

int ar[1010][1010];
int used[1010][1010];
int n, m;
int check(int i, int j, int c) {
    return i >= 0 && i < n && j >= 0 && j < m && ar[i][j] == c;
}
void operator += (pii &a, pii b) {
    a.first += b.first, a.second += b.second;
}
pii dfs(int i, int j) {
    if (used[i][j])
        return { 0, 0 };
    used[i][j] = 1;
    pii ans = { 0, 0 };
    if (ar[i][j])
        ans.first = 1;
    else
        ans.second = 1;
    int c = ar[i][j] ^ 1;
    if (check(i - 1, j, c))
        ans += dfs(i - 1, j);
    if (check(i + 1, j, c))
        ans += dfs(i + 1, j);
    if (check(i, j - 1, c))
        ans += dfs(i, j - 1);
    if (check(i, j + 1, c))
        ans += dfs(i, j + 1);
    return ans;
}

int32_t main() {
    cin.sync_with_stdio(false);
    cin.tie(0);
    //srand(time(NULL));
    //freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    //freopen("customs.in", "r", stdin); freopen("customs.out", "w", stdout);
    cin >> n >> m;
    forn(i, n) {
        forn(j, m) {
            char c;
            cin >> c;
            ar[i][j] = (c == '#');
        }
    }
    ll ans = 0;
    forn(i, n) {
        forn(j, m) {
            pii a = dfs(i, j);
            ans += 1LL * a.first * a.second;
        }
    }
    cout << ans;


    return 0;
}