#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << endl;
  err(++it, args...);
}
void faster() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
}
long long par[101];
long long root(long long n) {
  return (par[n] < 0) ? n : (par[n] = root(par[n]));
}
void merge(long long u, long long v) {
  if ((u = root(u)) == (v = root(v))) return;
  if (par[u] < par[v]) swap(u, v);
  par[v] += par[u];
  par[u] = v;
}
long long count_dis(long long n) {
  long long ans = 0;
  for (long long i = 0; i < n; i++)
    if (par[i] < 0) ans++;
  return ans;
}
void solve() {
  for (long long i = 0; i < 101; i++) par[i] = -1;
  long long n;
  cin >> n;
  vector<pair<long long, long long> > pts(n);
  for (long long i = 0; i < n; i++) cin >> pts[i].first >> pts[i].second;
  for (long long i = 0; i < n; i++) {
    for (long long j = i + 1; j < n; j++) {
      if (pts[i].first == pts[j].first || pts[i].second == pts[j].second)
        merge(i, j);
    }
  }
  cout << count_dis(n) - 1 << endl;
}
signed main() {
  faster();
  long long t = 1;
  while (t--) solve();
}
