#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e6 + 10;
const ll M = 1e9 + 7;
ll pw[N];
ll n;
ll answer = 1;
ll first[N], second[N];
map<ll, vector<pair<ll, ll>>> bx, by;
vector<ll> g[N];
void edge(ll v, ll u) {
  g[v].push_back(u);
  g[u].push_back(v);
}
ll ecnt, vcnt, used[N];
set<ll> xs, ys;
void dfs(ll v) {
  xs.insert(first[v]);
  ys.insert(second[v]);
  used[v] = true;
  ++vcnt;
  ecnt += (ll)g[v].size();
  for (ll u : g[v]) {
    if (!used[u]) {
      dfs(u);
    }
  }
}
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  pw[0] = 1;
  for (ll i = 1; i < N; ++i) {
    pw[i] = pw[i - 1] * 2 % M;
  }
  cin >> n;
  for (ll i = 0; i < n; ++i) {
    cin >> first[i] >> second[i];
    bx[first[i]].emplace_back(first[i], i);
    by[second[i]].emplace_back(second[i], i);
  }
  for (auto t : bx) {
    auto v = t.second;
    sort(v.begin(), v.end());
    for (ll i = 0; i + 1 < (ll)v.size(); ++i) {
      edge(v[i].second, v[i + 1].second);
    }
  }
  for (auto t : by) {
    auto v = t.second;
    sort(v.begin(), v.end());
    for (ll i = 0; i + 1 < (ll)v.size(); ++i) {
      edge(v[i].second, v[i + 1].second);
    }
  }
  for (ll i = 0; i < n; ++i) {
    if (used[i]) {
      continue;
    }
    ecnt = 0;
    vcnt = 0;
    xs.clear();
    ys.clear();
    dfs(i);
    assert(ecnt % 2 == 0);
    ecnt /= 2;
    ll sum = (ll)(xs.size() + ys.size());
    if (ecnt == vcnt - 1) {
      (answer *= pw[sum] - 1) %= M;
    } else {
      (answer *= pw[sum]) %= M;
    }
  }
  cout << answer << "\n";
  return 0;
}
