#include <bits/stdc++.h>
using namespace std;
template <typename T>
bool chmax(T &m, const T &v) {
  if (v > m) return m = v, true;
  return false;
}
template <typename T>
bool chmin(T &m, const T &v) {
  if (v < m) return m = v, true;
  return false;
}
template <typename T>
bool chinc(T &v1, T &v2) {
  if (v1 > v2) return swap(v1, v2), true;
  return false;
}
template <typename T>
bool chdec(T &v1, T &v2) {
  if (v1 < v2) return swap(v1, v2), true;
  return false;
}
static const int HMAX32 = INT32_MAX / 2;
static const int HMIN32 = -HMAX32;
static const int64_t HMAX64 = INT64_MAX / 2;
static const int64_t HMIN64 = -HMAX64;
namespace fio {
template <typename T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
struct Cg {
  inline char operator()() { return (char)getchar(); }
};
struct Cp {
  inline void operator()(char x) { putchar(x); }
};
struct Cpe {
  inline void operator()(char x) { putc(x, stderr); }
};
inline bool IS(char x) { return x == 10 || x == 13 || x == ' '; }
template <typename T>
struct Fr {
  T P;
  inline Fr &operator,(int &x) {
    x = 0;
    char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (f) x = -x;
    return *this;
  }
  inline operator int() {
    int x;
    *this, x;
    return x;
  }
  inline Fr &operator,(long long &x) {
    x = 0;
    char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (f) x = -x;
    return *this;
  }
  inline operator long long() {
    long long x;
    *this, x;
    return x;
  }
  inline Fr &operator,(char &x) {
    for (x = P(); IS(x); x = P()) continue;
    return *this;
  }
  inline operator char() {
    char x;
    *this, x;
    return x;
  }
  inline Fr &operator,(char *x) {
    char t = P();
    for (; IS(t); t = P()) continue;
    if (~t) {
      for (; !IS(t) && ~t; t = P()) *x++ = t;
    }
    *x++ = 0;
    return *this;
  }
  inline Fr &operator,(double &x) {
    x = 0;
    char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (t == '.') {
      double u = 0.1;
      for (t = P(); t >= '0' && t <= '9'; t = P(), u *= 0.1) x += u * (t - '0');
    }
    if (f) x = -x;
    return *this;
  }
  inline operator double() {
    double x;
    *this, x;
    return x;
  }
  inline Fr &operator,(long double &x) {
    x = 0;
    char t = P();
    while ((t < '0' || t > '9') && t != '-') t = P();
    bool f = 0;
    if (t == '-') t = P(), f = 1;
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    if (t == '.') {
      double u = 0.1;
      for (t = P(); t >= '0' && t <= '9'; t = P(), u *= 0.1) x += u * (t - '0');
    }
    if (f) x = -x;
    return *this;
  }
  inline operator long double() {
    long double x;
    *this, x;
    return x;
  }
  inline Fr &operator,(unsigned int &x) {
    x = 0;
    char t = P();
    while (t < '0' || t > '9') t = P();
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    return *this;
  }
  inline operator unsigned int() {
    unsigned int x;
    *this, x;
    return x;
  }
  inline Fr &operator,(unsigned long long &x) {
    x = 0;
    char t = P();
    while (t < '0' || t > '9') t = P();
    x = t - '0';
    for (t = P(); t >= '0' && t <= '9'; t = P()) x = x * 10 + t - '0';
    return *this;
  }
  inline operator unsigned long long() {
    unsigned long long x;
    *this, x;
    return x;
  }
};
template <typename T>
struct Fw {
  T P;
  inline Fw &operator,(int x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      char s[10];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator()(int x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      char s[10];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator,(unsigned int x) {
    if (x) {
      char s[10];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator()(unsigned int x) {
    if (x) {
      char s[10];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator,(long long x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      char s[19];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator()(long long x) {
    if (x) {
      if (x < 0) P('-'), x = -x;
      char s[19];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator,(unsigned long long x) {
    if (x) {
      char s[20];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator()(unsigned long long x) {
    if (x) {
      char s[20];
      int c = 0;
      while (x) s[c++] = x % 10 + '0', x /= 10;
      while (c--) P(s[c]);
    } else
      P('0');
    return *this;
  }
  inline Fw &operator,(char x) {
    P(x);
    return *this;
  }
  inline Fw &operator()(char x) {
    P(x);
    return *this;
  }
  inline Fw &operator,(const char *x) {
    while (*x) P(*x++);
    return *this;
  }
  inline Fw &operator()(const char *x) {
    while (*x) P(*x++);
    return *this;
  }
  inline Fw &operator()(double x, int y) {
    if (y) {
      double t = 0.5;
      for (int i = y; i--;) t *= 0.1;
      if (x >= 0)
        x += t;
      else
        x -= t, P('-');
      *this, (long long)(abs(x));
      P('.');
      if (x < 0) x = -x;
      while (y--) {
        x *= 10;
        x -= floor(x * 0.1) * 10;
        P(((int)x) % 10 + '0');
      }
    } else if (x >= 0)
      *this, (long long)(x + 0.5);
    else
      *this, (long long)(x - 0.5);
    ;
    return *this;
  }
  inline Fw &operator()(long double x, int y) {
    if (y) {
      double t = 0.5;
      for (int i = y; i--;) t *= 0.1;
      if (x >= 0)
        x += t;
      else
        x -= t, P('-');
      *this, (long long)(abs(x));
      P('.');
      if (x < 0) x = -x;
      while (y--) {
        x *= 10;
        x -= floor(x * 0.1) * 10;
        P(((int)x) % 10 + '0');
      }
    } else if (x >= 0)
      *this, (long long)(x + 0.5);
    else
      *this, (long long)(x - 0.5);
    ;
    return *this;
  }
};
}  // namespace fio
fio::Fw<fio::Cp> fout;
fio::Fw<fio::Cpe> ferr;
fio::Fr<fio::Cg> fin;
template <typename Int>
Int gcd(Int a, Int b) {
  while (a != 0) {
    b %= a;
    if (b == 0) return a;
    a %= b;
  }
  return b;
}
template <typename Int, typename RInt = Int>
Int lcm(Int a, Int b) {
  return a / gcd(a, b) * static_cast<RInt>(b);
}
template <typename Int, typename XInt>
Int extended_gcd(Int a, Int b, XInt &x, XInt &y) {
  static_assert(std::numeric_limits<XInt>::is_signed, "x, y must be signed");
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  Int g = extended_gcd(b, a % b, y, x);
  y -= (a / b) * x;
  return g;
}
template <typename Int, typename TInt = int64_t>
Int mul_mod(Int a, Int b, Int m) {
  TInt p = a;
  p = (p * b) % m;
  return (Int)p;
}
template <typename Int, typename PInt, typename TInt = int64_t>
Int pow_mod(Int a, PInt p, Int m) {
  Int r;
  a %= m;
  for (r = 1; p; p >>= 1) {
    if (p & 1) r = mul_mod(r, a, m);
    a = mul_mod(a, a, m);
  }
  return r;
}
template <typename Int, typename XInt = typename std::make_signed<Int>::type>
Int inv_mod(Int a, Int m) {
  XInt x, y;
  extended_gcd(a, m, x, y);
  if (x < 0) return x + m;
  return x;
}
template <typename Int>
Int addx_mod(Int u, Int v, Int m) {
  Int r = u + v;
  if (r >= m) r -= m;
  return r;
}
template <typename Int>
Int subx_mod(Int u, Int v, Int m) {
  Int r = u - v;
  if (r < 0) r += m;
  return r;
}
template <typename Int>
Int div_mod(Int u, Int v, Int m) {
  Int g = gcd(v, m);
  assert(u % g == 0);
  Int mm = m / g;
  return mul_mod(u / g, inv_mod(v / g, mm), mm);
}
template <typename Int>
Int div_pos_r(Int a, Int b, Int &r) {
  Int q = a / b;
  r = a % b;
  if (r < 0) {
    if (b < 0)
      q += 1, r -= b;
    else
      q -= 1, r += b;
  }
  return q;
}
static const int MOD = 1000000007;
static const int maxn = 100005;
int n;
int pts[maxn][2];
bool visit[maxn * 2];
vector<int> g[maxn * 2];
pair<int, int> dfs(int u) {
  pair<int, int> ret = {1, (int)g[u].size()};
  visit[u] = true;
  for (int v : g[u])
    if (!visit[v]) {
      pair<int, int> p = dfs(v);
      ret.first += p.first;
      ret.second += p.second;
    }
  return ret;
}
int main() {
  fin, n;
  map<int, int> trans[2];
  for (int i = 0, iend = n; i < iend; i++) {
    fin, pts[i][0], pts[i][1];
    for (int j = 0, jend = 2; j < jend; j++) trans[j][pts[i][j]] = 0;
  }
  int cnt = 0;
  for (int j = 0, jend = 2; j < jend; j++) {
    for (auto &p : trans[j]) p.second = cnt++;
  }
  for (int i = 0, iend = n; i < iend; i++) {
    int x = trans[0][pts[i][0]];
    int y = trans[1][pts[i][1]];
    g[x].push_back(y);
    g[y].push_back(x);
  }
  int ans = 1;
  for (int i = 0, iend = cnt; i < iend; i++)
    if (!visit[i]) {
      pair<int, int> p = dfs(i);
      int vers = p.first;
      int edgs = p.second / 2;
      if (edgs == vers - 1) {
        (ans) = mul_mod((ans),
                        (subx_mod((pow_mod((2), (vers), MOD)), (1), MOD)), MOD);
      } else {
        (ans) = mul_mod((ans), (pow_mod((2), (vers), MOD)), MOD);
      }
    }
  fout, ans, '\n';
  return 0;
}
