#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)(1e5 + 11);
const long long inf = (long long)(1e9);
const int base = (int)(1e9 + 7);
const int mod = (int)(1e9 + 7);
const double eps = (double)(1e-9);
int n, timer;
long long deg[maxn];
pair<pair<int, int>, int> xy[maxn];
unordered_map<int, int> ux, uy, l, r, up, d;
unordered_map<long long, bool> id;
vector<int> g[maxn];
int used[maxn];
long long point(int x, int y) {
  if (!x) return 2 * inf * inf + y;
  return x * inf + y;
}
int cntx, cnty, cn, ce;
void dfs(int v, int p = -1) {
  if (ux[xy[v].first.first] != timer) cntx++;
  if (uy[xy[v].first.second] != timer) cnty++;
  ux[xy[v].first.first] = uy[xy[v].first.second] = timer;
  used[v] = timer;
  cn++;
  for (int i = 0; i < g[v].size(); ++i) {
    int to = g[v][i];
    if (used[to] == timer && to != p) ce = 1;
    if (used[to] == timer) continue;
    dfs(to, v);
  }
}
pair<pair<int, int>, int> a[maxn];
bool cmp(pair<pair<int, int>, int> a, pair<pair<int, int>, int> b) {
  return a.first.second < b.first.second;
}
int main() {
  ios_base ::sync_with_stdio(false);
  deg[0] = 1;
  for (int i = 1; i <= maxn; ++i) deg[i] = (deg[i - 1] * 2) % mod;
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> xy[i].first.first >> xy[i].first.second;
    xy[i].second = i;
    a[i] = xy[i];
  }
  sort(xy + 1, xy + n + 1);
  for (int i = 1; i <= n; ++i) {
    if (l.count(xy[i].first.second)) {
      if (!id[point(xy[i].second, l[xy[i].first.second])])
        g[xy[i].second].push_back(l[xy[i].first.second]);
      id[point(xy[i].second, l[xy[i].first.second])] = 1;
    }
    l[xy[i].first.second] = xy[i].second;
    int j = n - i + 1;
    if (r.count(xy[j].first.second)) {
      if (!id[point(xy[j].second, r[xy[j].first.second])])
        g[xy[j].second].push_back(r[xy[j].first.second]);
      id[point(xy[j].second, r[xy[j].first.second])] = 1;
    }
    r[xy[j].first.second] = xy[j].second;
  }
  sort(xy + 1, xy + n + 1, cmp);
  for (int i = 1; i <= n; ++i) {
    if (d.count(xy[i].first.first)) {
      if (!id[point(xy[i].second, d[xy[i].first.first])])
        g[xy[i].second].push_back(d[xy[i].first.first]);
      id[point(xy[i].second, d[xy[i].first.first])] = 1;
    }
    d[xy[i].first.first] = xy[i].second;
    int j = n - i + 1;
    if (up.count(xy[j].first.first)) {
      if (!id[point(xy[j].second, up[xy[j].first.first])])
        g[xy[j].second].push_back(up[xy[j].first.first]);
      id[point(xy[j].second, up[xy[j].first.first])] = 1;
    }
    up[xy[j].first.first] = xy[j].second;
  }
  for (int i = 1; i <= n; ++i) xy[i] = a[i];
  long long ans = 1;
  for (int i = 1; i <= n; ++i) {
    if (!used[i]) {
      timer++;
      cntx = cnty = cn = ce = 0;
      dfs(i);
      if (ce)
        ans = (ans * deg[cntx + cnty]) % mod;
      else
        ans = (ans * (deg[cntx + cnty] - 1 + mod) % mod) % mod;
    }
  }
  cout << ans;
  return 0;
}
