#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e5 + 5;
const int MOD = 1e9 + 7;
int pot[MAX], x[MAX], y[MAX];
int n;
inline int add(int a, int b) {
  a += b;
  if (a >= MOD) {
    a -= MOD;
  }
  return a;
}
inline int mult(int a, int b) { return (1LL * a * b) % MOD; }
inline int sub(int a, int b) {
  a -= b;
  if (0 > a) {
    a += MOD;
  }
  return a;
}
map<int, vector<pair<int, int> > > by_x, by_y;
vector<int> adj[MAX];
bool visited[MAX];
void dfs(int source, set<int> &sx, set<int> &sy, int &P) {
  P++;
  visited[source] = true;
  sx.insert(x[source]);
  sy.insert(y[source]);
  for (auto &each : adj[source]) {
    if (!visited[each]) {
      dfs(each, sx, sy, P);
    }
  }
}
int main() {
  pot[0] = 1;
  for (int i = int(1); i < int(MAX); i++) {
    pot[i] = mult(pot[i - 1], 2);
  }
  scanf("%d", &n);
  for (int i = int(1); i < int(n + 1); i++) {
    scanf("%d %d", x + i, y + i);
    by_x[x[i]].emplace_back(y[i], i);
    by_y[y[i]].emplace_back(x[i], i);
  }
  for (auto &each : by_x) {
    sort(each.second.begin(), each.second.end());
    for (int i = int(1); i < int(each.second.size()); i++) {
      adj[each.second[i].second].push_back(each.second[i - 1].second);
      adj[each.second[i - 1].second].push_back(each.second[i].second);
    }
  }
  for (auto &each : by_y) {
    sort(each.second.begin(), each.second.end());
    for (int i = int(1); i < int(each.second.size()); i++) {
      adj[each.second[i].second].push_back(each.second[i - 1].second);
      adj[each.second[i - 1].second].push_back(each.second[i].second);
    }
  }
  int ans = 1;
  for (int i = int(1); i < int(n + 1); i++) {
    if (!visited[i]) {
      set<int> sx, sy;
      int P = 0;
      dfs(i, sx, sy, P);
      int L = sx.size() + sy.size();
      if (P >= L) {
        ans = mult(ans, pot[L]);
      } else {
        ans = mult(ans, sub(pot[L], 1));
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
