#include <bits/stdc++.h>
using namespace std;
const int MAXN = 110;
const int MAXM = 20010;
struct node {
  int to, next;
} edges[MAXM];
int box[MAXN], size;
int n, x[MAXN], y[MAXN];
bool flag[MAXN];
void dfs(int x, int father) {
  flag[x] = true;
  for (int i = box[x]; i != -1; i = edges[i].next) {
    int ne = edges[i].to;
    if (ne == father) continue;
    if (!flag[ne]) dfs(ne, x);
  }
}
void solve() {
  int cnt = 0;
  memset(flag, false, sizeof(flag));
  for (int i = 0; i < n; ++i)
    if (!flag[i]) dfs(i, -1), cnt++;
  cout << cnt - 1 << endl;
}
void inline add(int from, int to) {
  edges[size].to = to;
  edges[size].next = box[from];
  box[from] = size++;
}
int main() {
  scanf("%d", &n);
  memset(box, -1, sizeof(box)), size = 0;
  for (int i = 0; i < n; ++i) scanf("%d %d", &x[i], &y[i]);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j)
      if (i != j && (x[i] == x[j] || y[i] == y[j])) add(i, j);
  solve();
  return 0;
}
