Language: C++

#include <bits/stdc++.h>
#define REP(i, n) for(ll i = 0; i < (ll)n; i++)
#define FOR(i, a, b) for(ll i = (a); i < (ll)b; i++)
#define ALL(obj) (obj).begin(), (obj).end()
#define INF (1ll << 60)
#define sz(x) int(x.size())
using namespace std;
typedef long long ll;
using vl = vector<ll>;
using vvl = vector<vl>;
typedef double db;
typedef string str;
typedef pair<ll, ll> p;
constexpr int MOD = 1000000007;
using ll = long long;
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

void print(const std::vector<int> &v) {
    std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; });
    std::cout << std::endl;
}
class UnionFind {
  private:
    vector<int> parent;
    vector<int> height;
    vector<int> m_size;

  public:
    UnionFind(int size_) : parent(size_), height(size_, 0), m_size(size_, 1) {
        for(int i = 0; i < size_; ++i)
            parent[i] = i;
    }
    void init(int size_) {
        parent.resize(size_);
        height.resize(size_, 0);
        m_size.resize(size_, 0);
        for(int i = 0; i < size_; ++i)
            parent[i] = i;
    }
    int find(int x) {
        if(parent[x] == x)
            return x;
        return parent[x] = find(parent[x]);
    }
    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if(x == y)
            return;
        int t = size(x) + size(y);
        m_size[x] = m_size[y] = t;
        if(height[x] < height[y])
            parent[x] = y;
        else
            parent[y] = x;
        if(height[x] == height[y])
            ++height[x];
    }
    bool same(int x, int y) { return find(x) == find(y); }
    int size(int x) {
        if(parent[x] == x)
            return m_size[x];
        return size(parent[x] = find(parent[x]));
    }
};

int main() {
    int H, W;
    cin >> H >> W;
    vector<string> S(H);
    REP(i, H) { cin >> S[i]; }
    UnionFind tree(H * W);
    //白黒の順番の連結成分を探す
    REP(i.H) {
        REP(j, W - 1) {
            if(S[i][j] != S[i][j + 1]) {
                tree.unite(W * i + j, W * i + j + 1);
            }
        }
    }
    REP(j.W) {
        REP(i, H - 1) {
            if(S[i][j] != S[i + 1][j]) {
                tree.unite(W * i + j, W * (i + 1) + j);
            }
        }
    }
    set<int> p;
    REP(i, H) {
        REP(j, W) { p.insert(tree.find(i * W + j)) }
    }
    ll ans = 0;
    for(auto now : p) {
        int hoge = tree.size(now);
        if(hoge % 2 == 0) {
            ans += hoge * hoge / 4;
        } else {
            ans += (hoge + 1) * (hoge - 1) / 4;
        }
    }
    cout << ans << endl;
    return 0;
}

Compiler output:
a.cc:87:12: error: macro "REP" requires 2 arguments, but only 1 given
   87 |     REP(i.H) {
      |            ^
a.cc:2:9: note: macro "REP" defined here
    2 | #define REP(i, n) for(ll i = 0; i < (ll)n; i++)
      |         ^~~
a.cc:94:12: error: macro "REP" requires 2 arguments, but only 1 given
   94 |     REP(j.W) {
      |            ^
a.cc:2:9: note: macro "REP" defined here
    2 | #define REP(i, n) for(ll i = 0; i < (ll)n; i++)
      |         ^~~
a.cc: In function 'int main()':
a.cc:87:5: error: 'REP' was not declared in this scope
   87 |     REP(i.H) {
      |     ^~~
a.cc:94:8: error: expected ';' before '{' token
   94 |     REP(j.W) {
      |        ^     ~
      |        ;
a.cc:103:51: error: expected ';' before '}' token
  103 |         REP(j, W) { p.insert(tree.find(i * W + j)) }
      |                                                   ^~
      |                                                   ;