#include <bits/stdc++.h>
using namespace std;
long long int pw(long long int a, long long int b, long long int mod) {
  if (!b) return 1;
  if (b & 1) return a * pw(a * a % mod, b / 2, mod) % mod;
  return pw(a * a % mod, b / 2, mod) % mod;
}
const long long int N = 1e5 + 10;
const long long int MOD = 1e9 + 7;
const long long int INF = 1e18;
int n, A[N][2], mark[N], ans = 1;
vector<int> adj[N], vec[2], val[2][N];
set<int> st[2];
inline void add_edge(int u, int v) {
  adj[u].push_back(v);
  adj[v].push_back(u);
}
int DFS(int u, int p) {
  st[0].insert(A[u][0]);
  st[1].insert(A[u][1]);
  mark[u] = 1;
  int flag = 0;
  for (int v : adj[u])
    if (v != p) {
      flag |= mark[v];
      if (mark[v]) continue;
      flag |= DFS(v, u);
    }
  return flag;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> A[i][0] >> A[i][1];
    vec[0].push_back(A[i][0]);
    vec[1].push_back(A[i][1]);
  }
  for (int j = 0; j < 2; j++) {
    sort(vec[j].begin(), vec[j].end());
    vec[j].erase(unique(vec[j].begin(), vec[j].end()), vec[j].end());
    for (int i = 0; i < n; i++) {
      A[i][j] =
          lower_bound(vec[j].begin(), vec[j].end(), A[i][j]) - vec[j].begin();
      val[j][A[i][j]].push_back(i);
    }
    for (int i = 0; i < n; i++) {
      for (int k = 0; k + 1 < val[j][i].size(); k++) {
        add_edge(val[j][i][k], val[j][i][k + 1]);
      }
    }
  }
  for (int i = 0; i < n; i++)
    if (!mark[i]) {
      int flag = DFS(i, 0);
      int cnt = st[0].size() + st[1].size();
      ans = (long long int)ans * (pw(2, cnt, MOD) + MOD - 1 + flag) % MOD;
      st[0].clear();
      st[1].clear();
    }
  cout << ans << '\n';
  return 0;
}
