#include <bits/stdc++.h>
#include <stdlib.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
typedef pair<ll,ll> P;
typedef priority_queue<P,vector<P>,greater<P>> P_queue;

#define REP(i,a,b) for(int i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)
#define pb push_back
#define mp make_pair
#define ALL(a) a.begin(),a.end()
#define SORT(a) sort(ALL(a))
#define U_ERASE(V) V.erase(unique(ALL(V)), V.end());

const ll MOD=998244353;
const ll mod=1000000007;
const ll INF=1e15;
vec dx={1,0,-1,0};
vec dy={0,1,0,-1};

ll d[401][401];

const ll MAXN=200001;

ll par[MAXN];
ll rnk[MAXN];
ll Size[MAXN];

vec D(MAXN,-1);

ll Co[MAXN][2];

void shoki(){
    for(ll i=0;i<MAXN;i++) {par[i]=i; rnk[i]=0; Size[i]=1;}
}

ll sch(ll x){
    if(par[x]==x) return x;
    else return par[x]=sch(par[x]);
}

void con(ll A,ll B){
    A=sch(A);
    B=sch(B);
    if(A==B) return;
    if(rnk[A]>rnk[B]) swap(A,B);
    par[A]=B;
    Size[B]+=Size[A];
    Size[A]=Size[B];
    if(rnk[A]==rnk[B]) rnk[B]++;

    return;
}

ll is_size(ll k){
    return Size[sch(k)];
}

bool same(ll A,ll B){
    return sch(A)==sch(B);
}

int main(){
    shoki();
    rep(i,401) rep(j,401) d[i][j]=INF;
    ll H,W; cin>>H>>W;
    rep(i,H){
        string S; cin>>S;
        rep(j,W){
            if(S.at(j)=='#') d[i][j]=1;
            else d[i][j]=0;
            D.at(i*450+j)=d[i][j];
        }
    }

    rep(i,H) rep(j,W){
        if(i!=H-1){
            if(d[i][j]!=d[i+1][j]) con(i*450+j,(i+1)*450+j); 
        }

        if(j!=W-1){
            if(d[i][j]!=d[i][j+1]) con(i*450+j,i*450+j+1); 
        }
    }
    rep(i,H) rep(j,W){
        ll x=i*450+j;
        //cout<<sch(x)<<endl;
        Co[sch(x)][D.at(x)]++;
    }
    ll ans=0;
    rep(i,H) rep(j,W){
        ll x=i*450+j;
       // cout<<Co[x][0]<<' '<<Co[x][1]<<endl;
        ans+=Co[x][0]*Co[x][1];
    }
    cout<<ans<<endl;

    




}
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repr(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define FORR(i, m, n) for (int i = (m); i >= (n); --i)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll mod = 1000000007;
//const ll mod = 998244353;
const int inf = 1e9 + 10;
const ll INF = 1e18;
const ld EPS = 1e-10;
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

int h, w;
vector<string> s;

vector<int> G[160160];
bool visited[160160];

vector<ll> cnt;

void dfs(int v) {
  if (visited[v]) return;
  visited[v] = true;
  if (s[v / w][v % w] == '#') cnt[0]++;
  else cnt[1]++;
  for (int u: G[v]) {
    dfs(u);
  }
}

int main() {
  cin >> h >> w;
  s.resize(h);
  rep(i, h) cin >> s[i];

  rep(i, h) {
    rep(j, w) {
      rep(k, 4) {
        int ry = i + dy[k], rx = j + dx[k];
        if (ry < 0 || ry >= h || rx < 0 || rx >= w) continue;
        if (s[i][j] != s[ry][rx]) {
          G[i * w + j].push_back(ry * w + rx);
        }
      }
    }
  }
  ll ans = 0;
  rep(i, h) {
    rep(j, w) {
      if (visited[i * w + j]) continue;
      cnt = vector<ll>(2, 0);
      dfs(i * w + j);
      ans += cnt[0] * cnt[1];
    }
  }
  cout << ans << endl;


  
  return 0;
}