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 Go (1.14.1) (judge verdict: Accepted)

package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

func main() {
	io := NewIo(os.Stdin, os.Stdout)
	defer io.Flush()
	h, w := io.NextInt(), io.NextInt()
	stage := make([]string, h)
	for i := 0; i < h; i++ {
		stage[i] = io.Next()
	}
	ans := solve(h, w, stage)
	io.Println(ans)
}

var logger = log.New(os.Stderr, "", 0)

func solve(h, w int, stage []string) (ans int) {
	visited := make([][]bool, h)
	for i := range visited {
		visited[i] = make([]bool, w)
	}
	for x := 0; x < h; x++ {
		for y := 0; y < w; y++ {
			if visited[x][y] {
				continue
			}
			ans += bfs(x, y, visited, stage)
		}
	}
	return ans
}

func bfs(x, y int, visited [][]bool, stage []string) int {
	h, w := len(stage), len(stage[0])
	count := make(map[byte]int, 2)
	q := newQueue()
	visited[x][y] = true
	count[stage[x][y]]++
	q.push(pair{x, y})
	for len(*q) > 0 {
		p := q.pop()
		for i := range dx {
			nx, ny := p.x+dx[i], p.y+dy[i]
			if nx < 0 || h <= nx || ny < 0 || w <= ny {
				logger.Println("continue: out of range", nx, ny)
				continue
			}
			if visited[nx][ny] {
				logger.Println("continue: already visited", nx, ny)
				continue
			}
			if stage[nx][ny] == stage[p.x][p.y] {
				logger.Println("continue: same color", nx, ny)
				continue
			}
			logger.Printf("visit: (%d,%d)->(%d,%d)\n", p.x, p.y, nx, ny)
			visited[nx][ny] = true
			count[stage[nx][ny]]++
			q.push(pair{nx, ny})
		}
	}
	return count['#'] * count['.']
}

type pair struct{ x, y int }

type queue []pair

func newQueue() *queue {
	return &queue{}
}

func (q *queue) push(p pair) {
	*q = append(*q, p)
	logger.Println("push:", p)
}

func (q *queue) pop() pair {
	p := (*q)[0]
	*q = (*q)[1:]
	logger.Println("pop:", p)
	return p
}

var dx = []int{0, 0, -1, 1}
var dy = []int{-1, 1, 0, 0}

// Io is I/O object
type Io struct {
	reader    *bufio.Reader
	writer    *bufio.Writer
	tokens    []string
	nextToken int
}

// NewIo returns a new Io instance
func NewIo(r io.Reader, w io.Writer) *Io {
	return &Io{
		reader: bufio.NewReader(r),
		writer: bufio.NewWriter(w),
	}
}

// Flush flushes writer
func (io *Io) Flush() {
	err := io.writer.Flush()
	if err != nil {
		panic(err)
	}
}

// NextLine scans a line from stdin
func (io *Io) NextLine() string {
	var buffer []byte
	for {
		line, isPrefix, err := io.reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buffer = append(buffer, line...)
		if !isPrefix {
			break
		}
	}
	return string(buffer)
}

// Next return a word from stdin
func (io *Io) Next() string {
	for io.nextToken >= len(io.tokens) {
		line := io.NextLine()
		io.tokens = strings.Fields(line)
		io.nextToken = 0
	}
	r := io.tokens[io.nextToken]
	io.nextToken++
	return r
}

// NextInt returns an integer from stdin
func (io *Io) NextInt() int {
	i, err := strconv.Atoi(io.Next())
	if err != nil {
		panic(err)
	}
	return i
}

// Println is a wrapper of fmt.Fprintln
func (io *Io) Println(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}