#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100010;
const int MOD = 1000000007;
inline int mul(int x, int y) { return (long long)x * (long long)y % MOD; }
inline int qpow(int a, int p) {
  int x = a, ans = 1;
  while (p) {
    if (p & 1) ans = mul(ans, x);
    x = mul(x, x);
    p >>= 1;
  }
  return ans;
}
int X[MAXN], Y[MAXN], N, Ans = 1;
namespace graph {
int head[MAXN], next[8 * MAXN], tail[8 * MAXN], id = 1;
inline void link(int u, int v) {
  tail[id] = v;
  next[id] = head[u];
  head[u] = id++;
}
int ncc = 0, ccid[MAXN];
bool ring[MAXN];
set<int> ccX[MAXN], ccY[MAXN];
void dfs(int u, int f) {
  int i, v;
  ccid[u] = ncc;
  ccX[ncc].insert(X[u]), ccY[ncc].insert(Y[u]);
  for (i = head[u]; i; i = next[i])
    if ((v = tail[i]) != f) {
      if (!ccid[v])
        dfs(v, u);
      else
        ring[ncc] = 1;
    }
}
void work() {
  int i, t;
  for (i = 1; i <= N; i++)
    if (!ccid[i]) {
      ncc++, dfs(i, 0);
      t = qpow(2, ccX[ncc].size() + ccY[ncc].size());
      if (!ring[ncc]) t--;
      Ans = mul(Ans, t);
    }
}
}  // namespace graph
map<int, int> MX[MAXN], MY[MAXN];
map<int, int>::iterator it;
map<int, int> IDX, IDY;
int NX = 1, NY = 1;
int main() {
  int i, x, y;
  scanf("%d", &N);
  for (i = 1; i <= N; i++) {
    scanf("%d%d", &X[i], &Y[i]);
    if (!IDX[X[i]]) IDX[X[i]] = NX++;
    if (!IDY[Y[i]]) IDY[Y[i]] = NY++;
    x = IDX[X[i]], y = IDY[Y[i]];
    MX[x][y] = i;
    MY[y][x] = i;
  }
  for (i = 1; i <= N; i++) {
    x = IDX[X[i]], y = IDY[Y[i]];
    it = MX[x].find(y);
    if (it != MX[x].begin()) it--, graph::link(i, it->second), it++;
    it++;
    if (it != MX[x].end()) graph::link(i, it->second);
    it = MY[y].find(x);
    if (it != MY[y].begin()) it--, graph::link(i, it->second), it++;
    it++;
    if (it != MY[y].end()) graph::link(i, it->second);
  }
  graph::work();
  printf("%d", Ans);
}
