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 Perl (v5.18.2) (judge verdict: Time Limit Exceeded)

#!/usr/bin/perl
#= CPAN mocules =====================================================#
use strict;				# strictモード
use warnings;			# 警告有効

#= Global values ====================================================#
my ($H, $W);
my @g_field;
my @g_chkedField;
my @startMark;
my @detect;
my $g_detCnt = 0;

#= Local routines ===================================================#
# 1ならチェック済み、0なら未チェック
sub isChked{
	my $i = shift;
	my $j = shift;

	if (($i < 0) || ($H <= $i)){
		return 1;
	}
	if (($j < 0) || ($W <= $j)){
		return 1;
	}
	if ($g_chkedField[$i]){
		return $g_chkedField[$i]->[$j];
	}else{
		return 0;
	};
}

sub nextChk{
	my $i = shift;
	my $j = shift;
	my $expMark = shift;
	my $moveList = shift;

	my $mark = $g_field[$i]->[$j];
	if ($expMark eq $mark){
		if ($expMark eq "."){
			# ここで条件合致
			$g_detCnt++;
		}

		$g_chkedField[$i]->[$j] = 1;

		my $nextMark = ($mark eq ".")? "#" : "." ;
		# 上右下左
		# 上をチェックする
		if ($moveList & 0x8){
			if (!isChked($i-1, $j)){
				nextChk($i-1, $j, $nextMark, 0xD);
			}
		}
		# 右をチェックする
		if ($moveList & 0x4){
			if (!isChked($i, $j+1)){
				nextChk($i, $j+1, $nextMark, 0xE);
			}
		}
		# 下をチェックする
		if ($moveList & 0x2){
			if (!isChked($i+1, $j)){
				nextChk($i+1, $j, $nextMark, 0x7);
			}
		}
		# 左をチェックする
		if ($moveList & 0x1){
			if (!isChked($i, $j-1)){
				nextChk($i, $j-1, $nextMark, 0xB);
			}
		}
	}


}

sub main(){
	my $in = <>;chomp $in;
	($H, $W) = split(/ /, $in);

	foreach (1..$H){
		$in = <>; chomp $in;
		$g_field[$_ - 1] = [split(//, $in)];
	}

	foreach my $i (1..$H){
		foreach my $j (1..$W){
			my $nextMark = $g_field[$i-1]->[$j-1];
			if ($nextMark eq "#"){
				$startMark[0] = $i - 1;
				$startMark[1] = $j - 1;
				$startMark[2] = $nextMark;
				@g_chkedField = ();
				nextChk($i - 1, $j - 1, $nextMark, 0xF);
			}
		}
	}

	print $g_detCnt, "\n";

	return 0;
}

#----- 実行 -----#
exit( main() );