#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int x[maxn], y[maxn];
int solve(set<pair<int, int> >& sx, set<pair<int, int> >& sy) {
  set<pair<int, int> > X, Y;
  set<pair<int, int> >::iterator itx = sx.begin(), ity = sy.begin(), it, tmp;
  set<pair<int, int> >::reverse_iterator ritx = sx.rbegin(), rity = sy.rbegin(),
                                         rit, TMP;
  bool flag;
  for (int i = 0; i < sx.size() - 1; ++i) {
    flag = false;
    if (abs(itx->first - next(itx)->first) > 1) {
      flag = true;
      tmp = next(itx);
      for (it = sx.begin(); it != next(itx); ++it)
        X.insert({x[it->second], it->second});
    } else if (abs(ity->first - next(ity)->first) > 1) {
      flag = true;
      tmp = next(ity);
      for (it = sy.begin(); it != tmp; ++it)
        X.insert({x[it->second], it->second});
    } else if (abs(ritx->first - next(ritx)->first) > 1) {
      flag = true;
      TMP = next(ritx);
      for (rit = sx.rbegin(); rit != TMP; ++rit)
        X.insert({x[rit->second], rit->second});
    } else if (abs(rity->first - next(rity)->first) > 1) {
      flag = true;
      TMP = next(rity);
      for (rit = sy.rbegin(); rit != TMP; ++rit)
        X.insert({x[rit->second], rit->second});
    }
    if (flag) {
      for (pair<int, int> i : X) {
        Y.insert({y[i.second], i.second});
        sx.erase({x[i.second], i.second});
        sy.erase({y[i.second], i.second});
      }
      return (solve(X, Y) + solve(sx, sy));
    }
    ++itx;
    ++ity;
    ++ritx;
    ++rity;
  }
  return 1;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  set<pair<int, int> > sx, sy;
  for (int i = 0; i < n; ++i) {
    cin >> x[i] >> y[i];
    sx.insert({x[i], i});
    sy.insert({y[i], i});
  }
  cout << solve(sx, sy) << endl;
  return 0;
}
