#include <bits/stdc++.h>
using namespace std;
class Node {
 public:
  long long x;
  long long y;
  Node(long long x, long long y) {
    this->x = x;
    this->y = y;
  }
};
void dfs_visit(int u, int nVertices, int* color, int** matrix) {
  color[u] = 1;
  int v;
  for (int v = 0; v < nVertices; v++) {
    if (matrix[u][v] && color[v] == 0) {
      dfs_visit(v, nVertices, color, matrix);
    }
  }
  color[u] = 2;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long t, n, k;
  vector<pair<unordered_set<long long>, unordered_set<long long>>> a;
  cin >> n;
  vector<Node> nodes;
  int** m = new int*[n];
  for (int i = 0; i < n; ++i) m[i] = new int[n];
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < n; j++) {
      m[i][j] = 0;
    }
  }
  for (long long i = 0; i < n; i++) {
    long long x;
    long long y;
    cin >> x >> y;
    Node node(x, y);
    nodes.push_back(node);
  }
  for (long long i = 0; i < n; i++) {
    for (long long j = i + 1; j < n; j++) {
      if (nodes[i].x == nodes[j].x || nodes[i].y == nodes[j].y) {
        m[i][j] = 1;
        m[j][i] = 1;
      }
    }
  }
  int count = 0;
  int color[n];
  for (int i = 0; i < n; i++) {
    color[i] = 0;
  }
  for (int i = 0; i < n; i++) {
    if (color[i] == 0) {
      count++;
      dfs_visit(i, n, color, m);
    }
  }
  cout << count - 1;
  return 0;
}
