#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 4e5 + 10;
struct node {
  long long x, y, pos;
  node() {}
} a[N + 10], tmp[N + 10];
bool cmp1(node x, node y) { return x.x < y.x; }
bool cmp2(node x, node y) { return x.y < y.y; }
long long head[N], ver[M], nxt[M], tot = 0;
void add(long long x, long long y) {
  ver[++tot] = y;
  nxt[tot] = head[x];
  head[x] = tot;
}
bool vis[N];
long long cnt = 0;
map<long long, bool> xx, yy;
bool dfs(long long x, long long fa) {
  bool ans = 0;
  xx[tmp[x].x] = 1;
  yy[tmp[x].y] = 1;
  vis[x] = 1;
  for (long long i = head[x]; i; i = nxt[i]) {
    long long y = ver[i];
    if (y == fa) continue;
    if (vis[y]) {
      ans = 1;
      continue;
    }
    if (dfs(y, x)) ans = 1;
  }
  return ans;
}
const long long MOD = 1e9 + 7;
long long qpow(long long n) {
  long long ans = 1, base = 2;
  while (n) {
    if (n & 1) ans *= base, ans %= MOD;
    base *= base, base %= MOD;
    n >>= 1;
  }
  return ans;
}
signed main() {
  long long n;
  scanf("%lld", &n);
  for (long long i = 1; i <= n; i++) {
    scanf("%lld %lld", &a[i].x, &a[i].y);
    a[i].pos = i;
  }
  memcpy(tmp, a, sizeof(a));
  sort(a + 1, a + n + 1, cmp1);
  for (long long i = 1; i < n; i++)
    if (a[i].x == a[i + 1].x) {
      add(a[i].pos, a[i + 1].pos);
      add(a[i + 1].pos, a[i].pos);
    }
  sort(a + 1, a + n + 1, cmp2);
  for (long long i = 1; i < n; i++)
    if (a[i].y == a[i + 1].y) {
      add(a[i].pos, a[i + 1].pos);
      add(a[i + 1].pos, a[i].pos);
    }
  long long ans = 1;
  for (long long i = 1; i <= n; i++) {
    if (!vis[i]) {
      xx.clear();
      yy.clear();
      bool flag = dfs(i, 0);
      cnt = (long long)xx.size() + (long long)yy.size();
      if (flag)
        ans *= qpow(cnt);
      else
        ans *= qpow(cnt) - 1;
      ans %= MOD;
    }
  }
  printf("%lld", ans);
  return 0;
}
