#include <bits/stdc++.h>
using namespace std;
map<int, vector<pair<int, int> > > mx, my;
int x[100111], y[100111];
bool used[100111];
vector<int> adj[100111];
long long pw[2 * 100111];
set<int> pox, poy;
int vert, edge;
void DFS(int t) {
  vert++;
  used[t] = 1;
  pox.insert(x[t]);
  poy.insert(y[t]);
  for (int v : adj[t]) {
    edge++;
    if (!used[v]) DFS(v);
  }
}
int main() {
  pw[0] = 1LL;
  for (int i = 1; i < 2 * 100111; i++)
    pw[i] = (pw[i - 1] * 2LL) % (1000 * 1000 * 1000 + 7);
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", x + i, y + i);
    mx[x[i]].push_back(make_pair(y[i], i));
    my[y[i]].push_back(make_pair(x[i], i));
  }
  for (auto it = mx.begin(); it != mx.end(); it++) {
    vector<pair<int, int> > cur = it->second;
    sort(cur.begin(), cur.end());
    for (int i = 0; i < cur.size() - 1; i++) {
      adj[cur[i].second].push_back(cur[i + 1].second);
      adj[cur[i + 1].second].push_back(cur[i].second);
    }
  }
  for (auto it = my.begin(); it != my.end(); it++) {
    vector<pair<int, int> > cur = it->second;
    sort(cur.begin(), cur.end());
    for (int i = 0; i < cur.size() - 1; i++) {
      adj[cur[i].second].push_back(cur[i + 1].second);
      adj[cur[i + 1].second].push_back(cur[i].second);
    }
  }
  long long ans = 1;
  for (int i = 0; i < n; i++) {
    if (!used[i]) {
      vert = edge = 0;
      DFS(i);
      if (2 * vert == edge + 2)
        ans = (ans *
               ((pw[pox.size() + poy.size()] - 1 + (1000 * 1000 * 1000 + 7)) %
                (1000 * 1000 * 1000 + 7))) %
              (1000 * 1000 * 1000 + 7);
      else
        ans = (ans * pw[pox.size() + poy.size()]) % (1000 * 1000 * 1000 + 7);
      pox.clear();
      poy.clear();
    }
  }
  printf("%lld\n", ans);
  return 0;
}
