#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define int ll
typedef long double ld;
typedef vector<int> vi;
#define vec vector

#define rep(i, a, b) for(int i = a; i < b; i++)
#define all(x) begin(x), end(x)
#define sz(x) (int)x.size()
#define setmin(x, y) x = min(x, y)
#define setmax(x, y) x = max(x, y)
#define ff first
#define ss second

vec<pair<vi, vi>> comp;
map<int, int> row, col;
int merge(int a, int b) {
	if(sz(comp[a].ff) + sz(comp[a].ss) < sz(comp[b].ff) + sz(comp[b].ss)) swap(a, b);

	for(int x : comp[b].ff) {
		comp[a].ff.push_back(x);
		if(row[x] != 0 && row[x] != b) {
			merge(row[x], a);
		}
		row[x] = a;
	}
	comp[b].ff.clear();

	for(int y : comp[b].ss) {
		comp[a].ss.push_back(y);
		if(col[y] != 0 && col[y] != b) {
			merge(col[y], a);
		}
		col[y] = a;
	}
	comp[b].ss.clear();

	return a;
}

signed main() {
	int n; cin >> n;
	comp.push_back({{}, {}});
	rep(i, 1, n + 1) {
		int ni = i;
		int x, y; cin >> x >> y;
		comp.push_back({{x}, {y}});
		if(row[x] != 0) {
			ni = merge(row[x], ni);
		}
		else if(col[y] != 0) {
			ni = merge(col[y], ni);
		}
		else {
			row[x] = ni;
			col[y] = ni;
		}
	}
	int res = 0;
	rep(i, 0, comp.size()) {
		if(comp[i].first.size()) res++;
	}
	cout << res - 1 << "\n";
}