/*

This Submission is to determine how many 120/240 min const. delivery point there are.

//info
120 req. steps <= 5
*/
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <cstring>
#include <queue>
#include <stack>
#include <math.h>
#include <iterator>
#include <vector>
#include <string>
#include <set>
#include <math.h>
#include <iostream>
#include <random>
#include<map>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
#include <list>
#include <typeinfo>
#include <list>
#include <set>
#include <cassert>
#include<fstream>
#include <unordered_map>
#include <cstdlib>
#include <complex>
#include <cctype>
#include <bitset>
using namespace std;
typedef string::const_iterator State;
#define Ma_PI 3.141592653589793
#define eps 0.00000001
#define LONG_INF 1e18
#define GOLD 1.61803398874989484820458
#define MAX_MOD 1000000007
#define MOD 1000000007
#define seg_size 262144
#define REP(a,b) for(long long a = 0;a < b;++a)

unsigned long xor128() {
	static unsigned long x = time(NULL), y = 362436069, z = 521288629, w = 88675123;
	unsigned long t = (x ^ (x << 11));
	x = y; y = z; z = w;
	return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
#define int long long
int union_tree[300000];
int union_find(int now) {	
	if (union_tree[now] == now) return now;
	return union_tree[now] = union_find(union_tree[now]);
}
void union_merge(int a, int b) {
	a = union_find(a);
	b = union_find(b);
	if (a != b) {
		union_tree[a] = b;
	}
}
int color[300000];
int weight[300000];
int cnt[300000];
int minnest_color[300000];
long long mae[300000];
long long gyaku[300000];
long long inv(long long now) {
	long long hoge = MAX_MOD - 2LL;
	long long ans = 1;
	while (hoge != 0) {
		if (hoge % 2 == 1) {
			ans *= now;
			ans %= MAX_MOD;
		}
		now *= now;
		now %= MAX_MOD;
		hoge /= 2;
	}
	return ans;
}
vector<int> colors_find[300000];
#undef int 
int main() {
	iostream::sync_with_stdio(false);
#define int long long
	int n, x, y;
	cin >> n >> x >> y;
	mae[0] = 1;
	gyaku[0] = 1;
	for (long long i = 1; i <= 250000; ++i) {
		mae[i] = i * mae[i - 1];
		mae[i] %= MAX_MOD;
		gyaku[i] = inv(mae[i]);
	}
	REP(i, n) {
		cin >> color[i] >> weight[i];
		colors_find[color[i]].push_back(i);
		union_tree[i] = i;
		minnest_color[i+1] = -1;
	}
	int ok = 1;
	REP(i, n) {
		if (color[i] != color[i + 1])ok = 0;
	}
	if (ok == 1) {
		cout << 1 << endl;
		return 0;
	}
	int now_min_color = 0;
	REP(i, n) {
		if (weight[i] < weight[now_min_color]) {
			now_min_color = i;
		}
		if (minnest_color[color[i]] == -1 || weight[i] < weight[minnest_color[color[i]]]) {
			minnest_color[color[i]] = i;
		}
	}
	int next_color = -1;
	REP(i, n) {
		if (color[now_min_color] != color[i]) {
			if (next_color == -1 || weight[i] < weight[next_color]) {
				next_color = i;
			}
		}
	}
	REP(i, n) {
		if (color[i] != color[now_min_color]&&weight[i] + weight[now_min_color] <= y) {
			union_merge(i, now_min_color);
		}
		if (weight[i] + weight[minnest_color[color[i]]] <= x) {
			union_merge(i, minnest_color[color[i]]);
		}
		if (color[i] == color[now_min_color] && weight[i] + weight[next_color] <= y) {
			union_merge(i, next_color);
		}
	}
	REP(i, n) {
		cnt[union_find(i)]++;
	}
	long long ans = 1;
	REP(i, n) {
		ans *= mae[cnt[i]];
		ans %= MAX_MOD;
		cnt[i] = 0;
	}
	for (int i = 1; i <= 200000; ++i) {
		REP(q, colors_find[i].size()) {
			cnt[union_find(colors_find[i][q])]++;
		}
		REP(q, colors_find[i].size()) {
			ans *= gyaku[cnt[union_find(colors_find[i][q])]];
			ans %= MAX_MOD;
			cnt[union_find(colors_find[i][q])] = 0;
		}
	}
	cout << ans << endl;
}

Measured memory_bytes: 27776