#include <bits/stdc++.h>
using namespace std;
struct UFDS {
  int n;
  vector<int> sz, par;
  void init(int x) {
    n = x;
    par.resize(n + 5);
    sz.resize(n + 5, 1);
    iota(par.begin(), par.end(), 0);
  }
  int find(int v) { return par[v] == v ? v : par[v] = find(par[v]); }
  bool join(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b) return false;
    if (sz[a] < sz[b]) swap(a, b);
    par[b] = a;
    sz[a] += sz[b];
    return true;
  }
  int non_connected() {
    set<int> s;
    for (int i = 0; i <= n - 1; i++) {
      s.insert(find(i));
    }
    return s.size();
  }
};
int main() {
  int n;
  cin >> n;
  UFDS u;
  u.init(n);
  vector<pair<int, int>> v(n);
  for (int i = 0; i <= n - 1; i++) cin >> v[i].first >> v[i].second;
  for (int i = 0; i <= n - 1; i++) {
    for (int j = 0; j <= n - 1; j++) {
      if (i != j &&
          ((v[i].first == v[j].first) || (v[i].second == v[j].second))) {
        u.join(i, j);
      }
    }
  }
  cout << u.non_connected() - 1;
  return 0;
}
