#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int MAXN = 1e5 + 5;
const int MAXM = 2e6 + 5;
const int MOD = 1e9 + 7;
int sgn(double x) {
  if (fabs(x) < eps) return 0;
  if (x < 0)
    return -1;
  else
    return 1;
}
long long pw(long long a, long long n, long long mod) {
  long long ret = 1;
  while (n) {
    if (n & 1) ret = ret * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return ret;
}
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
struct Node {
  int x, y, id;
} a[MAXN];
bool cmp1(Node a, Node b) { return a.x < b.x; }
bool cmp2(Node a, Node b) { return a.y < b.y; }
int n, fa[MAXN];
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
vector<int> ve[MAXN];
bool is[MAXN], cir[MAXN];
set<int> sx, sy;
int main() {
  scanf("%d", &n);
  int x, y;
  for (int i = 1; i < n + 1; i++) {
    scanf("%d%d", &x, &y);
    a[i] = Node{x, y, i};
    fa[i] = i;
  }
  sort(a + 1, a + 1 + n, cmp1);
  for (int i = 2; i < n + 1; i++) {
    if (a[i].x == a[i - 1].x) {
      fa[find(a[i - 1].id)] = find(a[i].id);
    }
  }
  sort(a + 1, a + 1 + n, cmp2);
  for (int i = 2; i < n + 1; i++) {
    if (a[i].y == a[i - 1].y) {
      if (find(a[i - 1].id) == find(a[i].id)) {
        is[a[i].id] = true;
      }
      fa[find(a[i - 1].id)] = find(a[i].id);
    }
  }
  for (int i = 1; i < n + 1; i++) {
    ve[find(a[i].id)].push_back(i);
    if (is[a[i].id]) cir[find(a[i].id)] = true;
  }
  long long ans = 1;
  for (int i = 1; i < n + 1; i++) {
    if (((int)(ve[i]).size())) {
      sx.clear();
      sy.clear();
      for (auto j : ve[i]) {
        sx.insert(a[j].x);
        sy.insert(a[j].y);
      }
      long long tmp = pw(2, ((int)(sx).size()) + ((int)(sy).size()), MOD);
      if (!cir[i]) tmp = (tmp - 1 + MOD) % MOD;
      ans = ans * tmp % MOD;
    }
  }
  printf("%lld\n", ans);
}
