Problem: 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.

Examples

Input

3 3
.#.
..#
#..


Output

10


Input

3 3
.#.
..#
..


Output

10


Input

2 4
....
....


Output

0


Input

4 3


...


Output

6

Solution (in JAVA):

Solution:
import java.util.*;

public class Main {
    static final int MOD = 1000000007;
	public static void main (String[] args) {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		int w = sc.nextInt();
		UnionFindTree uft = new UnionFindTree(h, w);
		char[][] field = new char[h][];
		for (int i = 0; i < h; i++) {
		    field[i] = sc.next().toCharArray();
		    for (int j = 0; j < w; j++) {
		        if (field[i][j] == '#') {
		            uft.setBlack(i, j);
		        } else {
		            uft.setWhite(i, j);
		        }
		    }
		}
		
		for (int i = 0; i < h; i++) {
		    for (int j = 0; j < w; j++) {
		        if (field[i][j] == '.') {
		            continue;
		        }
		        if (i != 0 && field[i - 1][j] == '.') {
		            uft.unite(i, j, i - 1, j);
		        }
		        if (i != h - 1 && field[i + 1][j] == '.') {
		            uft.unite(i, j, i + 1, j);
		        }
		        if (j != 0 && field[i][j - 1] == '.') {
		            uft.unite(i, j, i, j - 1);
		        }
		        if (j != w - 1 && field[i][j + 1] == '.') {
		            uft.unite(i, j, i, j + 1);
		        }
		        
		    }
		}
	    System.out.println(uft.getCount());
	}
	
	static class UnionFindTree {
	    int h;
	    int w;
	    int[] parents;
	    int[] blacks;
	    int[] whites;
	    
	    public UnionFindTree(int h, int w) {
	        this.h = h;
	        this.w = w;
	        int size = h * w;
	        parents = new int[size];
	        blacks = new int[size];
	        whites = new int[size];
	        for (int i = 0; i < size; i++) {
	            parents[i] = i;
	        }
	    }
	    
	    public int find (int x) {
	        if (parents[x] == x) {
	            return x;
	        } else {
	            return parents[x] = find(parents[x]);
	        }
	    }
	    
	    public void unite(int h1, int w1, int h2, int w2) {
	        unite(h1 * w + w1, h2 * w + w2);
	    }
	    
	    public void unite(int x, int y) {
	        int xx = find(x);
	        int yy = find(y);
	        if (xx == yy) {
	            return;
	        }
	        parents[xx] = yy;
	        blacks[yy] += blacks[xx];
	        whites[yy] += whites[xx];
	    }
	    
	    public void setBlack(int h1, int w1) {
	        blacks[h1 * w + w1]++;
	    }
	    
	    public void setWhite(int h1, int w1) {
	        whites[h1 * w + w1]++;
	    }
	    
	    public long getCount() {
	        long total = 0;
	        for (int i = 0; i < parents.length; i++) {
	            if (parents[i] == i) {
	                total += (long)blacks[i] * whites[i];
	            }
	        }
	        return total;
	    }
	}
}