Buggy python submission (verdict: Runtime Error):
H, W = map(int, input().split())
F = [list(input()) for _ in range(H)]

move = [(-1, 0), (1, 0), (0, -1), (0, 1)]
seen = [[0] * W for _ in range(H)]

# Fの点を頂点とするグラフを考える。グラフの連結成分に'#'がbコ, '.'がwコある場合、
# b*wが条件を満たす

def dfs(sy, sx):
    seen[sy][sx] = 1
    b, w = 1, 0
    
    for dy, dx in move:
      ny = sy + dy
      nx = sx + dx
      if 0 <= ny < H and 0 <= nx < W and F[ny][nx] != F[sy][sx] and not seen[ny][nx]:
        p = dfs(ny, nx)
        b += p[1]  # 逆にしている
        w += p[0]  # 天才か？
    return (b, w)
        
count = 0
for i in range(H):
    for j in range(W):
        if not seen[i][j]:
            b, w = dfs(i, j)
            count += b * w

print(count)

Fixed submission:
import sys
sys.setrecursionlimit(10 ** 7)

H, W = map(int, input().split())
F = [list(input()) for _ in range(H)]

move = [(-1, 0), (1, 0), (0, -1), (0, 1)]
seen = [[0] * W for _ in range(H)]

# Fの点を頂点とするグラフを考える。グラフの連結成分に'#'がbコ, '.'がwコある場合、
# b*wが条件を満たす

def dfs(sy, sx):
    seen[sy][sx] = 1
    b, w = 1, 0
    
    for dy, dx in move:
      ny = sy + dy
      nx = sx + dx
      if 0 <= ny < H and 0 <= nx < W and F[ny][nx] != F[sy][sx] and not seen[ny][nx]:
        p = dfs(ny, nx)
        b += p[1]  # 逆にしている
        w += p[0]  # 天才か？
    return (b, w)
        
count = 0
for i in range(H):
    for j in range(W):
        if not seen[i][j]:
            b, w = dfs(i, j)
            count += b * w

print(count)

Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10**7)

H, W = map(int, input().split())
F = [list(input()) for _ in range(H)]

move = (-1, 1)
count = []

def dfs(i, j, seen):
    seen.add((i, j))
    if F[i][j] == '#':
        next = '.'
    else:
        next = '#'

    for m in move:
        if 0 <= i+m < H and F[i+m][j] == next and (i+m, j) not in seen:
            seen.add((i+m, j))
            if F[i][j] == '#':
                count.append((i+m, j))

            dfs(i+m, j, seen)
        if 0 <= j+m < W and F[i][j+m] == next and (i, j+m) not in seen:
            seen.add((i, j+m))
            if F[i][j] == '#':
                count.append((i, j+m))
            dfs(i, j+m, seen)

for i in range(H):
    for j in range(W):
        if F[i][j] == '#':
            dfs(i, j, set())

print(len(count))

Fixed submission:
import sys
sys.setrecursionlimit(10 ** 7)

H, W = map(int, input().split())
F = [list(input()) for _ in range(H)]

move = [(-1, 0), (1, 0), (0, -1), (0, 1)]
seen = [[0] * W for _ in range(H)]

# Fの点を頂点とするグラフを考える。グラフの連結成分に'#'がbコ, '.'がwコある場合、
# b*wが条件を満たす

def dfs(sy, sx):
    seen[sy][sx] = 1
    b, w = 1, 0
    
    for dy, dx in move:
      ny = sy + dy
      nx = sx + dx
      if 0 <= ny < H and 0 <= nx < W and F[ny][nx] != F[sy][sx] and not seen[ny][nx]:
        p = dfs(ny, nx)
        b += p[1]  # 逆にしている
        w += p[0]  # 天才か？
    return (b, w)
        
count = 0
for i in range(H):
    for j in range(W):
        if not seen[i][j]:
            b, w = dfs(i, j)
            count += b * w

print(count)

Buggy python submission (verdict: Runtime Error):
H, W = map(int, input().split())
F = [list(input()) for _ in range(H)]

move = (-1, 1)
count = []

def dfs(i, j, seen):
    seen.add((i, j))
    if F[i][j] == '#':
        next = '.'
    else:
        next = '#'

    for m in move:
        if 0 <= i+m < H and F[i+m][j] == next and (i+m, j) not in seen:
            seen.add((i+m, j))
            if F[i][j] == '#':
                count.append((i+m, j))

            dfs(i+m, j, seen)
        if 0 <= j+m < W and F[i][j+m] == next and (i, j+m) not in seen:
            seen.add((i, j+m))
            if F[i][j] == '#':
                count.append((i, j+m))
            dfs(i, j+m, seen)

for i in range(H):
    for j in range(W):
        if F[i][j] == '#':
            dfs(i, j, set())

print(len(count))

Fixed submission:
import sys
sys.setrecursionlimit(10 ** 7)

H, W = map(int, input().split())
F = [list(input()) for _ in range(H)]

move = [(-1, 0), (1, 0), (0, -1), (0, 1)]
seen = [[0] * W for _ in range(H)]

# Fの点を頂点とするグラフを考える。グラフの連結成分に'#'がbコ, '.'がwコある場合、
# b*wが条件を満たす

def dfs(sy, sx):
    seen[sy][sx] = 1
    b, w = 1, 0
    
    for dy, dx in move:
      ny = sy + dy
      nx = sx + dx
      if 0 <= ny < H and 0 <= nx < W and F[ny][nx] != F[sy][sx] and not seen[ny][nx]:
        p = dfs(ny, nx)
        b += p[1]  # 逆にしている
        w += p[0]  # 天才か？
    return (b, w)
        
count = 0
for i in range(H):
    for j in range(W):
        if not seen[i][j]:
            b, w = dfs(i, j)
            count += b * w

print(count)