#pragma warning(disable:4996)

#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <complex>
#include <iterator>
#include <random>
#include <time.h>
#include <tuple>
#include <functional>
#include <list>
#include <limits.h>
#define mp make_pair
#define ni(x) scanf("%d", &(x))
#define nii(x,y) scanf("%d%d",&(x),&(y))
#define mul(x,y) ((ll)(x)*(y)%mod)
#define mtp make_tuple
#define F(i,n) for(int i = 0; i < (n); i++)
#define FF(i,n) for(int i = 1; i <= (n); i++)
#define FE(i,n) for(int i = 0; i <= (n); i++)

using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const int mod = 1000000007;
const int inf = 2012345678;
const ll infl = 9012345678901234567;
const double pi = 3.1415926535897932384626433832795;
//----------------------------------------------------------------------------//

const int N = 1 << 18;
int par[N];
int c[N], w[N];
vector<int> V[N];
int chk[N];
int to[N];
const int B = 1 << 18;
vector<pii> tr[B << 1];
int L[B << 1], R[B << 1];
int tr2[B << 1];
void Up(int l, int r, int i, int Y) {
	for (l += B, r += B; l / 2 != r / 2; l /= 2, r /= 2) {
		if (!(l & 1))tr[l + 1].emplace_back(i, Y);
		if (r & 1)tr[r - 1].emplace_back(i, Y);
	}
}
int find(int i) {
	return par[i] < 0 ? i : (par[i] = find(par[i]));
}
void merge(int i, int j) {
	i = find(i); j = find(j);
	if (i == j)return;
	if (par[i] < par[j])swap(i, j);
	par[j] += par[i]; par[i] = j;
}
bool cmp(int i, int j) {
	return i < w[j];
}
int fact[N];
int inv[N];
int invfact[N];
int main() {
#ifndef __GNUG__
	freopen("input.txt", "r", stdin);
#endif
	int n, X, Y; ni(n); nii(X, Y);
	F(i, n)par[i] = -1;
	F(i, n)nii(c[i], w[i]);
	F(i, n)V[c[i]].push_back(i);
	FF(i, n)sort(V[i].begin(), V[i].end(), [](int x, int y) {return w[x] < w[y]; });
	F(i, B)L[B + i] = R[B + i] = i;
	for (int i = B - 1; i; i--)L[i] = L[i << 1], R[i] = R[i << 1 | 1];
	F(i, n) {
		int C = c[i];
		int j = upper_bound(V[C].begin(), V[C].end(), X - w[i], cmp) - V[C].begin() - 1;
		if (j != -1) {
			merge(V[C][j], i);
			to[C] = max(to[C], j);
		}
		Up(0, C, i, Y - w[i]);
		Up(C, n + 1, i, Y - w[i]);
	}
	FF(i, (B << 1) - 1) {
		int MM = inf;
		for (int j = L[i]; j <= R[i] && j <= n; j++)if (!V[j].empty())MM = min(MM, w[V[j][0]]);
		int cur = -1;
		for (auto &x : tr[i]) {
			if (x.second < MM) continue;
			if (cur != -1)merge(cur, x.first);
			cur = x.first;
		}
		int MAX = -inf;
		for (auto &x : tr[i])MAX = max(MAX, x.second);
		for (int j = L[i]; j <= R[i] && j <= n; j++) {
			if (!V[j].empty() && w[V[j][0]] <= MAX) {
				if (cur != -1)merge(cur, V[j][0]);
				cur = V[j][0];
			}
		}
		tr2[i] = MAX;
	}
	FF(i, n) {
		int MAX = -inf;
		for (int j = B + i; j; j /= 2)MAX = max(MAX, tr2[j]);
		int j = upper_bound(V[i].begin(), V[i].end(), MAX, cmp) - V[i].begin() - 1;
		j = max(j, to[i]);
		for (int k = 0; k < j - 1; k++) {
			merge(V[i][k], V[i][k + 1]);
		}
	}
	fact[0] = 1;
	FF(i, N - 1)fact[i] = mul(fact[i - 1], i);
	inv[1] = 1;
	for (int i = 2; i < N; i++)inv[i] = mul(mod - mod / i, inv[mod%i]);
	invfact[0] = 1;
	FF(i, N - 1)invfact[i] = mul(invfact[i - 1], inv[i]);
	vector<int> clr(n + 1);
	vector<vector<int> > UU(n);
	F(i, n) {
		UU[find(i)].push_back(i);
	}
	int ans = 1;
	F(i, n) {
		int ii = find(i);
		if (chk[ii])continue;
		chk[ii] = 1;
		ans = mul(ans, fact[-par[ii]]);
		for (auto &x : UU[ii]) {
			clr[c[x]]++;
		}
		for (auto &x : UU[ii]) {
			if (clr[c[x]]) ans = mul(ans, invfact[clr[c[x]]]);
			clr[c[x]] = 0;
		}
	}
	printf("%d\n", ans);
	return 0;
}


Measured memory_bytes: 121520