#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;
#define P 1000000007
#define N_MAX 1000000
typedef long long int ll;

ll fac[N_MAX+1], inv[N_MAX+1], finv[N_MAX+1];
void init(){
  fac[0] = finv[0] = fac[1] = finv[1] = inv[1] = 1;
  for(int i = 2; i <= N_MAX; i++){
    fac[i] = (fac[i-1]*i)%P;
    inv[i] = ((-(P/i)*inv[P%i])%P+P)%P;
    finv[i] = (finv[i-1]*inv[i])%P;
  }
}

struct segtree{
  int M=1, INF = 1000000007, INIT;
  vector<vector<int>> dat;
  segtree(ll N, int num){
    INIT = num;
    while(M<N) M*=2;
    dat.resize(M*2-1, vector<int>{num, -1});
  }
  void update(int x, int k, ll l=0, ll r=-1){
    if(r==-1) r = M;
    k+=M-1;
    dat[k] = vector<int>{x, k-(M-1)};
    while(k>0) {
      k = (k-1)/2;
      dat[k] = min(dat[k*2+1], dat[k*2+2]);
    }
  }
  vector<int> query(ll a, ll b=-1, ll k=0, ll l=0, ll r=-1){
    if(r==-1) r = M;
    if(b==-1) b = M;
    if(r<=a || b<=l) return vector<int>{INIT, -INIT};
    if(a<=l && r<=b) return dat[k];
    vector<int> A = query(a, b, k*2+1, l, (l+r)/2);
    vector<int> B = query(a, b, k*2+2, (l+r)/2, r);
    return min(A, B);
  }
};

struct UF{
  std::vector<int> par, dep, sz;
  UF(int n){
    par.resize(n+1), dep.resize(n+1), sz.resize(n+1);
    init(n);
  }
  void init(int nu) {
    for(int iu=0;iu<=nu;iu++){
      par[iu] = iu;
      dep[iu] = 0;
      sz[iu] = 1;
    }
  }
  int find(int xu){
    if(par[xu] == xu) return xu;
    return par[xu] = find(par[xu]);
  }
  void unite(int xu, int yu){
    xu=find(xu);
    yu=find(yu);
    if(xu == yu) return;
    if(dep[xu] < dep[yu]){
      sz[yu] += sz[xu];
      par[xu] = yu;
    }else{
      par[yu] = xu;
      sz[xu] += sz[yu];
      if(dep[xu] == dep[yu]) dep[xu]++;
    }
  }
  bool same(int xu, int yu){ return find(xu) == find(yu);}
  int get_size(int x){return sz[find(x)];}
};

int main(int argc, char const *argv[]) {
  init();
  ll n, x, y;std::cin >> n >> x >> y;
  ll INF = 1000000007;
  vector<int> minC(n+1, INF), mindex(n+1, INF);
  vector<vector<int>> d(n, vector<int>(2));
  //ll m = INF;
  UF uf(n+1);
  vector<vector<int>> C(n+1, vector<int>(0));
  segtree seg(n+1, INF);
  for(int i=0;i<n;i++){
    scanf("%d %d", &d[i][0], &d[i][1]);
    minC[d[i][0]] = min(minC[d[i][0]], d[i][1]);
  }
  for(int i=0;i<n;i++){
    ll c = d[i][0], num = d[i][1];
    C[c].push_back(i);
    if(minC[c]==num) {
      seg.update(num, c);//最小となる数字
      mindex[c] = i;
    }
  }

  for(int i=0;i<=n;i++){
    if(C[i].size()==0) continue;
    ll MINDEX = mindex[i];//色iの最小のidx
    vector<int> L = seg.query(0,i);
    vector<int> R = seg.query(i+1,n+1);
    ll min_other = INF, cc = -1;
    if(L[0]<R[0]&&L[0]!=INF) min_other=L[0], cc = L[1];
    if(L[0]>=R[0]&&R[0]!=INF) min_other=R[0], cc = R[1];
    for(auto k:C[i]){
      if(k==MINDEX) continue;
      //MINDEX + w[k] <= x || w[k] + min(othercolor) <= yならその色の親と併合
      ll w = d[k][1];
      if(d[MINDEX][1]+w<=x||w+min_other<=y) uf.unite(k, MINDEX);
    }
    if(min_other+d[MINDEX][1]<=y) uf.unite(mindex[cc], MINDEX);
  }

  // A:同じ色のボール
  // -> 色CのminCとotherCについて、minC + otherC <= XならotherCをminCに変換
  //
  // B:違う色のボール
  // -> 全体の最小値Mについて、
  // -> 1個とも交換できないものが仕切りになる
  // -> 連結成分の階乗?
  // 同じ色同士での隣接判定　最小値 + otherC <= Xか　O(N)
  // 異なる色同士での隣接判定

  vector<vector<int>> G(n, vector<int>(0));

  ll ans = 1;
  for(int i=0;i<n;i++) G[uf.find(i)].push_back(i);

  for(int i=0;i<n;i++){
    if(uf.find(i)!=i) continue;
    map<ll, ll> mp;

    for(auto to:G[i]){
      ll now_c = d[to][0];
      auto it = mp.find(now_c);
      if(it==mp.end()) mp.emplace(now_c, 1);
      else (*it).second++;
    }
    ll tmp = fac[uf.sz[i]];
    for(auto itr = mp.begin();itr!=mp.end();itr++){
      ll num = (*itr).second;
      tmp = (tmp * finv[num])%P;
    }
    //std::cout << "!" << i << " " << tmp << '\n';
    ans = (ans * tmp)%P;
  }
  std::cout << ans << '\n';
  return 0;
}


Measured memory_bytes: 92828