Language: C++

#pragma GCC optimize("Ofast")
#pragma GCC target("avx")
#include <bits/stdc++.h>
using namespace std;

#define INIT std::cin.tie(0);std::ios::sync_with_stdio(false);
#define ALL(c) (c).begin(), (c).end()
#define CALL(c) (c).cbegin(), (c).cend()
#define RALL(c) (c).rbegin(), (c).rend()
#define CRALL(c) (c).crbegin(), (c).crend()
#define REP(i, n) for (int i = 0; i < static_cast<int>(n); i++)
#define FOR(i, s, n) for (int i = s; i < static_cast<int>(n); i++)
#define ASC(t) [](t& x, t& y){ return x < y; }
#define DESC(t) [](t& x, t& y){ return x > y; }
#define PSORT(s,p,e) partial_sort((s), next((s), (p)), (e))
#define VIEW(v,t) for_each((v).begin(), (v).end(), [](t& a) { cout << a << " "; }); cout << endl;

#define IN(a, x, b) (a<=x && x<=b)
template<class T> inline T CHMAX(T& x, const T y){return x=(x<y)?y:x;}
template<class T> inline T CHMIN(T& x, const T y){return x=(x>y)?y:x;}
#define OUT(dist) std::cout<<(dist);
#define WS std::cout<<" ";
#define NL std::cout<<"\n"

using PII = pair<int, int>;
using PLL = pair<long long, long long>;
using LL = long long;
using ULL = unsigned long long;
template<class T> using V = vector<T>;
template<class T> using V2 = vector<vector<T>>;
template<class T, int W=255> using A = array<T, W>;
template<class T, int W=255, int H=255> using A2 = array<array<T, W>, W>;

template<int N=1000001>
struct UnionFindTree {
  LL cnt;
  A<LL, N> uftq{}, s{}, rank{};

  UnionFindTree() {
    cnt = N;
    FOR(i,0,N) { uftq[i] = i; s[i] = 1; rank[i] = 1; }
  }
  UnionFindTree(LL n) : cnt(n) {
    FOR(i,0,n) { uftq[i] = i; s[i] = 1; rank[i] = 1; }
  }
  LL find(LL x) {
      LL xParent = uftq[x];
      V<LL> v;
      while(xParent != uftq[xParent]) {
          v.push_back(xParent);
          xParent = uftq[xParent];
      }
      REP(i, v.size()) {
          uftq[v[i]] = xParent;
      }
      return xParent;
  }
  bool unite(LL x, LL y) {
      LL xRoot = find(x), yRoot = find(y);
      if(xRoot == yRoot) return false;
      if(rank[xRoot] > rank[yRoot])
          std::swap(xRoot, yRoot);
      if(rank[xRoot] == rank[yRoot])
          rank[yRoot] += 1 + rank[yRoot] - rank[xRoot];
      s[yRoot] = s[xRoot] + s[yRoot];
      s[xRoot] = 0;
      uftq[xRoot] = yRoot;
      cnt--;
      return true;
  }
  LL size(LL& idx) { return s[find(idx)]; }
  LL count() { return cnt; }
};

LL N;
int xt[100001];
int yt[100001];
set<int> xs[100001], ys[100001];
map<int,int> xm, ym;
UnionFindTree uft;

int main(){
    INIT;
    cin >> N; 
    REP(i,N) {
        cin >> xt[i] >> yt[i];
        if(xm.count(xt[i])) 
            uft.unite((LL)i,(LL)xm[xt[i]]);
        xm[xt[i]] = i;
        if(ym.count(yt[i])) 
            uft.unite((LL)i,(LL)ym[yt[i]]);
        ym[yt[i]] = i;
    }
    REP(i,N) {
        xs[uft.find((LL)i)].insert(xt[i]); 
        ys[uft.find((LL)i)].insert(yt[i]);
    }
    LL ans = 0;
    REP(i,N) ans += (LL)xs[i].size()*ys[i].size();
    cout << ans-N;
}

Compiler output:
In file included from /usr/include/c++/14/string:43,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52,
                 from a.cc:3:
/usr/include/c++/14/bits/allocator.h: In destructor 'std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_Rb_tree_impl<std::less<int>, true>::~_Rb_tree_impl()':
/usr/include/c++/14/bits/allocator.h:182:7: error: inlining failed in call to 'always_inline' 'std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = std::_Rb_tree_node<int>]': target specific option mismatch
  182 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/14/map:62,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:152:
/usr/include/c++/14/bits/stl_tree.h:658:16: note: called from here
  658 |         struct _Rb_tree_impl
      |                ^~~~~~~~~~~~~