#include <bits/stdc++.h>
using namespace std;
struct ura {
  int costo, a, b;
};
bool operator<(const ura a, const ura b) { return a.costo < b.costo; }
int N;
int puntos[105][2];
ura aristas[100005];
int tam;
int padres[105][2];
int answer;
int Jefe(int x) {
  int i = padres[x][0];
  while (i != padres[i][0]) i = padres[i][0];
  return i;
}
int main() {
  scanf("%d", &N);
  for (int i = 1; i <= N; i++) {
    padres[i][0] = i;
    padres[i][1] = 1;
  }
  for (int i = 1; i <= N; i++) scanf(" %d %d", &puntos[i][0], &puntos[i][1]);
  for (int i = 1; i <= N; i++) {
    for (int j = i + 1; j <= N; j++) {
      aristas[++tam].a = i;
      aristas[tam].b = j;
      if (puntos[i][0] == puntos[j][0] || puntos[i][1] == puntos[j][1])
        aristas[tam].costo = 0;
      else
        aristas[tam].costo = 1;
    }
  }
  sort(aristas + 1, aristas + 1 + tam);
  int padre1, padre2;
  for (int i = 1; i <= tam; i++) {
    padre1 = Jefe(aristas[i].a);
    padre2 = Jefe(aristas[i].b);
    if (padre1 != padre2) {
      answer += aristas[i].costo;
      if (padres[padre1][1] < padres[padre2][1]) {
        padres[padre1][0] = padre2;
        padres[padre2][1] += padres[padre1][1];
      } else {
        padres[padre2][0] = padre1;
        padres[padre1][1] += padres[padre2][1];
      }
    }
  }
  printf("%d\n", answer);
  return 0;
}
