#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5 + 10, MOD = 1e9 + 7;
int n, x[MAX_N], y[MAX_N], ordered_x[MAX_N], ordered_y[MAX_N], x_n, y_n,
    ans = 1;
int fa[MAX_N * 2], node_cnt[MAX_N * 2], edge_cnt[MAX_N * 2];
void init() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &x[i], &y[i]);
    ordered_x[i] = x[i];
    ordered_y[i] = y[i];
  }
  sort(ordered_x + 1, ordered_x + n + 1);
  x_n = unique(ordered_x + 1, ordered_x + n + 1) - ordered_x - 1;
  for (int i = 1; i <= n; i++)
    x[i] = lower_bound(ordered_x + 1, ordered_x + x_n + 1, x[i]) - ordered_x;
  sort(ordered_y + 1, ordered_y + n + 1);
  y_n = unique(ordered_y + 1, ordered_y + n + 1) - ordered_y - 1;
  for (int i = 1; i <= n; i++)
    y[i] = lower_bound(ordered_y + 1, ordered_y + y_n + 1, y[i]) - ordered_y;
  for (int i = 1; i <= x_n + y_n; i++) fa[i] = i;
}
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void merge(int a, int b) { fa[find(a)] = find(b); }
void solve() {
  for (int i = 1; i <= n; i++) merge(x[i], x_n + y[i]);
  for (int i = 1; i <= x_n; i++) node_cnt[find(i)]++;
  for (int i = 1; i <= y_n; i++) node_cnt[find(x_n + i)]++;
  for (int i = 1; i <= n; i++) edge_cnt[find(x[i])]++;
  for (int i = 1; i <= x_n + y_n; i++) {
    if (fa[i] != i) continue;
    int fac = 1;
    for (int j = 1; j <= node_cnt[i]; j++) fac = fac * 2 % MOD;
    if (edge_cnt[i] < node_cnt[i]) fac--;
    ans = (long long)ans * fac % MOD;
  }
  printf("%d\n", ans);
}
int main() {
  init();
  solve();
}
