Buggy python submission (verdict: Time Limit Exceeded):
class UnionFind(object):
    def __init__(self, size):
        self.parent = list(range(size))
    
    def find(self, x):
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])
            return self.parent[x]
    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            self.parent[x] = y

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


h, w = map(int, input().split())
s = [input() for _ in range(h)]

uf = UnionFind(h * w)

diffs = [(1, 0), (-1, 0), (0, 1), (0, -1)]
for i in range(h):
    for j in range(w):
        for di, dj in diffs:
            ni = i + di
            nj = j + dj
            if 0 <= ni < h and 0 <= nj < w and s[i][j] != s[ni][nj]:
                p = i * w + j
                np = ni * w + nj
                uf.union(p, np)
c = 0
for i in range(h * w):
    for j in range(i + 1, h * w):
        if s[i // w][i % w] != s[j // w][j % w] and uf.same(i, j):
            c += 1

print(c)

Fixed submission:
import itertools

h, w = map(int, input().split())
s = [input() for _ in range(h)]

diffs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
t = [[0] * w for _ in range(h)]
group = 1
for i, j in itertools.product(range(h), range(w)):
    if t[i][j] != 0:
        continue

    stack = [(i, j)]
    while stack:
        x, y = stack.pop()
        t[x][y] = group
        for dx, dy in diffs:
            nx = x + dx
            ny = y + dy
            if 0 <= nx < h and 0 <= ny < w and t[nx][ny] == 0 and s[x][y] != s[nx][ny]:
                stack.append((nx, ny))
    group += 1

d = [[0] * 2 for _ in range(group)]
for i, j in itertools.product(range(h), range(w)):
    d[t[i][j]][0 if s[i][j] == '.' else 1] += 1

ans = sum(d[i][0] * d[i][1] for i in range(len(d)))
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
h, w = map(int, input().split())
s = [input() for _ in range(h)]

diffs = [(1, 0), (-1, 0), (0, 1), (0, -1)]
wf = [[float('inf')] * (h * w) for _ in range(h * w)]
for i in range(h):
    for j in range(w):
        for di, dj in diffs:
            ni = i + di
            nj = j + dj
            if 0 <= ni < h and 0 <= nj < w and s[i][j] != s[ni][nj]:
                p = i * w + j
                np = ni * w + nj
                wf[p][np] = 1

for k in range(h * w):
    for i in range(h * w):
        for j in range(h * w):
            wf[i][j] = min(wf[i][j], wf[i][k] + wf[k][j])

c = 0
for i in range(h * w):
    for j in range(i + 1, h * w):
        if s[i // w][i % w] != s[j // w][j % w] and wf[i][j] != float('inf'):
            c += 1

print(c)

Fixed submission:
import itertools

h, w = map(int, input().split())
s = [input() for _ in range(h)]

diffs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
t = [[0] * w for _ in range(h)]
group = 1
for i, j in itertools.product(range(h), range(w)):
    if t[i][j] != 0:
        continue

    stack = [(i, j)]
    while stack:
        x, y = stack.pop()
        t[x][y] = group
        for dx, dy in diffs:
            nx = x + dx
            ny = y + dy
            if 0 <= nx < h and 0 <= ny < w and t[nx][ny] == 0 and s[x][y] != s[nx][ny]:
                stack.append((nx, ny))
    group += 1

d = [[0] * 2 for _ in range(group)]
for i, j in itertools.product(range(h), range(w)):
    d[t[i][j]][0 if s[i][j] == '.' else 1] += 1

ans = sum(d[i][0] * d[i][1] for i in range(len(d)))
print(ans)