#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
map<int, int> cx, cy;
map<int, map<int, int> > dx, dy;
map<int, map<int, int> > cnt;
map<int, map<int, int> > now;
map<int, map<int, pair<int, int> > > nxt;
int dp1[100010], dp2[100010];
int x[100010], y[100010];
long long gop[100010];
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d %d", &x[i], &y[i]);
    dx[x[i]][y[i]] = 1;
    dy[y[i]][x[i]] = 1;
    cnt[x[i]][y[i]] = 1;
  }
  gop[0] = 1;
  for (int i = 1; i <= 100001; i++) {
    gop[i] = gop[i - 1] << 1;
    gop[i] %= mod;
  }
  queue<int> qx, qy;
  for (int i = 0; i < n; i++) {
    if (dx[x[i]].size() == 1) {
      qx.push(x[i]);
      qy.push(y[i]);
    } else if (dy[y[i]].size() == 1) {
      qx.push(x[i]);
      qy.push(y[i]);
    }
  }
  long long ans = 1;
  while (qx.size()) {
    int tx = qx.front();
    int ty = qy.front();
    int tc = cnt[tx][ty];
    qx.pop();
    qy.pop();
    dx[tx].erase(ty);
    dy[ty].erase(tx);
    int nx;
    int ny;
    bool flag = false;
    if (dx[tx].size() == 1) {
      nx = tx;
      ny = (dx[tx].begin())->first;
      flag = true;
    } else if (dy[ty].size() == 1) {
      nx = (dy[ty].begin())->first;
      ny = ty;
      flag = true;
    } else if (dx[tx].size() == 0 && dy[ty].size() == 0) {
      ans *= gop[tc + 1] - 1;
      ans %= mod;
      cnt[tx][ty] = 0;
      continue;
    } else if (dx[tx].size() == 0) {
      nx = dy[ty].begin()->first;
      ny = ty;
    } else {
      nx = tx;
      ny = dx[tx].begin()->first;
    }
    if (flag) {
      qx.push(nx);
      qy.push(ny);
    }
    cnt[nx][ny] += tc;
    cnt[tx][ty] = 0;
    nxt[tx][ty] = {nx, ny};
  }
  for (int i = 0; i < n; i++) {
    int hx = x[i];
    int hy = y[i];
    vector<pair<int, int> > trace;
    int sx = hx, sy = hy;
    while (1) {
      trace.push_back({sx, sy});
      if (now[sx][sy] == 1) {
        for (auto &v : trace) now[v.first][v.second] = 1;
        break;
      } else if (now[sx][sy] == 2) {
        for (auto &v : trace) now[v.first][v.second] = 2;
        break;
      } else if (cnt[sx][sy]) {
        for (auto &v : trace) now[v.first][v.second] = 1;
        break;
      } else if (!nxt[sx].count(sy)) {
        for (auto &v : trace) now[v.first][v.second] = 2;
        break;
      }
      pair<int, int> tmp = nxt[sx][sy];
      sx = tmp.first;
      sy = tmp.second;
    }
    if (now[hx][hy] == 1) {
      cx[hx]++;
      cy[hy]++;
    }
  }
  ans *= gop[cx.size()];
  ans %= mod;
  ans *= gop[cy.size()];
  ans %= mod;
  printf("%lld\n", ans);
  return 0;
}
