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 Python (3.4.3) (judge verdict: Accepted)

#!/mnt/c/Users/moiki/bash/env/bin/python
H,W      = list(map(int, input().split()))
S        =  [ list(input()) for _ in range(H)]

import sys
sys.setrecursionlimit(2600000)

united_count = [ ]
# [ (黒1個、白2個) ,... k 個] 

directions = [(1,0), (0,1), (-1,0), (0,-1)] # y,x の順番


def dfs(pos, c, now_k):
    # pos : (1,2)
    # 引数は現在の連結成分の番号
    # 座標と、現在の1,0 が渡される
    # 渡されたnow_kで塗りつぶす
    y,x = pos
    for d in directions:
        try:
            if y+d[0] < 0 or x+d[1] < 0:
                continue
            content = S[y+d[0]][x+d[1]] 

            if c != content and (content == "#" or content == ".") :
                S[y+d[0]][x+d[1]] = now_k
                inplace_tuple     = united_count[now_k]
                united_count[now_k]     = ( inplace_tuple[0] + 1, inplace_tuple[1]) if content == "#" else \
                                    ( inplace_tuple[0]    , inplace_tuple[1]+1) # タプルなので新しく作る

                dfs( (y+d[0], x+d[1]),  content,  now_k)  # DFSかける

            else:
                continue
        except:
            continue



now_k = 0
for y in range(H):
    for x in range(W):
        c = S[y][x]  
        if c == "#" or c == "." :
            united_count.append( (1,0) if  c == "#" else (0,1) ) # now_k番目
            S[y][x] = now_k  # cの値は黒だったら、1 を入れてdfsに投げる

            pos = (y,x)
            dfs(pos, c, now_k)
            now_k         += 1

        else:
            continue # もう数字が入っている場合は、パス


answer = 0
for uni in united_count:
    answer = ((uni[0]*uni[1]) + answer) 

print(answer)