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 Scala (2.11.7) (judge verdict: Accepted)

import java.io._
import java.util.StringTokenizer
import scala.util.control.Breaks.{breakable,break}

object Main extends App {
  val in = new InputReader(System.in)
  val pw = new PrintWriter(System.out)

  val H, W = in.next().toInt
  val S = new Array[String](H+1)
  for (i <- 1 to H)
    S(i) = "N" + in.next()


  //
  type Coord = (Int, Int)

  val dp = Array.ofDim[Boolean](H+1, W+1)

  def inField(p: Coord): Boolean = {
    val (x, y) = p
    1 <= x && x <= W && 1 <= y && y <= H
  }

  def mk4dir(p: Coord): List[Coord] = {
    val (x, y) = p
    List((x-1, y), (x+1, y), (x, y-1), (x, y+1)).filter(inField)
  }

  def calc(p: Coord): (Int, Int) = {
    var B = 0
    var W = 0

    val stack = new scala.collection.mutable.Stack[(Coord, Char)]
    stack.push((p, 'N'))

    while(!stack.isEmpty) {
      val (p, pre) = stack.pop()

      val (x, y) = p

      if (dp(y)(x))
        ()
      else {
        if (S(y)(x) != pre) {
          dp(y)(x) = true
          if (S(y)(x) == '#')
            B += 1
          else
            W += 1

          mk4dir(p).foreach(p => stack.push((p, S(y)(x))))
        }
      }
    }

    (B, W)
  }

  var ans = 0L
  for (y <- 1 to H)
    for(x <- 1 to W) {
      if (!dp(y)(x) && S(y)(x) == '#') {
        val (b, w) = calc((x, y))

        ans += b.toLong * w
      }
    }

  println(ans)
}


class InputReader(stream: InputStream) {
  private val reader = new BufferedReader(new InputStreamReader(stream))
  private var tokenizer: StringTokenizer = new StringTokenizer(reader.readLine())
  def next(): String = {
    while (!tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(reader.readLine())
    }
    tokenizer.nextToken()
  }
}