import sys

sys.setrecursionlimit(200000)

input = sys.stdin.readline





H, W = [int(_) for _ in input().split()]

S = [eval(input()) for _ in range(H)]



move = ((1, 0), (-1, 0), (0, 1), (0, -1))

visited = [[False] * W for _ in range(H)]

b, w = 0, 0



def dfs(i, j):

    if visited[i][j]:

        return (0, 0)



    visited[i][j] = True



    if S[i][j] == '#':

        b, w = 1, 0

    else:

        b, w = 0, 1



    for di, dj in move:

        ni, nj = i + di, j + dj

        if not (0 <= ni < H and 0 <= nj < W):

            continue

        if S[i][j] != S[ni][nj]:

                db, dw = dfs(ni, nj)

                b, w = b + db, w + dw



    return (b, w)





result = 0

for i in range(H):

    for j in range(W):

        b, w = dfs(i, j)

        result += b * w

print(result)



from collections import deque



H, W = [int(_) for _ in input().split()]

S = [eval(input()) for _ in range(H)]



move = ((1, 0), (-1, 0), (0, 1), (0, -1))

visited = [[False] * W for _ in range(H)]



def bfs(i, j):

    b, w = 0, 0

    visited[i][j] = True

    que = deque([(i, j)])



    while que:

        ci, cj = que.popleft()

        if S[ci][cj] == '#':

            b += 1

        else:

            w += 1



        for di, dj in move:

            ni, nj = ci + di, cj + dj

            if not (0 <= ni < H and 0 <= nj < W) or visited[ni][nj]:

                continue

            if S[ci][cj] != S[ni][nj]:

                visited[ni][nj] = True

                que.append((ni, nj))



    return b * w





result = 0

for i in range(H):

    for j in range(W):

        if visited[i][j]:

            continue

        result += bfs(i, j)

print(result)

import sys

sys.setrecursionlimit(200000)
input = sys.stdin.readline
H, W = [int(_) for _ in input().split()]
S = [eval(input()) for _ in range(H)]
move = ((1, 0), (-1, 0), (0, 1), (0, -1))
visited = [[False] * W for _ in range(H)]
b, w = 0, 0


def dfs(i, j):
    if visited[i][j]:
        return (0, 0)
    visited[i][j] = True
    if S[i][j] == "#":
        b, w = 1, 0
    else:
        b, w = 0, 1
    for di, dj in move:
        ni, nj = i + di, j + dj
        if not (0 <= ni < H and 0 <= nj < W):
            continue
        if S[i][j] != S[ni][nj]:
            db, dw = dfs(ni, nj)
            b, w = b + db, w + dw
    return (b, w)


result = 0
for i in range(H):
    for j in range(W):
        b, w = dfs(i, j)
        result += b * w
print(result)

from collections import deque

H, W = [int(_) for _ in input().split()]
S = [eval(input()) for _ in range(H)]
move = ((1, 0), (-1, 0), (0, 1), (0, -1))
visited = [[False] * W for _ in range(H)]


def bfs(i, j):
    b, w = 0, 0
    visited[i][j] = True
    que = deque([(i, j)])
    while que:
        ci, cj = que.popleft()
        if S[ci][cj] == "#":
            b += 1
        else:
            w += 1
        for di, dj in move:
            ni, nj = ci + di, cj + dj
            if not (0 <= ni < H and 0 <= nj < W) or visited[ni][nj]:
                continue
            if S[ci][cj] != S[ni][nj]:
                visited[ni][nj] = True
                que.append((ni, nj))
    return b * w


result = 0
for i in range(H):
    for j in range(W):
        if visited[i][j]:
            continue
        result += bfs(i, j)
print(result)

-import sys +from collections import deque -sys.setrecursionlimit(200000) -input = sys.stdin.readline -b, w = 0, 0 -def dfs(i, j): -    if visited[i][j]: -        return (0, 0) +def bfs(i, j): +    b, w = 0, 0 -    if S[i][j] == "#": -        b, w = 1, 0 -    else: -        b, w = 0, 1 -    for di, dj in move: -        ni, nj = i + di, j + dj -        if not (0 <= ni < H and 0 <= nj < W): -            continue -        if S[i][j] != S[ni][nj]: -            db, dw = dfs(ni, nj) -            b, w = b + db, w + dw -    return (b, w) +    que = deque([(i, j)]) +    while que: +        ci, cj = que.popleft() +        if S[ci][cj] == "#": +            b += 1 +        else: +            w += 1 +        for di, dj in move: +            ni, nj = ci + di, cj + dj +            if not (0 <= ni < H and 0 <= nj < W) or visited[ni][nj]: +                continue +            if S[ci][cj] != S[ni][nj]: +                visited[ni][nj] = True +                que.append((ni, nj)) +    return b * w -        b, w = dfs(i, j) -        result += b * w +        if visited[i][j]: +            continue +        result += bfs(i, j)