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

object Main extends App {

  val (h, w) = readLine.split(" ").map(_.toInt) match {
    case Array(h, w) => (h, w)
  }

  case class Position(i: Int, j: Int)

  case class Point(position: Position,
                   isBlack: Boolean,
                   nexts: Seq[Position] = Nil)

  object Field {
    def apply(charArrArr: Array[Array[Char]]): Field = {
      val points: Array[Array[Point]] = charArrArr.zipWithIndex
        .filterNot(t => t._2 == 0 || t._2 == h + 1)
        .map {
          case (charArr, i) =>
            charArr.zipWithIndex
              .filterNot(t => t._2 == 0 || t._2 == w + 1)
              .flatMap {
                case (c, j) =>
                  def nexts(isBlack: Boolean): Seq[Position] =
                    Seq((i, j - 1), (i, j + 1), (i - 1, j), (i + 1, j))
                      .flatMap(p =>
                        charArrArr(p._1)(p._2) match {
                          case '#' if !isBlack => Some(Position(p._1, p._2))
                          case '.' if isBlack  => Some(Position(p._1, p._2))
                          case _               => None
                        })

                  c match {
                    case '#' => Some(Point(Position(i, j), true, nexts(true)))
                    case '.' => Some(Point(Position(i, j), false, nexts(false)))
                    case _   => None
                  }
              }
        }
      Field(points)
    }
  }

  case class Field(points: Array[Array[Point]]) {

    def find(p: Position): Point = points(p.i - 1)(p.j - 1)

    def nextWps(bp: Point,
                prevWps: Seq[Point] = Seq(),
                prevBps: Seq[Point] = Seq()): Seq[Point] =
      bp.nexts
        .filterNot(wpPositions => prevWps.exists(_.position == wpPositions))
        .map(find) match {
        case Nil => Seq()
        case wps =>
          wps ++ wps.flatMap(wp => nextBps(wp, prevWps, bp +: prevBps))
      }

    def nextBps(wp: Point,
                prevWps: Seq[Point] = Seq(),
                prevBps: Seq[Point] = Seq()): Seq[Point] =
      wp.nexts
        .filterNot(bpPositions => prevBps.exists(_.position == bpPositions))
        .map(find) match {
        case Nil => Seq()
        case bps => bps.flatMap(bp => nextWps(bp, wp +: prevWps, prevBps))
      }

  }

  val charArrList =
    List(Array.fill(w + 2)('x')) ++ (1 to h)
      .map(_ => ('x' + readLine + 'x').toCharArray)
      .toList ++ List(Array.fill(w + 2)('x'))

  val field = Field(charArrList.toArray)
  val count = field.points.flatten
    .filter(_.isBlack)
    .map(bp => field.nextWps(bp).map(_.position).distinct.length)
    .sum
  println(count)

}