#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <stack>
#include <string>
#include <functional>
#include <numeric>
#define _USE_MATH_DEFINES
#include <math.h>
#include <iomanip>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
using namespace std;
#define INT_MAX 2147483647
#define INT_MIN (-2147483647 - 1)
#define INF (int)1e8
#define _INF (int)-1e8
#define INFLL (long long)1e14
#define _INFLL (long long)-1e14
#define Loop(i, n) for(int i = 0; i < (int)n; i++)
#define Loop1(i, n) for(int i = 1; i <= (int)n; i++)
#define Loopr(i, n) for(int i = (int)n - 1; i >= 0; i--)
#define Loopr1(i, n) for(int i = (int)n; i >= 1; i--)
#define bitmanip(m,val) static_cast<bitset<(int)m>>(val)
typedef long long int ll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef pair<int, int> P;
 
 
//x! O(x)
vll mod_factorial(ll x, ll mod) {
	if (x < 0) return{};
	else {
		vll ret((int)x + 1);
		ret[0] = 1;
		Loop1(i, (int)x) ret[i] = ret[i - 1] * i % mod;
		return ret;
	}
}
 
//x^y O(log y)
ll mod_pow(ll x, ll y, ll mod) {
	if (y == 1) return x;
	else {
		ll ans = mod_pow(x, y / 2, mod);
		ans = ans * ans % mod;
		if (y % 2 == 1) ans = ans * x % mod;
		return ans;
	}
}
 
class Union_Find {
private:
	vi p, r;
public:
	Union_Find(int N) {
		p.resize(N);
		r.resize(N);
		Loop(i, N) {
			p[i] = i;
			r[i] = 0;
		}
	}
	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return;
		if (r[x] < r[y]) p[x] = y;
		else {
			p[y] = x;
			if (r[x] == r[y]) r[x]++;
		}
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
	int find(int x) {
		if (p[x] == x) return x;
		else return p[x] = find(p[x]);
	}
};
 
int main() {
	ll n, x, y;
	cin >> n >> x >> y;
	vll c(n), w(n);
	Loop(i, n) cin >> c[i] >> w[i];
 
	map<ll, ll> mp1; //色→最小重量をもつindex
	Loop(i, n) {
		if (mp1.find(c[i]) == mp1.end()) mp1[c[i]] = i;
		else if (w[mp1[c[i]]] > w[i]) mp1[c[i]] = i;
	}
	ll min_index = INFLL; //全てのボールの最小重量をもつindex
	ll min2_index = INFLL; //上とは別の色で、最小重量をもつindex
	for (auto itr = mp1.begin(); itr != mp1.end(); itr++) {
		int t = (*itr).second;
		if (min_index == INFLL || w[min_index] > w[t]) {
			min2_index = min_index;
			min_index = t;
		}
		else if (min2_index == INFLL || w[min2_index] > w[t]) {
			min2_index = t;
		}
	}
	//可換index同士を連結
	Union_Find *uf = new Union_Find(n);
	//操作1
	Loop(i, n) {
		if (w[i] + w[mp1[c[i]]] <= x) {
			uf->unite(i, mp1[c[i]]);
		}
	}
	//操作2
	Loop(i, n) {
		if (c[i] != c[min_index]) {
			if (w[i] + w[min_index] <= y) {
				uf->unite(i, min_index);
			}
		}
		else if (min2_index != INFLL) {
			if (w[i] + w[min2_index] <= y) {
				uf->unite(i, min2_index);
			}
		}
	}
	//計算の準備
	map<ll, vll> mp2; //親→同じ親を持つ集合
	Loop(i, n) {
		mp2[uf->find(i)].push_back(i);
	}
	ll mod = 1e9 + 7;
	vll fact = mod_factorial(n, mod);
	vll invfact(n + 1);
	Loop(i, n + 1) {
		invfact[i] = mod_pow(fact[i], mod - 2, mod);
	}
	ll ans = 1;
	for (auto itr2 = mp2.begin(); itr2 != mp2.end(); itr2++) {
		vll dat = (*itr2).second;
		map<ll, ll> mp3; //色→個数
		Loop(j, dat.size()) {
			int index = dat[j];
			mp3[c[index]]++;
		}
		ll p = fact[dat.size()];
		for (auto itr3 = mp3.begin(); itr3 != mp3.end(); itr3++) {
			ll k = (*itr3).second;
			p = p * invfact[k] % mod;
		}
		ans = ans * p % mod;
	}
	cout << ans << endl;
	return 0;
}

Measured memory_bytes: 37500