#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using AR2 = array<int, 2>;
constexpr int MOD{1000000000 + 7};
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
constexpr int dx[4]{1, 0, -1, 0};
constexpr int dy[4]{0, 1, 0, -1};
constexpr int div_roundup(int a, int b)
{
    return (a + b - 1) / b;
}
// vector<vector<int>> vec(n_rows, vector<int>(n_cols, value));
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(0);

    int h, w;
    cin >> h >> w;
    vector<string> m(h);
    for (string &s : m)
        cin >> s;

    vector<vector<bool>> used(h, vector<bool>(w, false));

    ll pattern = 0;

    rep(i, h)
        rep(j, w)
    {
        if (used[i][j])
            continue;
        used[i][j] = true;

        queue<array<int, 2>> sqs;
        sqs.push({i, j});
        int n_black = 0, n_white = 0;

        if (m[i][j] == '#')
            n_black++;
        else if (m[i][j] == '.')
            n_white++;

        while (!sqs.empty())
        {
            const int i = sqs.front()[0], j = sqs.front()[1];
            sqs.pop();
            rep(k, 4)
            {
                const int ii = i + dx[k], jj = j + dy[k];
                if (ii < 0 || ii >= h || jj < 0 || jj >= w)
                    continue;

                if (used[ii][jj])
                    continue;

                if (m[i][j] == '#' && m[ii][jj] == '.')
                {
                    sqs.push({ii, jj});
                    used[ii][jj] = true;
                    n_white++;
                }
                else if (m[i][j] == '.' && m[ii][jj] == '#')
                {
                    sqs.push({ii, jj});
                    used[ii][jj] = true;
                    n_black++;
                }
            }
        }
        pattern += (ll)n_black * n_white;
    }

    cout << pattern << endl;

    // rep(i, h)
    //     rep(j, w)
    // {
    //     if (m[i][j] == '#')
    //         black_sqs.push({i, j});
    // }

    // int patterns = 0;
    // while (!black_sqs.empty())
    // {
    //     queue<array<int, 2>> sqs;
    //     sqs.push({black_sqs.front()});
    //     black_sqs.pop();

    //     vector<vector<bool>> m2(h, vector<bool>(w, false));
    //     m2[sqs.front().at(0)][sqs.front().at(1)] = true;

    //     while (!sqs.empty())
    //     {
    //         const int i = sqs.front()[0], j = sqs.front()[1];
    //         sqs.pop();

    //         bool is_black;
    //         if (m[i][j] == '#')
    //             is_black = true;
    //         else
    //             is_black = false;

    //         rep(k, 4)
    //         {
    //             const int ii = i + dx[k], jj = j + dy[k];
    //             if (ii < 0 || ii >= h || jj < 0 || jj >= w)
    //                 continue;

    //             if (m2[ii][jj])
    //                 continue;

    //             if (is_black && m[ii][jj] == '.')
    //             {
    //                 sqs.push({ii, jj});
    //                 m2[ii][jj] = true;
    //                 patterns++;
    //             }
    //             else if (!is_black && m[ii][jj] == '#')
    //             {
    //                 sqs.push({ii, jj});
    //                 m2[ii][jj] = true;
    //             }
    //         }
    //     }
    // }
}


Measured memory_bytes: 512