import std.stdio, std.conv, std.string, std.bigint;
import std.math, std.random, std.datetime;
import std.array, std.range, std.algorithm, std.container, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

class Node{
	long value;
	long id;
	long groupid = -1;
	bool isGrouped;
	Node[] nodes;
	this(long id, long value){
		this.id = id;
		this.value = value;
	}
	void join(Node nd){
		if(this.value == nd.value) return;
		else{
			this.nodes ~= nd;
			nd.nodes ~= this;
		}
	}
	void groupify(long id){
		if(this.isGrouped) return;
		this.isGrouped = 1;
		this.groupid = id;
		foreach(nd; this.nodes){
			nd.groupify(id);
		}
	}
	override string toString(){
		return "\n" ~ this.id.to!string ~  " '" ~ this.value.to!char ~ "' " ~ this.groupid.to!string ~ " " ~ this.nodes.map!(x => x.id.to!string).join(",");
	}
}

void main(){
	auto h = read.to!long;
	auto w = read.to!long;
	
	string s;
	foreach(i; 0 .. h) s ~= readln.chomp;
	
	Node[] nodes;
	foreach(i; 0 .. h * w){
		nodes ~= new Node(i, s[i]);
		}
	
	foreach(i, nd; nodes){
		if(i > w) nd.join(nodes[i - w]);
		if(i % w > 0) nd.join(nodes[i - 1]);
	}
	debug writeln("nodes:", nodes);
	
	foreach(nd; nodes){
		nd.groupify(nd.id);
	}
	debug writeln("nodes:", nodes);
	
	long[] bcount, wcount;
	foreach(i; 0 .. h * w){
		bcount ~= 0;
		wcount ~= 0;
	}
	foreach(nd; nodes){
		if(nd.value == '#') bcount[nd.groupid] += 1;
		else wcount[nd.groupid] += 1;
	}
	debug writeln("bcount:", bcount);
	debug writeln("wcount:", wcount);
	
	
	long ans = 0;
	foreach(i; 0 .. h * w){
		ans += bcount[i] * wcount[i];
	}
	
	ans.writeln;
}
