#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200010;
const int MOD = 1e9 + 7;
int read() {
  int x = 0, ch;
  while (isspace(ch = getchar()))
    ;
  do x = x * 10 + ch - '0';
  while (isdigit(ch = getchar()));
  return x;
}
int n;
map<int, int> idx, idy;
int nid;
namespace G {
int head[MAXN], nxt[MAXN], to[MAXN], m;
void init() { memset(head, -1, sizeof head); }
void adde(int u, int v) {
  to[m] = v, nxt[m] = head[u], head[u] = m++;
  to[m] = u, nxt[m] = head[v], head[v] = m++;
}
}  // namespace G
int fpow(int a, int b) {
  int c = 1;
  while (b) {
    if (b & 1) c = int(1LL * c * a % MOD);
    a = int(1LL * a * a % MOD);
    b >>= 1;
  }
  return c;
}
int vis[MAXN];
queue<int> q;
int solve(int s) {
  using namespace G;
  int e = 0, o = 0;
  vis[s] = 1, q.push(s);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    ++o;
    for (int i = head[u]; ~i; i = nxt[i], ++e)
      if (!vis[to[i]]) vis[to[i]] = 1, q.push(to[i]);
  }
  e >>= 1;
  return e == o - 1 ? (fpow(2, o) - 1 + MOD) % MOD : fpow(2, o);
}
int main() {
  n = read();
  G::init();
  for (int i = 0; i < n; ++i) {
    int x = read(), y = read();
    if (!idx[x]) idx[x] = ++nid;
    if (!idy[y]) idy[y] = ++nid;
    G::adde(idx[x], idy[y]);
  }
  int ans = 1;
  for (int i = 1; i <= nid; ++i)
    if (!vis[i]) ans = int(1LL * ans * solve(i) % MOD);
  printf("%d\n", ans);
  return 0;
}
