#include <bits/stdc++.h>
using namespace std;
map<int, vector<int> > mx;
map<int, vector<int> > my;
int pow(int x) {
  long long i = 2;
  long long r = 1;
  while (x) {
    if (x & 1) r = (r * i) % 1000000007;
    i = (i * i) % 1000000007;
    x = x >> 1;
  }
  return r;
}
int main() {
  ios::sync_with_stdio(false);
  int i, j, n, t;
  cin >> n;
  int x[n];
  int y[n];
  long long an = 1;
  for (i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    mx[x[i]].push_back(i);
    my[y[i]].push_back(i);
  }
  bool visit[i];
  memset(visit, 0, i);
  set<int> sx;
  set<int> sy;
  int c;
  queue<int> q;
  for (i = 0; i < n; i++)
    if (!visit[i]) {
      c = 0;
      sx.clear();
      sy.clear();
      for (j = 0; j < mx[x[i]].size(); j++) {
        c++;
        q.push(mx[x[i]][j]);
        visit[mx[x[i]][j]] = 1;
      }
      sx.insert(x[i]);
      for (j = 0; j < my[y[i]].size(); j++) {
        c++;
        q.push(my[y[i]][j]);
        visit[my[y[i]][j]] = 1;
      }
      sy.insert(y[i]);
      t = i;
      while (!q.empty()) {
        i = q.front();
        q.pop();
        if (sx.find(x[i]) == sx.end())
          for (j = 0; j < mx[x[i]].size(); j++) {
            c++;
            q.push(mx[x[i]][j]);
            visit[mx[x[i]][j]] = 1;
          }
        sx.insert(x[i]);
        if (sy.find(y[i]) == sy.end())
          for (j = 0; j < my[y[i]].size(); j++) {
            c++;
            q.push(my[y[i]][j]);
            visit[my[y[i]][j]] = 1;
          }
        sy.insert(y[i]);
      }
      i = t;
      if (c / 2 < sx.size() + sy.size())
        an = (an * (pow(sx.size() + sy.size()) + 1000000007 - 1)) % 1000000007;
      else
        an = (an * pow(sx.size() + sy.size())) % 1000000007;
    }
  cout << an;
  return 0;
}
