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: Runtime Error)

use v5.18;
use warnings;
  use DDP +{ deparse => 1, use_prototypes => 0 };
use List::Util qw( sum );
sub read_line { chomp(my $s = <>); $s }
sub splited_read_line { split / /, read_line }
sub unique { my %u; $u{$_} = $_ for @_; values %u; }
 
package UnionFind {
 
  sub new {
    my ($class, $n) = @_;
    bless +{
      size => $n,
      par  => [ 0 .. $n - 1 ],
      rank => [ (0) x $n ],
    }, $class;
  }

  sub size { shift->{size} }
 
  sub root {
    my ($self, $x) = @_;
    $self->{par}[$x] == $x ? $x : ( $self->{par}[$x] = $self->root($self->{par}[$x]) );
  }
 
  sub unite {
    my ($self, $x, $y) = @_;
    my ($x_root, $y_root) = ($self->root($x), $self->root($y));
    return if $x_root == $y_root;
    if ( $self->{rank}[$x_root] < $self->{rank}[$y_root] ) {
      $self->{par}[$x_root] = $y_root;
    }
    else {
      $self->{par}[$y_root] = $x_root;
      $self->{rank}[$x_root]++ if $self->{rank}[$x_root] == $self->{rank}[$y_root];
    }
  }
 
  sub is_same {
    my ($self, $x, $y) = @_;
    $self->root($x) == $self->root($y);
  }
 
  sub roots {
    my $self = shift;
    [ map { $self->root($_) } 0 .. $#{ $self->{par} } ];
  }
 
}
 
my ($h, $w) = splited_read_line;
my $mass = [ map { [ split //, read_line ] } 0 .. $h - 1 ];
say solve($h, $w, $mass);
 
sub solve {
  my ($h, $w, $mass) = @_;
  my $tree = UnionFind->new($h * $w);
  for my $y (0 .. $h - 1) {
    for my $x (0 .. $w - 1) {
      my $current = $y * $w + $x;
      next if $mass->[$y][$x] eq '.';
      my $points = [
        [ $y + 1, $x ],
        [ $y - 1, $x ],
        [ $y, $x + 1 ],
        [ $y, $x - 1 ],
      ];
      for my $point (@$points) {
        my ($y, $x) = @$point;
        if ( $y < $h && $y >= 0 && $x < $w && $x >= 0 && $mass->[$y][$x] eq '.' ) {
          $tree->unite($current, $y * $w + $x);
        }
      }
    }
  }
  my @roots = @{ $tree->roots };
  my @vertexes = unique @roots;
  sum map {
    my $vertex = $_;
    my @points = grep { $vertex == $roots[$_] } 0 .. $tree->size - 1;
    my $colors = join '', map {
      my $y = int($_ / $w);
      my $x = $_ % $w;
      $mass->[$y][$x];
    } @points;
    my $black = () = $colors =~ /#/g;
    my $white = () = $colors =~ /\./g;
    $black * $white;
  } @vertexes;
}