#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define repd(i,x,y) for(int i=x; i>=y; --i)
#define pb push_back

using namespace std;
const int N=200005,mod=1000000007;
typedef long long LL;
int n,X,Y,fa[N],cnt[N];
LL ans,flv[N],inv[N],seed;
vector <int> vt[N];
struct node{int c,w;} dat[N];
struct data
{
	int x,y;
	
	bool operator < (const data &t) const
	{
		return x<t.x || (x==t.x && y<t.y);
	}

	bool operator == (const data &t) const
	{
		return x==t.x && y==t.y;
	}
};

struct treap
{
	data t[N];
	int tot,l[N],r[N],cur[N],root,stk[N];
	LL key[N<<1];

	LL ran()
	{
		return seed=((seed^998244353)*1000000007ll+19260817)%1000000009;
	}

	int New()
	{
		return *stk?stk[(*stk)--]:++tot;
	}

	int getfa(int x)
	{
		return fa[x]==x?x:fa[x]=getfa(fa[x]);
	}
	
	void merge(int x,int y)
	{
		x=getfa(x),y=getfa(y);
		if(x!=y) fa[x]=y;
	}

   void rotate(int &x,bool tp)
    {
        int y=tp?r[x]:l[x];
        if(tp) r[x]=l[y],l[y]=x;
        else l[x]=r[y],r[y]=x;
        x=y;
    }	

	void turn(int rt,int x)
	{
		if(!rt) return;
		if(cur[rt]) merge(cur[rt],x);
		else cur[rt]=x,merge(x,t[rt].y);
	}

	void pushdown(int rt)
	{
		if(cur[rt]) turn(l[rt],cur[rt]),turn(r[rt],cur[rt]),cur[rt]=0;
	}

	void ins(int &rt,data x)
	{
		if(!rt)
		{
			rt=New(),key[rt]=ran(),t[rt]=x;
			return;
		}
		pushdown(rt);
		if(x<t[rt])
		{
			ins(l[rt],x);
			if(key[l[rt]]>key[rt]) rotate(rt,0);
		}
		else
		{
			ins(r[rt],x);
			if(key[r[rt]]>key[rt]) rotate(rt,1);
		}
	}

	void ins(data x)
	{
		ins(root,x);
	}

	void erase(int &rt,data x)
	{
		if(pushdown(rt),t[rt]==x)
		{
			if(!l[rt] && !r[rt]) {stk[++*stk]=rt,rt=0; return;}
			if(key[l[rt]]>key[r[rt]]) pushdown(l[rt]),rotate(rt,0),erase(r[rt],x);
			else pushdown(r[rt]),rotate(rt,1),erase(l[rt],x);
		}
		else if(x<t[rt]) erase(l[rt],x);
		else erase(r[rt],x);
	}

	void erase(data x)
	{
		erase(root,x);
	}

	void modify(int rt,int lim,int x)
	{
		if(!rt) return;
		if(t[rt].x<=lim) merge(x,t[rt].y),turn(l[rt],x),modify(r[rt],lim,x);
		else modify(l[rt],lim,x);
	}

	void modify(int lim,int x)
	{
		modify(root,lim,x);
	}

	void dfs(int rt)
	{
		if(!rt) return;
		pushdown(rt);
		dfs(l[rt]),dfs(r[rt]);
	}

	void dfs()
	{
		dfs(root);
	}
} t;

int getint()
{
	char ch;
	while(!isdigit(ch=getchar()));
	int x=ch-48;
	while(isdigit(ch=getchar())) x=x*10+ch-48;
	return x;
}

LL getmi(LL a,LL x)
{
	LL rt=1;
	while(x)
	{
		if(x&1) rt=rt*a%mod;
		a=a*a%mod,x>>=1;
	}
	return rt;
}

bool cmp(node a,node b)
{
	return a.c<b.c || (a.c==b.c && a.w<b.w);
}

void solve1()
{
	int i=1;
	while(i<=n)
	{
		int p=i;
		while(p+1<=n && dat[p+1].c==dat[i].c) ++p;
		rep(j,i,p) if(dat[i].w+dat[j].w<=X) t.merge(i,j);
		i=p+1;
	}
}

void solve2()
{
	rep(i,1,n) t.ins((data){dat[i].w,i});
	int i=1;
	while(i<=n)
	{
		int p=i;
		while(p+1<=n && dat[p+1].c==dat[i].c) ++p;
		rep(j,i,p) t.erase((data){dat[j].w,j});
		rep(j,i,p) if(dat[j].w<Y) t.modify(Y-dat[j].w,j);
		rep(j,i,p)
			t.ins((data){dat[j].w,j});
		i=p+1;
	}
	t.dfs();
}

int main()
{
	n=getint(),X=getint(),Y=getint();
	rep(i,1,n) dat[i].c=getint(),dat[i].w=getint(),fa[i]=i;
	sort(dat+1,dat+1+n,cmp);
	solve1();
	solve2();

	rep(i,1,n) vt[t.getfa(i)].pb(dat[i].c);	
	ans=flv[0]=1;
	rep(i,1,n) flv[i]=flv[i-1]*i%mod;
	inv[n]=getmi(flv[n],mod-2);
	repd(i,n,1) inv[i-1]=inv[i]*i%mod;
	
	rep(i,1,n) if(fa[i]==i)
	{
		int sz=vt[i].size();
		LL ret=flv[sz];
		rep(j,0,sz-1) ++cnt[vt[i][j]];
		rep(j,0,sz-1) ret=ret*inv[cnt[vt[i][j]]]%mod,cnt[vt[i][j]]=0;
		ans=ans*ret%mod;
	}
	printf("%lld\n",ans);
	return 0;
}

Measured memory_bytes: 24832