import std;
import core.bitop;

ulong MAX = 100_100, MOD = 1_000_000_007, INF = 1_000_000_000_000;
alias sread = () => readln.chomp();
alias lread(T = long) = () => readln.chomp.to!(T);
alias aryread(T = long) = () => readln.split.to!(T[]);
alias Pair = Tuple!(long, "B", long, "W");
alias PQueue(T, alias less = "a>b") = BinaryHeap!(Array!T, less);

class UnionFind
{
    long n;
    long[] par;

    this(long init)
    {
        n = init;
        par = iota(n).array();
    }

    long root(long x)
    {
        if (par[x] == x)
            return x;
        else
            return par[x] = root(par[x]);
    }

    void unit(long x, long y)
    {
        if (root(x) != root(y))
            par[root(x)] = root(y);
    }

    bool same(long x, long y)
    {
        return (root(x) == root(y));
    }
}

void main()
{
    long h, w;
    scan(h, w);
    auto s = new string[](h);
    s.each!((ref x) => x = sread());

    long convIdx(long x, long y)
    {
        return x * w + y;
    }

    auto uf = new UnionFind(h * w);
    foreach (i; iota(h))
    {
        foreach (j; iota(w))
        {
            if (i - 1 >= 0 && s[i - 1][j] != s[i][j])
                uf.unit(convIdx(i - 1, j), convIdx(i, j));

            if (i + 1 < h && s[i + 1][j] != s[i][j])
                uf.unit(convIdx(i + 1, j), convIdx(i, j));

            if (j - 1 >= 0 && s[i][j - 1] != s[i][j])
                uf.unit(convIdx(i, j - 1), convIdx(i, j));

            if (j + 1 < w && s[i][j + 1] != s[i][j])
                uf.unit(convIdx(i, j + 1), convIdx(i, j));
        }
    }
    Pair[long] countBW;
    foreach (i; iota(h))
    {
        foreach (j; iota(w))
        {
            auto idx = uf.root(convIdx(i, j));
            auto p = Pair(s[i][j] == '#', s[i][j] == '.');
            if (idx in countBW)
                countBW[idx] = Pair(countBW[idx].B + p.B, countBW[idx].W + p.W);
            else
                countBW[idx] = p;
        }
    }

    long ans;
    foreach (key, value; countBW)
        ans += value.B * value.W;

    ans.writeln();
}

void scan(TList...)(ref TList Args)
{
    auto line = readln.split();
    foreach (i, T; TList)
    {
        T val = line[i].to!(T);
        Args[i] = val;
    }
}
