#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const int INF = (1 << 30) - 1;
const int mod = (int)(1e9 + 7);
int n;
struct Point {
  int x, y, id;
} P[100010];
int fa[100010];
map<int, int> mp[100010][2];
int num[100010], pw[200010];
int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]); }
bool cmp(Point A, Point B) { return A.x < B.x; }
bool cmpy(Point A, Point B) { return A.y < B.y; }
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", &P[i].x, &P[i].y);
    P[i].id = i;
    fa[i] = i;
  }
  sort(P + 1, P + n + 1, cmp);
  int p = 1;
  for (int i = 2; i <= n; ++i) {
    if (P[i].x == P[p].x) {
      int x = Find(P[p].id);
      int y = Find(P[i].id);
      if (x != y) {
        fa[y] = x;
      }
    } else {
      p = i;
    }
  }
  sort(P + 1, P + n + 1, cmpy);
  p = 1;
  for (int i = 2; i <= n; ++i) {
    if (P[i].y == P[p].y) {
      int x = Find(P[p].id);
      int y = Find(P[i].id);
      if (x != y) {
        fa[y] = x;
      }
    } else {
      p = i;
    }
  }
  for (int i = 1; i <= n; ++i) {
    int ID = Find(P[i].id);
    mp[ID][0][P[i].x] = 1;
    mp[ID][1][P[i].y] = 1;
    num[ID]++;
  }
  int ans = 1;
  pw[0] = 1;
  for (int i = 1; i <= 200000; ++i) pw[i] = 2LL * pw[i - 1] % mod;
  for (int i = 1; i <= n; ++i)
    if (fa[i] == i) {
      int k = mp[i][0].size() + mp[i][1].size();
      if (k > num[i]) {
        ans = 1ll * ans * (pw[k] - 1) % mod;
      } else
        ans = 1ll * ans * pw[k] % mod;
    }
  printf("%d\n", ans);
  return 0;
}
