#include <bits/stdc++.h>
using namespace std;
long long fast_exp(long long a, long long k, long long &q) {
  if (k == 0) return 1;
  return (k % 2 == 0) ? fast_exp((a * a) % q, k / 2, q)
                      : (a * fast_exp((a * a) % q, (k - 1) / 2, q)) % q;
}
int find1(int x, vector<int> &L) {
  return (L[x] == x) ? L[x] : L[x] = find1(L[x], L);
}
bool union1(int x, int y, vector<int> &L, vector<int> &S) {
  int fx = find1(x, L), fy = find1(y, L);
  if (fx == fy) return false;
  if (S[fx] < S[fy]) swap(fx, fy);
  L[fy] = fx;
  S[fx] += S[fy];
  return true;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int n;
  cin >> n;
  vector<pair<int, int> > V(n);
  vector<int> W1(n), W2(n);
  for (int i = 0; i < n; i++) {
    cin >> V[i].first >> V[i].second;
    W1[i] = V[i].first;
    W2[i] = V[i].second;
  }
  sort(W1.begin(), W1.end());
  sort(W2.begin(), W2.end());
  int e1 = unique(W1.begin(), W1.end()) - W1.begin(),
      e2 = unique(W2.begin(), W2.end()) - W2.begin();
  for (int i = 0; i < n; i++) {
    V[i].first =
        lower_bound(W1.begin(), W1.begin() + e1, V[i].first) - W1.begin();
    V[i].second =
        lower_bound(W2.begin(), W2.begin() + e2, V[i].second) - W2.begin() + e1;
  }
  vector<int> L(n), S(n, 1), M(e1 + e2, -1);
  for (int i = 0; i < n; i++) L[i] = i;
  bool f;
  for (int i = 0; i < n; i++) {
    (M[V[i].first] == -1) ? M[V[i].first] = i
                          : f = union1(i, M[V[i].first], L, S);
    (M[V[i].second] == -1) ? M[V[i].second] = i
                           : f = union1(i, M[V[i].second], L, S);
  }
  vector<bool> Leader(n, false);
  vector<vector<int> > Lines(n);
  for (int i = 0; i < n; i++) {
    int fi = find1(i, L);
    Leader[fi] = true;
    Lines[fi].push_back(V[i].first);
    Lines[fi].push_back(V[i].second);
  }
  long long ans = 1, cur, q = 1000000007;
  vector<long long> Sil(e1 + e2 + 1, 1), Rev_sil(e1 + e2 + 1, 1);
  for (int i = 2; i <= e1 + e2; i++) {
    Sil[i] = (Sil[i - 1] * i) % q;
    Rev_sil[i] = fast_exp(Sil[i], q - 2, q);
  }
  for (int i = 0; i < n; i++)
    if (Leader[i]) {
      sort(Lines[i].begin(), Lines[i].end());
      int l = unique(Lines[i].begin(), Lines[i].end()) - Lines[i].begin();
      cur = 0;
      for (int j = 0; j <= min(S[i], l); j++) {
        cur = (cur + ((Sil[l] * Rev_sil[j]) % q) * Rev_sil[l - j]) % q;
      }
      ans = (ans * cur) % q;
    }
  cout << ans << endl;
  return 0;
}
