#include <bits/stdc++.h>
using namespace std;
inline long long ri() {
  long long x;
  scanf("%lld", &x);
  return x;
}
template <typename T>
inline bool smax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
inline bool smin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
struct mint {
  const static long long mod = 1e9 + 7;
  int x;
  mint() : x(0) {}
  mint(long long x) : x(((x % mod) + mod) % mod){};
  mint operator+=(const mint& a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint operator-=(const mint& a) {
    if ((x += mod - a.x) >= mod) x -= mod;
    return *this;
  }
  mint operator*=(const mint& a) {
    x = ((long long)x * a.x) % mod;
    return *this;
  }
  mint operator*(const mint& a) { return mint(*this) *= a; }
  mint operator-(const mint& a) { return mint(*this) -= a; }
  mint operator+(const mint& a) { return mint(*this) += a; }
  template <typename T>
  mint operator*(const T& a) {
    return mint(*this) *= a;
  }
  template <typename T>
  mint operator-(const T& a) {
    return mint(*this) -= a;
  }
  template <typename T>
  mint operator+(const T& a) {
    return mint(*this) += a;
  }
  template <typename T>
  friend mint operator*(T x, const mint& m) {
    return mint(x) *= m;
  }
  template <typename T>
  friend mint operator-(T x, const mint& m) {
    return mint(x) -= m;
  }
  template <typename T>
  friend mint operator+(T x, const mint& m) {
    return mint(x) += m;
  }
  bool operator==(const mint& a) const { return x == a.x; }
  operator long long() const { return x; }
};
mint pw(mint a, long long b) {
  mint res(1);
  while (b) {
    if (b & 1) res *= a;
    a *= a;
    b >>= 1;
  }
  return res;
}
mint inv(mint a) { return pw(a, mint::mod - 2); }
map<int, set<int>> gx, gy;
set<int> vx, vy;
int n;
bool ok = false;
set<int> v[2];
void dfs(int x, int p, int t) {
  v[t].insert(x);
  if (t == 0) vx.insert(x);
  auto& g = t ? gy : gx;
  auto& c = g[x];
  for (const int& i : c)
    if (i != p) {
      if (v[1 - t].find(i) != v[1 - t].end()) {
        ok = true;
      } else {
        dfs(i, x, t ^ 1);
      }
    }
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = 0; i < (n); i++) {
    int x, y;
    cin >> x >> y;
    gx[x].insert(y);
    gy[y].insert(x);
  }
  mint res = 1;
  for (auto& pr : gx) {
    if (!vx.count(pr.first)) {
      ok = false;
      v[0].clear();
      v[1].clear();
      dfs(pr.first, 1000000001, 0);
      if (ok)
        res *= pw(2, v[0].size() + v[1].size());
      else
        res *= pw(2, v[0].size() + v[1].size()) - 1;
    }
  }
  cout << res << endl;
  return 0;
}
