#include <bits/stdc++.h>
using namespace std;
struct P {
  int x, y;
  bool operator<(const P &a) const { return y < a.y; };
};
int a, b, c, d, i, k, n, m, e, dx[10] = {1, 0, -1, 0, 1, 1, -1, -1},
                               dy[10] = {0, 1, 0, -1, 1, -1, 1, -1};
int o[200101], o1[200101];
int l[200141];
long long j[200041];
long long x, y, z, mod = 1000000007;
char r[3];
P u[100101];
queue<int> q;
set<int> s[2];
map<int, int> p[2];
vector<int> v[100];
bool as(P a, P b) { return a.y > b.y; }
int f(int n) {
  if (o[n] == n) return o[n] = n;
  return o[n] = f(o[n]);
}
int main() {
  j[0] = 1;
  for (int t = 1; t <= 200000; t++) j[t] = j[t - 1] * 2 % mod;
  scanf("%d", &a);
  x = 1;
  for (int t = 1; t <= a; t++) {
    scanf("%d %d", &n, &m);
    u[t] = {n, m};
    s[0].insert(n);
    s[1].insert(m);
  }
  for (int i = 0; i < 2; i++)
    for (set<int>::iterator w = s[i].begin(); w != s[i].end(); w++) {
      e++;
      p[i][*w] = e;
    }
  for (int t = 1; t <= a; t++) {
    u[t] = {p[0][u[t].x], p[1][u[t].y]};
  }
  iota(o + 1, o + e + 1, 1);
  for (int t = 1; t <= e; t++) l[t] = 1;
  for (int t = 1; t <= a; t++) {
    if (f(u[t].x) == f(u[t].y))
      o1[f(u[t].x)] = 1;
    else {
      l[f(u[t].x)] += l[f(u[t].y)];
      o1[f(u[t].x)] = max(o1[f(u[t].x)], o1[f(u[t].y)]);
      o[f(u[t].y)] = f(u[t].x);
    }
  }
  for (int t = 1; t <= e; t++)
    if (f(t) == t) {
      if (o1[t])
        x *= j[l[t]], x %= mod;
      else
        x *= (j[l[t]] - 1 + mod) % mod, x %= mod;
    }
  printf("%lld", x);
}
