#include <bits/stdc++.h>
const int p = 1e9 + 7;
int fpow(int x, int n) {
  int ret = 1;
  while (n) {
    if (n & 1) ret = 1ll * ret * x % p;
    x = 1ll * x * x % p;
    n /= 2;
  }
  return ret;
}
class UFS {
 private:
  int n, *fa, *siz;
  bool *cir;
  int find(int);

 public:
  UFS(int);
  void merge(int, int);
  int size(int);
  bool isroot(int);
  bool iscir(int);
};
UFS::UFS(int n) : n(n), fa(new int[n]), siz(new int[n]), cir(new bool[n]()) {
  for (int i = 0; i < n; ++i) {
    fa[i] = i;
    siz[i] = 1;
  }
}
int UFS::find(int x) {
  while (x != fa[x]) x = fa[x] = fa[fa[x]];
  return x;
}
void UFS::merge(int x, int y) {
  int u = find(x), v = find(y);
  if (u == v)
    cir[u] = true;
  else {
    fa[u] = v;
    siz[v] += siz[u];
    cir[v] |= cir[u];
  }
}
int UFS::size(int x) { return siz[x]; }
bool UFS::isroot(int x) { return x == find(x); }
bool UFS::iscir(int x) { return cir[x]; }
int decrease(int n, int *a) {
  std::vector<int> v;
  for (int i = 0; i < n; ++i) v.push_back(a[i]);
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(), v.end()), v.end());
  for (int i = 0; i < n; ++i)
    a[i] = std::lower_bound(v.begin(), v.end(), a[i]) - v.begin();
  return v.size();
}
int main() {
  int n;
  std::cin >> n;
  int *x = new int[n], *y = new int[n];
  std::vector<int> vx, vy;
  for (int i = 0; i < n; ++i) std::cin >> x[i] >> y[i];
  int mx = decrease(n, x), m = mx + decrease(n, y);
  UFS s(m);
  for (int i = 0; i < n; ++i) s.merge(x[i], mx + y[i]);
  int ans = 1;
  for (int i = 0; i < m; ++i)
    if (s.isroot(i)) ans = 1ll * ans * (fpow(2, s.size(i)) - (!s.iscir(i))) % p;
  std::cout << ans << std::endl;
  return 0;
}
