#include <bits/stdc++.h>
using namespace std;
const int MaxN = 1e5 + 15;
const int MaxK = 20;
const int INF = 1e9 * 1ll * 1e9;
const int MOD = 1e9 + 7;
struct point {
  int x, y, num;
} a[MaxN];
bool used[MaxN];
vector<int> vx, vy;
int n;
vector<int> v[MaxN];
int ans;
int bpow(int a, int b) {
  if (!b) return 1;
  int res = bpow(a, b >> 1);
  res = (res * 1ll * res) % MOD;
  if (b & 1) res = (res * 1ll * a) % MOD;
  return res;
}
bool cmp1(point a, point b) {
  if (a.x < b.x) return true;
  if (a.x > b.x) return false;
  if (a.y < b.y) return true;
  if (a.y > b.y) return false;
  if (a.num < b.num) return true;
  if (a.num > b.num) return false;
}
bool cmp2(point a, point b) {
  swap(a.x, a.y);
  swap(b.x, b.y);
  if (a.x < b.x) return true;
  if (a.x > b.x) return false;
  if (a.y < b.y) return true;
  if (a.y > b.y) return false;
  if (a.num < b.num) return true;
  if (a.num > b.num) return false;
}
bool cmp3(point a, point b) { return a.num < b.num; }
bool dfs(int x, int p = 0) {
  used[x] = true;
  vx.push_back(a[x].x);
  vy.push_back(a[x].y);
  bool OK = false;
  for (int i = 0; i < v[x].size(); ++i) {
    int to = v[x][i];
    if (used[to] && to != p)
      OK = true;
    else if (!used[to]) {
      if (dfs(to, x)) OK = true;
    }
  }
  return OK;
}
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i].x >> a[i].y;
    a[i].num = i;
  }
  sort(a + 1, a + n + 1, cmp1);
  int l = 1;
  while (l <= n) {
    int r = l + 1;
    while (r <= n && a[r].x == a[l].x) ++r;
    for (int i = l + 1; i < r; ++i) {
      v[a[i].num].push_back(a[i - 1].num);
      v[a[i - 1].num].push_back(a[i].num);
    }
    l = r;
  }
  sort(a + 1, a + n + 1, cmp2);
  l = 1;
  while (l <= n) {
    int r = l + 1;
    while (r <= n && a[r].y == a[l].y) ++r;
    for (int i = l + 1; i < r; ++i) {
      v[a[i].num].push_back(a[i - 1].num);
      v[a[i - 1].num].push_back(a[i].num);
    }
    l = r;
  }
  sort(a + 1, a + n + 1, cmp3);
  int ans = 1;
  for (int i = 1; i <= n; ++i)
    if (!used[i]) {
      vx.clear();
      vy.clear();
      bool OK = dfs(i);
      sort(vx.begin(), vx.end());
      sort(vy.begin(), vy.end());
      vx.resize(unique(vx.begin(), vx.end()) - vx.begin());
      vy.resize(unique(vy.begin(), vy.end()) - vy.begin());
      int cur;
      if (OK)
        cur = bpow(2, vx.size() + vy.size());
      else
        cur = (bpow(2, vx.size() + vy.size()) - 1 + MOD) % MOD;
      ans = (ans * 1ll * cur) % MOD;
    }
  cout << ans << '\n';
  return 0;
}
