Buggy python submission (verdict: Time Limit Exceeded):
from collections import Counter,defaultdict,deque
from heapq import heappop,heappush
from bisect import bisect_left,bisect_right 
import sys,math,itertools,fractions,pprint
sys.setrecursionlimit(10**8)
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]
        
    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())
    
    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

#初期化
# uf = UnionFind(n)
h,w = inpl()
s = [input() for _ in range(h)]
d = [(1,0),(-1,0),(0,1),(0,-1)]
neg = [set() for _ in range(h*w)]
uf = UnionFind(h*w)
def ind(i,j): return i*w+j
for y in range(h):
    for x in range(w):
        for dy,dx in d:
            ny = y+dy
            nx = x+dx
            if 0 <= ny < h and 0 <= nx < w and s[ny][nx] != s[y][x]:
                uf.union(ind(y,x), ind(ny,nx))

res = 0
for li in uf.all_group_members().values():
    wh = bl = 0
    for va in li:
        y,x = divmod(va,w)
        if s[y][x] == '#': bl += 1
        else: wh += 1
    res += bl*wh
print(res)

Fixed submission:
from collections import Counter,defaultdict,deque
from heapq import heappop,heappush,heapify
import sys,bisect,math,itertools,fractions,pprint
sys.setrecursionlimit(10**8)
mod = 10**9+7
mod2 = 998244353
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpln(n): return list(int(sys.stdin.readline()) for i in range(n))


h,w = inpl()
s = [input() for i in range(h)]
d = dict()
ld = dict()
i = 0
dx = [-1,0,1,0]
dy = [0,1,0,-1]
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    #根を返す
    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]
        
    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

#初期化
uf = UnionFind(h*w)
for y in range(h):
    for x in range(w):
        if s[y][x] == '.':
            d[(y,x)] = i
            i += 1
for y in range(h):
    for x in range(w):
        if s[y][x] == '.':
            continue
        l = []
        for dir in range(4):
            nx = x+dx[dir]; ny = y+dy[dir]
            if nx<0 or nx>=w or ny<0 or ny>=h:
                continue
            if s[ny][nx] == '#':
                continue
            if l == []:
                ld[(y,x)] = d[(ny,nx)]
            l.append(d[(ny,nx)])            
            uf.union(l[0],d[(ny,nx)])

# print(ld)
res = 0
for key,value in ld.items():
    res += uf.size(value)
print(res)