#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC optimize("no-stack-protector,fast-math")
using namespace std;
const long long N = 5e5 + 100, OO = 1e9 + 7, K = 1e7 + 4, T = 22, M = 1e9 + 7,
                P = 6151, SQ = 1300, lg = 22;
pair<long long, long long> p[N];
vector<long long> vi, hi, v[N];
vector<pair<long long, long long> > vt[N], ht[N];
long long n, sz = 0, pw[N];
set<long long> sv, sh;
bool mark[N];
bool dfs(long long x, long long y) {
  mark[x] = true;
  sv.insert(p[x].first), sh.insert(p[x].second);
  bool k = false;
  for (auto u : v[x]) {
    if (u == y) continue;
    if (mark[u])
      k = true;
    else
      k |= dfs(u, x);
  }
  return k;
}
int32_t main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n;
  for (long long i = 1; i <= n; i++)
    cin >> p[i].first >> p[i].second, vi.push_back(p[i].first),
        hi.push_back(p[i].second);
  pw[0] = 1;
  for (long long i = 1; i <= 2 * n; i++) pw[i] = pw[i - 1] * 2 % M;
  sort(vi.begin(), vi.end());
  vi.resize(unique(vi.begin(), vi.end()) - vi.begin());
  sort(hi.begin(), hi.end());
  hi.resize(unique(hi.begin(), hi.end()) - hi.begin());
  for (long long i = 1; i <= n; i++) {
    p[i].first = lower_bound(vi.begin(), vi.end(), p[i].first) - vi.begin();
    p[i].second = lower_bound(hi.begin(), hi.end(), p[i].second) - hi.begin();
    vt[p[i].first].push_back({p[i].second, i});
    ht[p[i].second].push_back({p[i].first, i});
  }
  for (long long i = 0; i < n; i++) {
    sort(vt[i].begin(), vt[i].end());
    sort(ht[i].begin(), ht[i].end());
    for (long long j = 1; j < (long long)vt[i].size(); j++) {
      v[vt[i][j].second].push_back(vt[i][j - 1].second);
      v[vt[i][j - 1].second].push_back(vt[i][j].second);
    }
    for (long long j = 1; j < (long long)ht[i].size(); j++) {
      v[ht[i][j].second].push_back(ht[i][j - 1].second);
      v[ht[i][j - 1].second].push_back(ht[i][j].second);
    }
  }
  long long ans = 1;
  for (long long i = 1; i <= n; i++) {
    if (!mark[i]) {
      sv.clear(), sh.clear();
      long long cnt = 1 - dfs(i, 0);
      cnt = (pw[(long long)sv.size() + (long long)sh.size()] - cnt + M) % M;
      ans = (ans * cnt) % M;
    }
  }
  cout << ans << endl;
  return 0;
}
