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 LuaJIT (2.0.4) (judge verdict: Accepted)

local ior = io.input()
local h, w = ior:read("*n", "*n", "*l")

local function getindex(i_h, i_w)
  return i_w + (i_h - 1) * w
end

local function createMap()
  local str = ""
  local map = {}
  for i_h = 1, h do
    str = ior:read()
    for i_w = 1, w do
      map[getindex(i_h, i_w)] = (str:sub(i_w, i_w) == "#")
    end
  end
  return map
end

local function uf_initialize(n)
  local parent = {}
  for i = 1, n do parent[i] = i end
  return parent
end

local function uf_findroot(idx, parent)
  while parent[idx] ~= idx do
    idx = parent[idx]
  end
  return idx
end

local map = createMap()
local parent = uf_initialize(h * w)

local function walk(src, dst)
  if map[src] ~= map[dst] then
    local sr, dr = uf_findroot(src, parent), uf_findroot(dst, parent)
    parent[src], parent[dst] = sr, dr
    if sr ~= dr then
      parent[dst], parent[dr] = sr, sr
    end
  end
end

for idx = 1, h * w do
  if w < idx then walk(idx, idx - w) end
  if idx <= (h - 1) * w then walk(idx, idx + w) end
  if 1 < w then
    if idx % w ~= 0 then walk(idx, idx + 1) end
    if idx % w ~= 1 then walk(idx, idx - 1) end
  end
end
local groups = {}
for idx = 1, h * w do
  local r = uf_findroot(idx, parent)
  if not groups[r] then
    local tmp = {0, 0}
    groups[r] = tmp
  end
  if map[idx] then
    groups[r][1] = groups[r][1] + 1
  else
    groups[r][2] = groups[r][2] + 1
  end
end
local ret = 0
for k, v in pairs(groups) do
  ret = ret + v[1] * v[2]
end
print(ret)