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 JavaScript (Node.js 12.16.1) (judge verdict: Runtime Error)

function Main(input) {
	input = input.trim().split("\n").map(function(x) { return x.split(" ")});
	var H = parseInt(input[0][0], 10);
	var W = parseInt(input[0][1], 10);
	var arr_S = [];
	var colorPairMap = [];
	var doneOrNotMap = [];
	var tmpIslandMap = [];

	for (var i = 0; i < H; i++){
		arr_S.push(input[i + 1]);
		colorPairMap.push(Array.from({length: W}, () => 0));
		doneOrNotMap.push(Array.from({length: W}, () => 0));
		tmpIslandMap.push(Array.from({length: W}, () => -1));
	}
	var tmp = '';
	for (var i = 0; i < H; i++){
		for (var j = 0; j < W; j++){
			if ((i + j) % 2 === 0) tmp = '#';
			else tmp = '.';
			if (arr_S[i][0].substr(j, 1) === tmp) colorPairMap[i][j] = 1;
		}
	}

	
	var tmpIslandID = 0;
	var tmpAdj = [];
	var eachIslandColorCount = [];
	var eachIslandCoordinates = [];
	var tmpList;
	for (var i = 0; i < H; i++){
		for (var j = 0; j < W; j++){
			tmpAdj = [];
			 if ((i - 1) >= 0){
				if (colorPairMap[i - 1][j] === colorPairMap[i][j]) tmpAdj.push(tmpIslandMap[i - 1][j]);
			 }
			 if ((j - 1) >= 0){
				if (colorPairMap[i][j - 1] === colorPairMap[i][j])tmpAdj.push(tmpIslandMap[i][j - 1]);
			 }

			 if (tmpAdj.length > 1) {
			 	if (tmpAdj[0] !== tmpAdj[1]){
					 tmpList = eachIslandCoordinates[Math.max(tmpAdj[0], tmpAdj[1])];
					 for (var i = 0; i < tmpList.length; i++){
						 tmpIslandMap[tmpList[i][0]][tmpList[i][1]] = Math.min(tmpAdj[0], tmpAdj[1]);
						 eachIslandCoordinates[Math.min(tmpAdj[0], tmpAdj[1])].push(tmpList[i][0], tmpList[i][1]);
					 }
					 eachIslandColorCount[Math.min(tmpAdj[0], tmpAdj[1])] = VO(eachIslandColorCount[Math.min(tmpAdj[0], tmpAdj[1])], eachIslandColorCount[Math.max(tmpAdj[0], tmpAdj[1])], '+');
				 }
				 tmpIslandMap[i][j] = Math.min(tmpAdj[0], tmpAdj[1]);
				 eachIslandColorCount[tmpIslandMap[i][j]][(i + j) % 2] ++;
				 eachIslandCoordinates[tmpIslandMap[i][j]].push([i, j]);
			 }
			 if (tmpAdj.length === 1){
				 tmpIslandMap[i][j] = tmpAdj[0];
				 eachIslandColorCount[tmpAdj[0]][(i + j) % 2] ++;
				 eachIslandCoordinates[tmpAdj[0]].push([i, j]);
			 }		
			 if (tmpAdj.length === 0){
				 tmpIslandMap[i][j] = tmpIslandID;
				 eachIslandColorCount[tmpIslandID] = [0, 0];
				 eachIslandColorCount[tmpIslandID][(i + j) % 2] ++;
				 eachIslandCoordinates[tmpIslandID] = [[i, j]];
				 tmpIslandID ++;
			 }
		}
	}
	var ans = 0;
	for (var i of eachIslandColorCount){
		ans += i[0] * i[1];
	}
	console.log(ans);
}

function VO(v1, v2, op){
    var ans = []
    if (v1.length !== v2.length) {
      if (v2.length == 1){
        v2 = Array.from({ length: (v1.length) }, () => v2);
      } else {
          return null;
      }
    }
    for (var i = 0; i < v1.length; i++){
        if (op == '+') {
            ans.push(v1[i] + v2[i]);
        } 
        if (op == '-') {
            ans.push(v1[i] - v2[i]);
        } 
        if (op == '*') {
            ans.push(v1[i] * v2[i]);
        } 
        if (op == '/') {
            ans.push(v1[i] / v2[i]);
        } 
        if (op == '%') {
            ans.push(v1[i] % v2[i]);
        } 
        if (op == '||') {
            ans.push(Math.max(v1[i],v2[i]));
        } 
    }
    return ans;    
}


Main(require("fs").readFileSync("/dev/stdin", "utf8"));