import java.io.BufferedReader

fun main() = aising2019c()

@OptIn(ExperimentalStdlibApi::class)
fun aising2019c() = SimpleIO_aising2019c().exec {
    val (h, w) = readLine().split(" ").map { it.toInt() }
    val board = Array(h) { readLine().map { it == '#' }.toBooleanArray() }

    val gridSize = h * w
    val uf = UnionFind(gridSize)
    fun toIndex(y: Int, x: Int) = y * w + x

    for (y in 0 until h) for (x in 0 until w) {
        if (x + 1 < w && board[y][x] != board[y][x + 1]) uf.unite(toIndex(y, x), toIndex(y, x + 1))
        if (y + 1 < h && board[y][x] != board[y + 1][x]) uf.unite(toIndex(y, x), toIndex(y + 1, x))
    }

    val blackCountByGroup = IntArray(gridSize)
    val whiteCountByGroup = IntArray(gridSize)

    for (y in 0 until h) for (x in 0 until w) {
        val groupRoot = uf.root(toIndex(y, x))
        if (board[y][x]) blackCountByGroup[groupRoot]++ else whiteCountByGroup[groupRoot]++
    }

    val answer = (0 until gridSize)
        .map { blackCountByGroup[it].toLong() * whiteCountByGroup[it] }.sum()

    println(answer)
}

private class UnionFind(initSize: Int) {
    private val parent = IntArray(initSize) { it }
    private val size = LongArray(initSize) { 1L }

    fun root(x: Int): Int {
        if (x == parent[x]) return x

        val xr = root(parent[x])
        parent[x] = xr
        return xr
    }

    fun unite(x: Int, y: Int) {
        val xr = root(x)
        val yr = root(y)
        if (xr == yr) return

        if (size[xr] >= size[yr]) {
            size[xr] += size[yr]
            parent[yr] = xr
        } else {
            size[yr] += size[xr]
            parent[xr] = yr
        }
    }

    fun isSame(x: Int, y: Int): Boolean = root(x) == root(y)

    fun unite(pair: Pair<Int, Int>): Unit = unite(pair.first, pair.second)
    fun isSame(pair: Pair<Int, Int>): Boolean = isSame(pair.first, pair.second)

    fun size(x: Int): Long = size[root(x)]
}

// region kokokara template dayo (^o^)
@Suppress("unused", "HasPlatformType", "MemberVisibilityCanBePrivate", "ClassName")
private class SimpleIO_aising2019c(private val separator: String = System.lineSeparator()) {
    private val br: BufferedReader = System.`in`.bufferedReader()
    private val sb: StringBuilder = StringBuilder()
    fun readLine(): String = br.readLine()!!
    fun println(): Unit = run { sb.append(separator) }
    fun print(any: Any): Unit = run { sb.append(any) }
    fun println(any: Any): Unit = print(any.toString() + separator)
    fun exec(action: SimpleIO_aising2019c.() -> Unit) = run {
        Thread(null, { action() }, "(^o^)", 128 * 1024 * 1024).apply { start() }.join()
    }.run { kotlin.io.print(sb) }
}
// endregion kokomade template dayo (^o^)
