#include <bits/stdc++.h>
using namespace std;
int n;
map<int, int> mx;
map<int, int> my;
vector<pair<int, int> > v;
struct UF {
  vector<int> belong;
  vector<int> size;
  void resize(int n) {
    belong.assign(n + 1, -1);
    size.assign(n + 1, 1);
  }
  inline int root(int b) {
    if (belong[b] == -1) {
      return b;
    }
    belong[b] = root(belong[b]);
    return belong[b];
  }
  void merge(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b) return;
    belong[a] = b;
    size[b] += size[a];
  }
};
UF uf;
int node[200002];
long long int p2[200002];
int main() {
  p2[0] = 1;
  for (int i = 1; i < 200002; i++) {
    p2[i] = p2[i - 1];
    p2[i] *= 2LL;
    if (p2[i] >= 1000000007) {
      p2[i] %= 1000000007;
    }
  }
  cin >> n;
  for (int i = 0; i < n; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    mx[a] = 0;
    my[b] = 0;
    v.push_back(make_pair(a, b));
  }
  int id = 0;
  for (auto it = mx.begin(); it != mx.end(); it++) {
    (*it).second = id;
    id++;
  }
  for (auto it = my.begin(); it != my.end(); it++) {
    (*it).second = id;
    id++;
  }
  uf.resize(id);
  for (int i = 0; i < n; i++) {
    int x = mx[v[i].first];
    int y = my[v[i].second];
    uf.merge(x, y);
  }
  for (int i = 0; i < n; i++) {
    node[uf.root(mx[v[i].first])]++;
  }
  long long int way = 1;
  for (int i = 0; i < id; i++) {
    if (uf.root(i) == i) {
      int nodes = uf.size[i];
      int ed = node[i];
      if (nodes <= ed) {
        way *= p2[nodes];
      } else {
        way *= ((p2[nodes] + 1000000007 - 1) % 1000000007);
      }
      if (way >= 1000000007) {
        way %= 1000000007;
      }
    }
  }
  printf("%lld\n", way);
  return 0;
}
