package main

import (
  "bufio"
  "fmt"
  "os"
  "sort"
  "strconv"
  "strings"
)

func main() {
  input := Input{bufio.NewReaderSize(os.Stdin,100)}
  n,x,y := input.Next3Ints()
  m := ModUtil{mod:1000000007}.Init(n)
  b := make(Balls,n)
  for i:=0;i<n;i++ {
    c,w := input.Next2Ints()
    b[i] = Ball{c,w}
  }
  sort.Sort(b)
  if b[0].c == b[n-1].c { fmt.Println(1);return }
  b = append(b,Ball{0,0})
  u := NewUnionFind(n)
  for i,j:=0,0;i<n; {
    for b[j].c == b[i].c { j++ }
    for k:=i+1;k<j;k++ {
      if b[i].w+b[k].w <= x { u.Unite(i,k) }
    }
    i = j
  }
  p := 0
  for i:=0;i<n;i++ {
    if b[p].w > b[i].w { p = i }
  }
  q := 0
  for i:=0;i<n;i++ {
    if b[i].c != b[p].c { q = i;break }
  }
  for i:=0;i<n;i++ {
    if b[i].c != b[p].c && b[q].w > b[i].w { q = i }
  }
  for i:=0;i<n;i++ {
    if b[i].c == b[p].c {
      if b[i].w+b[q].w <= y { u.Unite(i,q) }
    } else {
      if b[i].w+b[p].w <= y { u.Unite(i,p) }
    }
  }
  mmp := make(map[int]map[int]int)
  for i:=0;i<n;i++ {
    j := u.Find(i)
    if _,ok := mmp[j];!ok { mmp[j] = map[int]int{} }
    mmp[j][b[i].c]++
  }
  ans := int64(1)
  for i,mp := range mmp {
    s := u.Size(i)
    for _,v := range mp {
      ans = (ans*m.Comb(s,v))%m.mod
      s -= v
    }
  }
  fmt.Println(ans)
}

type Ball struct { c,w int }
type Balls []Ball
func(b Balls) Len() int { return len(b) }
func(b Balls) Swap(i,j int) { b[i],b[j] = b[j],b[i] }
func(b Balls) Less(i,j int) bool {
  if b[i].c == b[j].c { return b[i].w < b[j].w }
  return b[i].c < b[j].c
}

type ModUtil struct {
  mod int64
  f,invf []int64
}
func(m ModUtil) Init(n int) ModUtil {
  m.f = make([]int64,n+1)
  m.invf = make([]int64,n+1)
  m.f[0] = 1
  for i:=1;i<n+1;i++ { m.f[i] = (int64(i)*m.f[i-1])%m.mod }
  m.invf[n] = m.Inv(m.f[n])
  for i:=n;i>0;i-- { m.invf[i-1] = (int64(i)*m.invf[i])%m.mod }
  return m
}
func(m ModUtil) Inv(n int64) int64 {
  var a,b,c,x int64 = n%m.mod,m.mod,0,1
  for b != 0 { a,b,c,x = b,a%b,x-(a/b)*c,c }
  return (x%m.mod+m.mod)%m.mod
}
func(m ModUtil) Perm(n,k int) int64 {
  if n < 0 || k < 0 || n-k < 0 { return 0 }
  return (m.f[n]*m.invf[n-k])%m.mod
}
func(m ModUtil) Comb(n,k int) int64 {
  if n < 0 || k < 0 || n-k < 0 { return 0 }
  return (m.Perm(n,k)*m.invf[k])%m.mod
}
func(m ModUtil) Homo(n,k int) int64 {
  if n == 0 && k == 0 { return 1 }
  return m.Comb(n+k-1,k)
}

type UnionFind struct { par,rank,size []int }
func NewUnionFind(n int) UnionFind {
  par := make([]int,n)
  rank := make([]int,n)
  size := make([]int,n)
  for i:=0;i<n;i++ { par[i],size[i] = i,1 }
  return UnionFind{par,rank,size}
}
func(u UnionFind) Find(i int) int {
  if u.par[i] == i { return i }
  u.par[i] = u.Find(u.par[i])
  return u.par[i]
}
func(u UnionFind) Same(i,j int) bool { return u.Find(i) == u.Find(j) }
func(u UnionFind) Unite(i,j int) {
  i,j = u.Find(i),u.Find(j)
  if i == j { return }
  if u.rank[i] < u.rank[j] {
    u.par[i] = j
    u.size[j] += u.size[i]
    return
  }
  u.par[j] = i
  u.size[i] += u.size[j]
  if u.rank[i] == u.rank[j] { u.rank[i]++ }
}
func(u UnionFind) Size(i int) int { return u.size[u.Find(i)] }

type Input struct { reader *bufio.Reader }
func(i *Input) NextLine() string {
  var buffer []byte
  for {
    line,isPrefix,err := i.reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer,line...)
    if !isPrefix { break }
  }
  return string(buffer)
}
func(i *Input) Next2Ints() (int,int) {
  s := strings.Fields(i.NextLine())
  x,_ := strconv.Atoi(s[0])
  y,_ := strconv.Atoi(s[1])
  return x,y
}
func(i *Input) Next3Ints() (int,int,int) {
  s := strings.Fields(i.NextLine())
  x,_ := strconv.Atoi(s[0])
  y,_ := strconv.Atoi(s[1])
  z,_ := strconv.Atoi(s[2])
  return x,y,z
}

Measured memory_bytes: 67200