#include <bits/stdc++.h>
using namespace std;
inline int read() {
  register int res = 0, c, d = 0;
  while (c = getchar(), c < '0' || c > '9') d = (c == '-');
  do {
    res = (res << 3) + (res << 1) + (c ^ 48);
  } while (c = getchar(), c >= '0' && c <= '9');
  return d ? -res : res;
}
const int mod = 1000000007;
pair<pair<int, int>, int> P[100010];
vector<int> edge[100010];
inline bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B) {
  return A.first.second == B.first.second ? A.first.first < B.first.first
                                          : A.first.second < B.first.second;
}
inline bool cmp2(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B) {
  return A.second < B.second;
}
bool vis[100010], con;
set<int> X, Y;
void dfs(int now, int fa) {
  vis[now] = 1;
  X.insert(P[now].first.first);
  Y.insert(P[now].first.second);
  for (auto i : edge[now])
    if (i != fa) {
      if (vis[i])
        con = true;
      else
        dfs(i, now);
    }
}
int qpow(int n, int k) {
  int res = 1;
  while (k) {
    if (k & 1) res = 1ll * res * n % mod;
    n = 1ll * n * n % mod;
    k >>= 1;
  }
  return res;
}
int main() {
  int N = read();
  for (int i = 1; i <= N; i++)
    P[i].first.first = read(), P[i].first.second = read(), P[i].second = i;
  sort(P + 1, P + 1 + N);
  for (int i = 1; i < N; i++) {
    if (P[i].first.first == P[i + 1].first.first)
      edge[P[i].second].push_back(P[i + 1].second),
          edge[P[i + 1].second].push_back(P[i].second);
  }
  sort(P + 1, P + 1 + N, cmp);
  for (int i = 1; i < N; i++) {
    if (P[i].first.second == P[i + 1].first.second)
      edge[P[i].second].push_back(P[i + 1].second),
          edge[P[i + 1].second].push_back(P[i].second);
  }
  sort(P + 1, P + 1 + N, cmp2);
  int ans = 1;
  for (int i = 1; i <= N; i++)
    if (!vis[i]) {
      con = false;
      X.clear();
      Y.clear();
      dfs(i, 0);
      ans = 1ll * ans * (qpow(2, X.size() + Y.size()) - !con) % mod;
    }
  ans = (ans + mod) % mod;
  printf("%d\n", ans);
  return 0;
}
