unittest
{
	assert( [ "3 3", ".#.", "..#", "#.." ].parse.expand.solve == 10 );
	assert( [ "2 4", "....", "...." ].parse.expand.solve == 0 );
	assert( [ "4 3", "###", "###", "...", "###" ].parse.expand.solve == 6 );
}



import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto hw = input.front.split.to!( long[] );
	auto ss = new string[ hw[ 0 ] ];
	foreach( ref s; ss )
	{
		input.popFront;
		s = input.front;
	}
	return tuple( hw[ 0 ], hw[ 1 ], ss );
}

auto solve( long h, long w, string[] ss )
{
	auto ans = 0L;
	auto lss = new long[][]( h, w );
	auto lc = 0L;
	
	for( auto i = 0; i < h; i++ )
	{
		for( auto j = 0; j < w; j++ )
		{
			auto bc = 0L;
			auto wc = 0L;
			lc++;
			
			// 島判定して島内の黒マスと白マスをカウント
			ss.checkBlack( i, j, lc, lss, bc, wc );
			
			// 黒マスと白マスの組数を計算
			ans += bc * wc;
		}
	}
	
	return ans;
}

bool checkBlack( string[] ss, long i, long j, long lc, ref long[][] lss, ref long bc, ref long wc )
{
	// 黒マスは島判定済だったら再判定やらない
	if( ss[ i ][ j ] != '#' || 0 < lss[ i ][ j ] ) return false;
	
	auto w8 = false;
	auto w2 = false;
	auto w4 = false;
	auto w6 = false;
	
	// 白マス判定用に自分に島番号を付ける
	lss[ i ][ j ] = lc;
	
	// 隣の白マスチェック
	if( 0 <= i - 1             ) w8 = ss.checkWhite( i - 1, j, lc, lss, bc, wc );
	if( i + 1 < ss.length      ) w2 = ss.checkWhite( i + 1, j, lc, lss, bc, wc );
	if( 0 <= j - 1             ) w4 = ss.checkWhite( i, j - 1, lc, lss, bc, wc );
	if( j + 1 < ss[ i ].length ) w6 = ss.checkWhite( i, j + 1, lc, lss, bc, wc );
	
	if( w8 || w2 || w4 || w6 )
	{
		// 隣に白マスがあったら組が成立しているのでカウントする
		bc++;
		wc += w8 + w2 + w4 + w6;
		return true;
	}
	else
	{
		// 隣に白マスがなかったら別の島の可能性があるので島番号を消す
		lss[ i ][ j ] = 0;
		return false;
	}
}

bool checkWhite( string[] ss, long i, long j, long lc, ref long[][] lss, ref long bc, ref long wc )
{
	// 黒マスは島判定済でも別の島だったら再判定やる
	if( ss[ i ][ j ] != '.' || lss[ i ][ j ] == lc ) return false;
	
	// 自分に島番号を付ける
	lss[ i ][ j ] = lc;
	
	// 隣の黒マスチェック
	if( 0 <= i - 1             ) ss.checkBlack( i - 1, j, lc, lss, bc, wc );
	if( i + 1 < ss.length      ) ss.checkBlack( i + 1, j, lc, lss, bc, wc );
	if( 0 <= j - 1             ) ss.checkBlack( i, j - 1, lc, lss, bc, wc );
	if( j + 1 < ss[ i ].length ) ss.checkBlack( i, j + 1, lc, lss, bc, wc );
	
	// 呼ばれた時点で組が成立している
	return true;
}
