#include <bits/stdc++.h>
using namespace std;
const int N = 100020, mo = 1e9 + 7;
int n, second[N], x, y, cnt, dfn[N], vis[N];
int dot[N], size;
int l[N], r[N];
long long ans = 1;
set<pair<int, int> > L[N], R[N];
struct Dot {
  int x, y;
} s[N];
inline void read(int &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = 10 * x + c - '0';
    c = getchar();
  }
  x *= f;
}
inline int LS() {
  sort(second + 1, second + n + 1);
  int l = 0;
  for (int i = 1; i <= n; i++)
    if (i == 1 || second[i] != second[i - 1]) second[++l] = second[i];
  return l;
}
inline void dfs(int u) {
  if (u > n || u < 1) return;
  vis[u] = cnt;
  dot[++size] = u;
  set<pair<int, int> >::iterator it = L[s[u].x].find(pair<int, int>(s[u].y, u));
  it++;
  if (!vis[(*it).second]) dfs((*it).second);
  it--;
  it--;
  if (!vis[(*it).second]) dfs((*it).second);
  it = R[s[u].y].find(pair<int, int>(s[u].x, u));
  it++;
  if (!vis[(*it).second]) dfs((*it).second);
  it--;
  it--;
  if (!vis[(*it).second]) dfs((*it).second);
}
inline int power(long long a, int n) {
  long long ans = 1;
  while (n) {
    if (n & 1) ans = (ans * a % mo);
    a = (a * a % mo);
    n >>= 1;
  }
  return ans;
}
int main() {
  read(n);
  for (int i = 1; i <= n; i++) read(s[i].x), read(s[i].y);
  for (int i = 1; i <= n; i++) second[i] = s[i].x;
  int X = LS();
  for (int i = 1; i <= n; i++)
    s[i].x = lower_bound(second + 1, second + X + 1, s[i].x) - second;
  for (int i = 1; i <= n; i++) second[i] = s[i].y;
  int Y = LS();
  for (int i = 1; i <= n; i++)
    s[i].y = lower_bound(second + 1, second + Y + 1, s[i].y) - second;
  vis[n + 1] = 1e9;
  for (int i = 1; i <= n; i++)
    L[i].insert(pair<int, int>(0, n + 1)),
        L[i].insert(pair<int, int>(n + 1, n + 1));
  for (int i = 1; i <= n; i++)
    R[i].insert(pair<int, int>(0, n + 1)),
        R[i].insert(pair<int, int>(n + 1, n + 1));
  for (int i = 1; i <= n; i++) {
    L[s[i].x].insert(pair<int, int>(s[i].y, i));
    R[s[i].y].insert(pair<int, int>(s[i].x, i));
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) {
      size = 0;
      cnt++;
      dfs(i);
      int num = 0;
      bool flag = 0;
      for (int j = 1; j <= size; j++) {
        if (l[s[dot[j]].x] || r[s[dot[j]].y]) flag = 1;
        num += (!l[s[dot[j]].x]) + (!r[s[dot[j]].y]);
        l[s[dot[j]].x] = 1;
        r[s[dot[j]].y] = 1;
      }
      int x = power(2, num);
      if (size < num) x--;
      if (x < 0) x += mo;
      ans = ans * x % mo;
    }
  printf("%lld", ans);
  return 0;
}
