#include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (int)(k); i < (int)(n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1e9 + 7;
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<class T>
istream& operator >> (istream& is, vector<T>& v)
{
	for (auto &i : v) is >> i;
	return is;
}
template<class T>
ostream& operator<<(ostream& os, vector<T>& v)
{
	const string delimiter = "\n";
	REP(i, v.size())
	{
		os << v[i];
		if (i != v.size() - 1) os << delimiter;
	}
	return os;
}
/*--------------------template--------------------*/

const int INF = 1e9 + 1;

struct UnionFind
{
	vector<int> par;
	UnionFind(int n) :par(n, -1) {}
	int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
	void unite(int x, int y)
	{
		x = find(x); y = find(y);
		if (x == y) return;
		if (par[y] < par[x]) swap(x, y);
		if (par[x] == par[y]) par[x]--;
		par[y] = x;
		if (find(x) != find(y)) par[find(y)] = x;
	}
	int count()
	{
		int cnt = 0;
		REP(i, par.size()) if (par[i] < 0) cnt++;
		return cnt;
	}
	bool same(int x, int y)
	{
		return find(x) == find(y);
	}
};

template<int M>
class Cyclic {
	using ll = long long;
	int n;
	static ll inv(ll a, ll p) { return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p); }
public:
	Cyclic() : n(0) { ; }
	Cyclic(int m) : n(m) {
		if (n >= M) n %= M;
		else if (n < 0) n = (n % M + M) % M;
	}
	operator int() const { return n; }
	bool operator==(const Cyclic &a) const { return n == a.n; }
	Cyclic operator+=(const Cyclic &a) { n += a.n; if (n >= M) n -= M; return *this; }
	Cyclic operator-=(const Cyclic &a) { n -= a.n; if (n < 0) n += M; return *this; }
	Cyclic operator*=(const Cyclic &a) { n = (ll(n) * a.n) % M; return *this; }
	Cyclic operator+(const Cyclic &a) const { Cyclic res = *this; return res += a; }
	Cyclic operator-(const Cyclic &a) const { Cyclic res = *this; return res -= a; }
	Cyclic operator*(const Cyclic &a) const { Cyclic res = *this; return res *= a; }
	Cyclic operator/(const Cyclic &a) const { return *this * Cyclic<M>(inv(a, M)); }
	Cyclic operator^(int n) const {
		if (n == 0) return Cyclic(1);
		const Cyclic a = *this;
		Cyclic res = (a * a) ^ (n / 2);
		return n % 2 ? res * a : res;
	}
};

template<int M> Cyclic<M> fact(int n, bool sw = true) {
	static vector<Cyclic<M>> v1 = { 1 }, v2 = { 1 };
	if (n >= (int)v1.size()) {
		const int from = v1.size(), to = n + 1024;
		v1.reserve(to);
		v2.reserve(to);
		for (int i = from; i < to; ++i) {
			v1.push_back(v1.back() * Cyclic<M>(i));
			v2.push_back(v2.back() / Cyclic<M>(i));
		}
	}
	return sw ? v1[n] : v2[n];
}

template<int M> Cyclic<M> comb(int a, int b) {
	return fact<M>(a, true) * fact<M>(b, false) * fact<M>(a - b, false);
}

const int mod = 1000000007;
using Mod = Cyclic<mod>;


int main()
{
	cin.sync_with_stdio(false); cout << fixed << setprecision(10);
	int n, x, y;
	cin >> n >> x >> y;
	vector<pii> v;
	REP(i, n)
	{
		int a, b; cin >> a >> b;
		v.emplace_back(b, a);
	}
	sort(ALL(v));
	map<int, pii> color_min; // color, <weight, index>
	tuple<int, int, int> all_min(INF, -1, -1), all_min2(INF, -1, -1); //weight, color, index
	REP(i, n)
	{
		int tw = v[i].first, tc = v[i].second;
		if (color_min.count(tc) == 0) color_min[tc] = pii(tw, i);

		if (get<0>(all_min) > tw)
		{
			if (tc != get<1>(all_min2)) all_min2 = all_min;
			all_min = make_tuple(tw, tc, i);
		}
		else if (get<0>(all_min2) > tw && get<1>(all_min) != tc)
		{
			all_min2 = make_tuple(tw, tc, i);
		}
	}
	assert(get<1>(all_min) != get<1>(all_min2));
	UnionFind uf(n);
	REP(i, n)
	{
		int tw = v[i].first, tc = v[i].second;
		if (color_min[tc].second != i && tw + color_min[tc].first <= x)
		{
			uf.unite(i, color_min[tc].second);
		}

		if (tc != get<1>(all_min))
		{
			if (tw + get<0>(all_min) <= y)
			{
				uf.unite(i, get<2>(all_min));
			}
		}
		else
		{
			if (tw + get<0>(all_min2) <= y)
			{
				uf.unite(i, get<2>(all_min2));
			}
		}
	}
	vector<map<int, int>> vmp(n);
	REP(i, n)
	{
		int r = uf.find(i);
		vmp[r][v[i].second]++;
	}

	Mod ans = 1;
	for (auto mp : vmp)
	{
		if (mp.size() == 0) continue;
		int sum = 0;
		Mod tmp = 1;
		for (auto i : mp) sum += i.second;
		for (auto i : mp)
		{
			tmp *= comb<mod>(sum, i.second);
			sum -= i.second;
		}
		ans *= tmp;
	}
	cout << int(ans) << endl;
	return 0;
}

Measured memory_bytes: 36464