#include <bits/stdc++.h>
using namespace std;
inline bool CI(int &_x) { return scanf("%d", &_x) == 1; }
inline bool CI(int &_x, int &_y) { return CI(_x) && CI(_y); }
inline bool CI(int &_x, int &_y, int &_z) { return CI(_x) && CI(_y) && CI(_z); }
inline bool CI(int &_x, int &_y, int &_z, int &_zz) {
  return CI(_x) && CI(_y) && CI(_z) && CI(_zz);
}
inline void wait(double seconds) {
  double endtime = clock() + (seconds * CLOCKS_PER_SEC);
  while (clock() < endtime) {
    ;
  }
}
const int mxn = 1005;
int N;
struct NODE {
  int x;
  int y;
} vi[105];
bool vis[105];
inline void read() {
  CI(N);
  int x, y;
  for (int i = 0, j1 = N; i < j1; ++i) {
    CI(x, y);
    vi[i] = NODE{x - 1, y - 1};
  }
}
inline void fillit(int j) {
  vis[j] = true;
  for (int i = 0, j1 = N; i < j1; ++i) {
    if (vis[i] == false && (vi[i].x == vi[j].x || vi[i].y == vi[j].y)) {
      fillit(i);
    }
  }
}
inline void proc() {
  int cnt = 0;
  int prothom = 0;
  memset(vis, false, sizeof(vis));
  for (int i = 0; i < N; ++i) {
    if (!vis[i]) {
      cnt += prothom;
      prothom = 1;
      fillit(i);
    }
  }
  cout << (cnt) << '\n';
}
int main() {
  read();
  proc();
  return 0;
}
