import sys

sys.setrecursionlimit(10**6)



around = [(0,1),(1,0),(0,-1),(-1,0)]



H,W = list(map(int,input().split()))

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



checked = [[0]*W for _ in range(H)]



def dfs(i,j):

    checked[i][j] = 1

    for di,dj in around:

        ni = i + di; nj = j + dj

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

            continue

        if checked[ni][nj]:

            continue

        p = grid[i][j]

        np = grid[ni][nj]

        if (p,np) == (".","#"):

            global b

            b += 1

            dfs(ni,nj)

        if (p,np) == ("#","."):

            global w

            w += 1

            dfs(ni,nj)



ans = 0

for i in range(H):

    for j in range(W):

        b = 0; w = 1

        if not checked[i][j] and grid[i][j] == ".":

            dfs(i,j)

        ans += b*w

print(ans)
from collections import deque

around = [(0,1),(1,0),(0,-1),(-1,0)]



H,W = list(map(int,input().split()))

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



checked = [[0]*W for i in range(H)]



def bfs(si,sj):

    if grid[si][sj] == ".":

        b = 0; w = 1

    if grid[si][sj] == "#":

        b = 1; w = 0

    dq = deque()

    dq.append((si,sj))

    checked[si][sj] = 1

    while dq:

        i,j = dq.popleft()

        for di,dj in around:

            ni = i + di; nj = j + dj

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

                continue

            if checked[ni][nj]:

                continue

            p = grid[i][j]

            np = grid[ni][nj]

            if (p,np) == (".","#"):

                b += 1

                dq.append((ni,nj))

                checked[ni][nj] = 1

            if (p,np) == ("#","."):

                w += 1

                dq.append((ni,nj))

                checked[ni][nj] = 1

    return b*w



ans = 0

for i in range(H):

    for j in range(W):

        if not checked[i][j] and grid[i][j] == ".":

            ans += bfs(i,j)

print(ans)
import sys

sys.setrecursionlimit(10**6)
around = [(0, 1), (1, 0), (0, -1), (-1, 0)]
H, W = list(map(int, input().split()))
grid = [list(eval(input())) for _ in range(H)]
checked = [[0] * W for _ in range(H)]


def dfs(i, j):
    checked[i][j] = 1
    for di, dj in around:
        ni = i + di
        nj = j + dj
        if not (0 <= ni <= H - 1 and 0 <= nj <= W - 1):
            continue
        if checked[ni][nj]:
            continue
        p = grid[i][j]
        np = grid[ni][nj]
        if (p, np) == (".", "#"):
            global b
            b += 1
            dfs(ni, nj)
        if (p, np) == ("#", "."):
            global w
            w += 1
            dfs(ni, nj)


ans = 0
for i in range(H):
    for j in range(W):
        b = 0
        w = 1
        if not checked[i][j] and grid[i][j] == ".":
            dfs(i, j)
        ans += b * w
print(ans)

from collections import deque

around = [(0, 1), (1, 0), (0, -1), (-1, 0)]
H, W = list(map(int, input().split()))
grid = [list(eval(input())) for _ in range(H)]
checked = [[0] * W for i in range(H)]


def bfs(si, sj):
    if grid[si][sj] == ".":
        b = 0
        w = 1
    if grid[si][sj] == "#":
        b = 1
        w = 0
    dq = deque()
    dq.append((si, sj))
    checked[si][sj] = 1
    while dq:
        i, j = dq.popleft()
        for di, dj in around:
            ni = i + di
            nj = j + dj
            if not (0 <= ni <= H - 1 and 0 <= nj <= W - 1):
                continue
            if checked[ni][nj]:
                continue
            p = grid[i][j]
            np = grid[ni][nj]
            if (p, np) == (".", "#"):
                b += 1
                dq.append((ni, nj))
                checked[ni][nj] = 1
            if (p, np) == ("#", "."):
                w += 1
                dq.append((ni, nj))
                checked[ni][nj] = 1
    return b * w


ans = 0
for i in range(H):
    for j in range(W):
        if not checked[i][j] and grid[i][j] == ".":
            ans += bfs(i, j)
print(ans)

-import sys +from collections import deque -sys.setrecursionlimit(10**6) -checked = [[0] * W for _ in range(H)] +checked = [[0] * W for i in range(H)] -def dfs(i, j): -    checked[i][j] = 1 -    for di, dj in around: -        ni = i + di -        nj = j + dj -        if not (0 <= ni <= H - 1 and 0 <= nj <= W - 1): -            continue -        if checked[ni][nj]: -            continue -        p = grid[i][j] -        np = grid[ni][nj] -        if (p, np) == (".", "#"): -            global b -            b += 1 -            dfs(ni, nj) -        if (p, np) == ("#", "."): -            global w -            w += 1 -            dfs(ni, nj) +def bfs(si, sj): +    if grid[si][sj] == ".": +        b = 0 +        w = 1 +    if grid[si][sj] == "#": +        b = 1 +        w = 0 +    dq = deque() +    dq.append((si, sj)) +    checked[si][sj] = 1 +    while dq: +        i, j = dq.popleft() +        for di, dj in around: +            ni = i + di +            nj = j + dj +            if not (0 <= ni <= H - 1 and 0 <= nj <= W - 1): +                continue +            if checked[ni][nj]: +                continue +            p = grid[i][j] +            np = grid[ni][nj] +            if (p, np) == (".", "#"): +                b += 1 +                dq.append((ni, nj)) +                checked[ni][nj] = 1 +            if (p, np) == ("#", "."): +                w += 1 +                dq.append((ni, nj)) +                checked[ni][nj] = 1 +    return b * w -        b = 0 -        w = 1 -            dfs(i, j) -        ans += b * w +            ans += bfs(i, j)