#include <bits/stdc++.h>
using namespace std;
const int MAXN = (int)1e5 + 40;
const long long MOD = (int)1e9 + 7;
struct pnt {
  int x, y, ind;
};
vector<int> g[MAXN];
vector<pnt> test(MAXN);
bool used[MAXN];
bool usedx[MAXN];
bool usedy[MAXN];
long long dfs_ans = 1;
set<int> stx;
set<int> sty;
long long t = 0;
long long cnt = 0;
long long cntv = 0;
void dfs(int u) {
  used[u] = 1;
  for (auto v : g[u])
    if (!used[v]) dfs(v);
  cnt += g[u].size();
  cntv++;
  if (stx.find(test[u].x) == stx.end()) dfs_ans = (dfs_ans * 2) % MOD;
  stx.insert(test[u].x);
  if (sty.find(test[u].y) == sty.end()) dfs_ans = (dfs_ans * 2) % MOD;
  sty.insert(test[u].y);
}
int main() {
  int n;
  cin >> n;
  vector<pnt> ps(n);
  for (int i = 0; i < n; i++) {
    cin >> ps[i].x >> ps[i].y;
    ps[i].ind = i;
    test[i] = ps[i];
  }
  sort(ps.begin(), ps.end(),
       [](pnt a, pnt b) { return a.x == b.x ? a.y < b.y : a.x < b.x; });
  for (int i = 1; i < n; i++) {
    if (ps[i - 1].x == ps[i].x) {
      g[ps[i - 1].ind].push_back(ps[i].ind);
      g[ps[i].ind].push_back(ps[i - 1].ind);
      usedx[ps[i - 1].ind] = 1;
      usedx[ps[i].ind] = 1;
    }
  }
  sort(ps.begin(), ps.end(),
       [](pnt a, pnt b) { return a.y == b.y ? a.x < b.x : a.y < b.y; });
  for (int i = 1; i < n; i++) {
    if (ps[i - 1].y == ps[i].y) {
      g[ps[i - 1].ind].push_back(ps[i].ind);
      g[ps[i].ind].push_back(ps[i - 1].ind);
      usedy[ps[i - 1].ind] = 1;
      usedy[ps[i].ind] = 1;
    }
  }
  long long ans = 1;
  for (int i = 0; i < n; i++)
    if (!used[i]) {
      dfs(i);
      ans = (ans * (dfs_ans - (cntv * 2 - 2 == cnt)) % MOD) % MOD;
      dfs_ans = 1;
      cnt = 0;
      cntv = 0;
    }
  cout << ans;
  return 0;
}
