// Original C++ solution (slower):
#include<vector>

#include<cstdio>

#include<cstring>

#include<algorithm>

#define fr first

#define sc second

#define gt getchar()

#define ll long long

#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

inline int in()

{

	int k=0;char ch=gt;

	while(ch<'-')ch=gt;

	while(ch>'-')k=k*10+ch-'0',ch=gt;

	return k;

}

const int N=2e5+5,inf=1e9,YL=1e9+7;

inline int ksm(int a,int k){int r=1;while(k){if(k&1)r=1ll*r*a%YL;a=1ll*a*a%YL,k>>=1;}return r;}

int col[N],w[N],mn[N],siz[N],fnv[N],fac[N],id[N],o[N];

using std::min;

#define mk std::make_pair

std::vector<int>G[N];

inline bool cmp(const int &a,const int &b){return w[a]<w[b];}

int main()

{

	int n=in(),X=in(),Y=in(),mn1=YL,mn2=YL;fac[0]=fnv[0]=1;

	for(int i=1;i<=n;++i)fac[i]=1ll*fac[i-1]*i%YL;fnv[n]=ksm(fac[n],YL-2);

	for(int i=n;i>=2;--i)fnv[i-1]=1ll*fnv[i]*i%YL;

	for(int i=1,x;i<=n;++i)x=in(),G[x].push_back(in());

	for(int i=1;i<=n;++i)

		if(G[i].size())

		{

			std::sort(G[i].begin(),G[i].end());

			mn2=min(mn2,mn[i]=G[i][0]);

			if(mn2<mn1)std::swap(mn1,mn2);

		}

		else mn[i]=YL;

	int ans=1,tot=0;

	for(int i=1;i<=n;++i)

	{

		int mm=mn[i]==mn1?mn2:mn1,sz=G[i].size();

		while(sz>1&&G[i][sz-1]+mn[i]>X&&G[i][sz-1]+mm>Y)--sz,G[i].pop_back();

		if(mn[i]+mn1<=Y)ans=1ll*ans*fnv[sz]%YL,tot+=sz;

	}

	printf("%d\n",1ll*ans*fac[tot]%YL);

	return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define mod 1000000007ll

using namespace std;

struct edge

{

	int to;

	int nxt;

}e[3000010];

int color[200010],head[200010],pos[200010];

int cnt[200010],tot;

long long w[200010],minn[200010];

long long fac[200010],rfac[200010];

int v[200010];

int n,minnum,minnum2;

long long X,Y,min1,min2,ans;

long long qpow(long long a,long long b)

{

	long long ans = 1,res = a;

	while(b)

	{

		if(b&1)ans = (ans * res) % mod;

		res *= res;

		res %= mod;

		b >>= 1;

	}

	return ans;

}

long long C(long long n,long long k)

{

	return  fac[n] * rfac[k] % mod * rfac[n - k] % mod;

}

void addedge(int x,int y)

{

	e[++tot].nxt = head[x];

	e[tot].to = y;

	head[x] = tot;

}

void add(int x,int y)

{

	addedge(x,y);

	addedge(y,x);

}

void dfs(int x)

{

	v[x] = 1;

	for(int i = head[x]; i; i = e[i].nxt)

	{

		if(!v[e[i].to])

			dfs(e[i].to);

	}

}

int main()

{

	scanf("%d%lld%lld",&n,&X,&Y);

	fac[0] = 1;

	for(int i = 1; i <= n;i++)scanf("%d%lld",&color[i],&w[i]);

	for(int i = 1;i <= n;i++)fac[i] = (i * fac[i - 1]) % mod,minn[i] = 2147483647ll;

	rfac[n] = qpow(fac[n],mod - 2);

	for(int i = n; i > 0; i--)rfac[i - 1] = (i * rfac[i]) % mod;

	for(int i = 1; i <= n; i++)

	{

		if(w[i] < minn[color[i]])

		{

			minn[color[i]] = w[i];

			pos[color[i]] = i;

		}

	}

	for(int i = 1; i <= n; i++)

	{

		if(i != pos[color[i]] && w[i] + minn[color[i]] <= X)

		{

			add(i,pos[color[i]]);

		}

	}

	min1 = min2 = 2147483647ll;

	for(int i = 1; i <= n; i++)

	{

		if(w[i] < min1)

		{

			min1 = w[i];

			minnum = i;

		}

	}

	for(int i = 1; i <= n; i++)

	{

		if(w[i] <= min2 && color[i] != color[minnum])

		{

			min2 = w[i];

			minnum2 = i;

		}

	}

	for(int i = 1; i <= n; i++)

	{

		if(i == minnum)continue;

		if(color[i] != color[minnum] && w[i] + w[minnum] <= Y)

		{

			add(i,minnum);

		}

		if(minnum2 && color[i] != color[minnum2] && w[i] + w[minnum2] <= Y)

		{

			add(i,minnum2);

		}

	}

	dfs(minnum);

	long long tot = 0;

	for(int i = 1; i <= n; i++)

	{

		if(v[i])

		{

			++tot;

			cnt[color[i]]++;

		}

	}

	ans = 1;

	for(int i = 1; i <= n; i++)

	{

		if(cnt[i])

		{

			ans = (ans * C(tot,cnt[i])) % mod;

			tot -= cnt[i];

		}

	}

	printf("%lld",ans);

	return 0;

}

// Fastest known solution for this problem: