import std.stdio;
import std.algorithm;
import std.array;
import std.conv;
import std.datetime;
import std.numeric;
import std.math;
import std.string;

string my_readln() { return chomp(readln()); }

void main()
{//try{
	auto tokens = split(my_readln());
	auto H = tokens[0].to!ulong();
	auto W = tokens[1].to!ulong();
	string[] S;
	foreach (i; 0..H)
	{
		S ~= my_readln();
	}

	uint[][] close;
	close.length = H;
	foreach (ref e; close) e.length = W;
	ulong[2][][] memo;
	memo.length = H;
	foreach (ref e; memo)
	{
		e.length = W;
		fill(e, ulong.max);
	}

	ulong f(long i, long j, char last, uint depth)
	{
		if (i < 0 || i >= H || j < 0 || j >= W) return 0;
		if (close[i][j] == 1) return 0;
		if (S[i][j] == last) return 0;
		auto m = memo[i][j];
		if (m[0] != ulong.max && m[1] <= depth) 
		{
			return m[0];
		}

		ulong cnt = S[i][j] == '.' ? 1 : 0;
		close[i][j] = 1;
		cnt += f(i-1, j, S[i][j], depth+1);
		cnt += f(i+1, j, S[i][j], depth+1);
		cnt += f(i, j-1, S[i][j], depth+1);
		cnt += f(i, j+1, S[i][j], depth+1);
		close[i][j] = 0;
		memo[i][j] = [cnt, depth];
		if (i == 2) stderr.writeln(i, " ", j, " ", cnt);
		return cnt;
	}

	ulong ans;
	foreach (i; 0..H)
	{
		foreach (j; 0..W)
		{
			if (S[i][j] == '#')
			{
				//auto t = f(i, j, '.');
				//if (t != 0) stderr.writeln(i, " ", j, " ", t);
				ans += f(i, j, '.', 0);
			}
		}
	}

	writeln(ans);
	stdout.flush();
	/*}catch (Throwable e)
	{
	writeln(e.toString());
	}
	readln();*/
}