#include <bits/stdc++.h>
#pragma GCC optimaze("Ofast");
#pragma GCC optimize("unroll-loops")
using namespace std;
const int maxn = 1e5 + 113;
map<int, int> sw1, sw2;
vector<int> gr[maxn][2];
bool used[maxn][3];
void dfs(int v, int &l1, int &l2, bool &tr, int k, int p) {
  used[v][k] = 1;
  if (k == 1)
    l1++;
  else
    l2++;
  for (int i = 0; i < gr[v][k].size(); i++) {
    int to = gr[v][k][i];
    if (used[to][1 - k]) {
      if (to != p) tr = true;
    } else
      dfs(to, l1, l2, tr, 1 - k, v);
  }
}
const long long mod = 1e9 + 7;
void powmod(long long &a, long long x, long long p) {
  long long result = 1;
  while (x)
    if (!(x % 2))
      a = (a * a) % p, x /= 2;
    else
      result = (result * a) % p, x--;
  a = result;
}
signed main() {
  srand(time(NULL));
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n;
  cin >> n;
  vector<pair<int, int>> in;
  set<int> z1, z2;
  for (int i = 0; i < n; i++) {
    int a, b;
    cin >> a >> b;
    in.push_back({a, b});
    z1.insert(a);
    z2.insert(b);
  }
  int coe = 1;
  for (auto it : z1) sw1[it] = coe++;
  coe = 1;
  for (auto it : z2) sw2[it] = coe++;
  for (int i = 0; i < in.size(); i++) {
    in[i].first = sw1[in[i].first];
    in[i].second = sw2[in[i].second];
  }
  for (int i = 0; i < in.size(); i++) {
    gr[in[i].first][0].push_back(in[i].second);
    gr[in[i].second][1].push_back(in[i].first);
  }
  long long ans = 1;
  for (int i = 1; i <= sw1.size(); i++) {
    if (!used[i][0]) {
      int l1 = 0, l2 = 0;
      bool tr = false;
      dfs(i, l1, l2, tr, 0, -1);
      long long ans2 = 2;
      powmod(ans2, l1 + l2, mod);
      if (!tr) ans2--;
      ans = (ans * ans2) % mod;
    }
  }
  cout << ans;
}
