#include using namespace std; class UnionFind { private: vector rank, p; int sz; public: UnionFind(int n) { rank.assign(n, 0); p.assign(n, 0); for (int i = 0; i < n; i++) p[i] = i; sz = n; } int find(int a) { if (p[a] == a) return a; return p[a] = find(p[a]); } int getNum() { return sz; } void unite(int a, int b) { int pa = find(a); int pb = find(b); if (pa == pb) return; if (rank[pa] == rank[pb]) { rank[pa]++; p[pb] = pa; } else if (rank[pa] > rank[pb]) { p[pb] = pa; }else { p[pa] = pb; } sz--; } }; int main() { int n; scanf("%d", &n); unordered_map xs; unordered_map ys; vector> pts(n); UnionFind uf(n); for (int i = 0; i < n; i++) { int a, b; scanf("%d %d", &a, &b); pts[i] = {a, b}; if (xs.find(a) != xs.end()) { uf.unite(xs[a], i); } else { xs[a] = i; } if (ys.find(b) != ys.end()) { uf.unite(ys[b], i); } else { ys[b] = i; } } printf("%d\n", uf.getNum() - 1); return 0; }