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.*;
import java.io.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;
 
public class Main{
//    static final long mod=1000000007;
    static int dx[]={-1,0,1,0};
    static int dy[]={0,-1,0,1};
    static long pl,mi;

    public  static void main(String[] args)   throws Exception, IOException{        
        Reader sc = new Reader(System.in);
        PrintWriter out=new PrintWriter(System.out);
        // int n=sc.nextInt();
        // char c[][] = new char[h][w];
        // char c[]=sc.nextString().toCharArray();
        // int d[]=new int[n];
        // for(int i=0; i<n; i++) {d[i]=sc.nextInt();}

        int h=sc.nextInt();
        int w=sc.nextInt();
        char c[][]=new char[h][w];
        
        for (int i = 0; i < c.length; i++) {
			c[i]=sc.nextString().toCharArray();
		}
        int m[][]=new int[h][w];
        int k=0;
        long ans=0;
        for (int i = 0; i < m.length; i++) {
			for (int t = 0; t < m[0].length; t++) {
				if(c[i][t]=='#' && m[i][t]==0) {
					pl=0;
					mi=0;
					rep(c,m,i,t,++k);
					ans+=pl*mi;
				}
			}
		}



        
        

        out.println(ans);
        out.flush();
    }
    
    static void rep(char c[][],int mark[][] ,int x, int y, int k) {
    	for (int i = 0; i < 4; i++) {
			int xx=x+dx[i],yy=y+dy[i];
			if(validpos(xx, yy, c.length, c[0].length) && mark[xx][yy]==0) {
				if(c[xx][yy]=='.' && c[x][y]=='#') {
					mark[xx][yy]=-k;mi++;
					rep(c,mark,xx,yy,k);
				}
				if(c[xx][yy]=='#' && c[x][y]=='.') {
					mark[xx][yy]=k;pl++;
					rep(c,mark,xx,yy,k);
				}
			}
		}
    }
    
    static boolean validpos(int x,int y,int r, int c){
        return x<r && 0<=x && y<c && 0<=y;
    }

    static void db(Object... os){
        System.err.println(Arrays.deepToString(os));
    }  
}

//class P {
//    int id, d;
//    P(int  id, int d) {
//        this.id=id;
//        this.d=d;
//    }
//}

//class P implements Comparable<P>{
//    int id, d;
//    P(int  id, int d) {
//        this.id=id;
//        this.d=d;
//    }
//    public int compareTo(P p){
//        return d-p.d; //des
//    }
//}

class Reader
{ 
    private BufferedReader x;
    private StringTokenizer st;
    
    public Reader(InputStream in)
    {
        x = new BufferedReader(new InputStreamReader(in));
        st = null;
    }
    public String nextString() throws IOException
    {
        while( st==null || !st.hasMoreTokens() )
            st = new StringTokenizer(x.readLine());
        return st.nextToken();
    }
    public int nextInt() throws IOException
    {
        return Integer.parseInt(nextString());
    }
    public int[] nextIntArray(int size) throws IOException{
    	int r[] = new int[size];
    	for (int i = 0; i < size; i++) {
			r[i] = this.nextInt(); 
		}
    	return r;
    }
    public long nextLong() throws IOException
    {
        return Long.parseLong(nextString());
    }
    public double nextDouble() throws IOException
    {
        return Double.parseDouble(nextString());
    }
}