#include <bits/stdc++.h>
inline int nxt() {
  int aaa;
  scanf("%d", &aaa);
  return aaa;
}
using namespace std;
int row, col;
int visited[1100][1100];
vector<pair<int, int> > vec;
queue<pair<int, int> > q;
void right(int x, int y) {
  int i;
  for (i = x; i <= 1000; i++) {
    if (visited[i][y] == 2) {
      pair<int, int> v;
      v.first = i;
      v.second = y;
      q.push(v);
    } else
      visited[i][y] = 1;
  }
}
void left(int x, int y) {
  int i;
  for (i = x; i >= 1; i--) {
    if (visited[i][y] == 2) {
      pair<int, int> v;
      v.first = i;
      v.second = y;
      q.push(v);
    } else
      visited[i][y] = 1;
  }
}
void up(int x, int y) {
  int j;
  for (j = y; j <= 1000; j++) {
    if (visited[x][j] == 2) {
      pair<int, int> v;
      v.first = x;
      v.second = j;
      q.push(v);
    } else
      visited[x][j] = 1;
  }
}
void down(int x, int y) {
  int j;
  for (j = y; j >= 1; j--) {
    if (visited[x][j] == 2) {
      pair<int, int> v;
      v.first = x;
      v.second = j;
      q.push(v);
    } else
      visited[x][j] = 1;
  }
}
int main() {
  int i, snow, cnt = 0;
  snow = nxt();
  for (i = 0; i < snow; i++) {
    int x, y;
    x = nxt();
    y = nxt();
    pair<int, int> p1;
    p1.first = x;
    p1.second = y;
    vec.push_back(p1);
    visited[x][y] = 2;
  }
  for (i = 0; i < vec.size(); i++) {
    int temp1, temp2;
    temp1 = vec[i].first;
    temp2 = vec[i].second;
    if (visited[temp1][temp2] == 2) {
      visited[temp1][temp2] = 1;
      pair<int, int> p1;
      p1.first = temp1;
      p1.second = temp2;
      q.push(p1);
      cnt++;
      while (!q.empty()) {
        pair<int, int> u = q.front();
        q.pop();
        temp1 = u.first;
        temp2 = u.second;
        visited[temp1][temp2] = 1;
        up(temp1, temp2);
        down(temp1, temp2);
        left(temp1, temp2);
        right(temp1, temp2);
      }
    }
  }
  cout << cnt - 1 << endl;
}
