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 Rust (1.15.1) (judge verdict: Accepted)

#[test]
fn test_solve() {
    assert_eq!(solve("3 3\n.#.\n..#\n#..\n"), "10\n");
    assert_eq!(solve("2 4\n....\n....\n"), "0\n");
    assert_eq!(solve("4 3\n###\n###\n...\n###\n"), "6\n");
    assert_eq!(solve("3 3 ### ### ###"), "0\n");
    assert_eq!(solve("3 3 #.# .#. #.#"), "20\n");
    assert_eq!(solve("3 3 ### #.# ###"), "4\n");
}
fn solve(s: &str) -> String {
    let mut sc = Scanner::from_str(s);

    let h: usize = sc.read();
    let w: usize = sc.read();
    let g: Vec<Vec<_>> = (0..h).map(|_| sc.get().chars().collect()).collect();

    let mut seen = vec![vec![false; w]; h];
    let mut ret: u64 = 0;
    for i in 0..h {
        for j in 0..w {
            if !seen[i][j] {
                seen[i][j] = true;
                let mut sa = 0;
                let mut sb = 0;
                let mut q = vec![(i, j)];
                while let Some((i, j)) = q.pop() {
                    let c = g[i][j];
                    if c == '#' {
                        sa += 1;
                    } else {
                        sb += 1;
                    }
                    let mut chk = |i: usize, j: usize| {
                        if !seen[i][j] && g[i][j] != c {
                            seen[i][j] = true;
                            q.push((i, j))
                        }
                    };
                    if i > 0 {
                        chk(i - 1, j)
                    }
                    if i < h - 1 {
                        chk(i + 1, j)
                    }
                    if j > 0 {
                        chk(i, j - 1)
                    }
                    if j < w - 1 {
                        chk(i, j + 1)
                    }
                }
                ret += sa * sb;
            }
        }
    }
    format!("{}\n", ret)
}

fn main() {
    let mut buf = String::new();
    use std::io::{Read, Write};
    std::io::stdin().read_to_string(&mut buf).unwrap();
    std::io::stdout().write_all(solve(&buf).as_bytes()).unwrap();
}
struct Scanner<'a>(std::str::SplitWhitespace<'a>);
impl<'a> Scanner<'a> {
    fn from_str(src: &str) -> Scanner {
        Scanner(src.split_whitespace())
    }
    fn get(&mut self) -> &str {
        self.0.next().unwrap()
    }
    fn read<T: std::str::FromStr>(&mut self) -> T {
        self.get().parse().ok().unwrap()
    }
}