#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

struct Element {
  int position;
  int color;
  int weight;
};

// Verified: AOJ-DSL1A, AGC002D
class UFSet {
 private:
  vector<int> ranks;
  vector<int> prevs;
  vector<int> sizes;

 public:
  UFSet(int n) : ranks(n), prevs(n), sizes(n) {
    for (int i = 0; i < n; i++) prevs[i] = i;
    for (int i = 0; i < n; i++) sizes[i] = 1;
  }

  // Returns an ID of a set which x belongs to.
  int Find(int x) {
    if (x != prevs[x]) prevs[x] = Find(prevs[x]);
    return prevs[x];
  }

  // Merges a set which x blongs to and a set which y belongs to.
  void Union(int x, int y) {
    int x_root = Find(x);
    int y_root = Find(y);
    if (ranks[x_root] > ranks[y_root]) {
      prevs[y_root] = prevs[x_root];
      sizes[x_root] += sizes[y_root];
    } else if (ranks[x_root] < ranks[y_root]) {
      prevs[x_root] = prevs[y_root];
      sizes[y_root] += sizes[x_root];
    } else if (prevs[x_root] != prevs[y_root]) {
      prevs[y_root] = prevs[x_root];
      ranks[x_root]++;
      sizes[x_root] += sizes[y_root];
    }
  }

  // Returns a size of a set which x belongs to.
  int Size(int x) {
    return sizes[Find(x)];
  }
};

constexpr int64 P = 1000000007;

struct FiniteField {
 private:
  int64 x;
 public:
  FiniteField(int64 raw_x) : x(raw_x) {
    if (x >= P || x < 0) {
    x %= P;
    if (x < 0) x += P;
  }
}
  FiniteField() : x(0) {}
  int64 Value() const { return x; }
  inline FiniteField operator+(FiniteField o) const {
    FiniteField r(*this); r += o; return r;
  }
  inline FiniteField operator-(FiniteField o) const {
    FiniteField r(*this); r -= o; return r;
  }
  inline FiniteField operator* (FiniteField o) const {
    FiniteField r(*this); r *= o; return r;
  }
  inline FiniteField operator/ (FiniteField o) const {
    FiniteField r(*this); r /= o; return r;
  }
  inline void operator+= (FiniteField o) { x = (x + o.x) % P; }
  inline void operator-= (FiniteField o) { x = (x + P - o.x) % P; }
  inline void operator*= (FiniteField o) { x = (x * o.x) % P; }
  void operator/=(FiniteField o) {
    int64 p = P - 2; while (p) { if (p % 2) { *this *= o; } o *= o; p /= 2; }
  }
};
ostream& operator<<(ostream& s, const FiniteField& x) { s << x.Value(); return s; }

vector<FiniteField> MakeFactorialTable(int n) {
  vector<FiniteField> values(n + 1);
  values[0] = 1;
  for (int i = 1; i <= n; i++) {
    values[i] = values[i - 1] * i;
  }
  return values;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  int x, y;
  cin >> n >> x >> y;

  vector<Element> es(n);
  vector<vector<Element>> color_to_es(n);
  for (int i = 0; i < n; i++) {
    int color;
    int weight;
    cin >> color >> weight;
    color--;

    es[i] = {i, color, weight};
    color_to_es[color].push_back({i, color, weight});
  }

  UFSet uf_set(n);
  for (int color = 0; color < n; color++) {
    if (color_to_es[color].empty()) continue;
    sort(color_to_es[color].begin(), color_to_es[color].end(),
         [](const auto& e1, const auto& e2) {
           return e1.weight < e2.weight;
         });
    for (int i = 1; i < color_to_es[color].size(); i++) {
      if (color_to_es[color][0].weight + color_to_es[color][i].weight <= x) {
        uf_set.Union(color_to_es[color][0].position, color_to_es[color][i].position);
      }
    }
  }

  sort(es.begin(), es.end(),
        [](const auto& e1, const auto& e2) {
          return e1.weight < e2.weight;
        }); 
  for (int i = 1; i < n; i++) {
    if (es[0].color != es[i].color && es[0].weight + es[i].weight <= y) {
      uf_set.Union(es[0].position, es[i].position);
    }
  }

  for (int i = 1; i < n; i++) {
    if (es[i].color != es[0].color) {
      for (int j = 0; j < n; j++) {
        if (es[j].color != es[i].color && es[j].weight + es[i].weight <= y) {
          uf_set.Union(es[j].position, es[i].position);
        }
      }
      break;
    }
  }

  vector<vector<int>> set_to_colors(n);
  for (int i = 0; i < n; i++) {
    int set = uf_set.Find(es[i].position);
    set_to_colors[set].push_back(es[i].color);
  }

  auto factorials = MakeFactorialTable(n);

  FiniteField ans = 1;
  for (int s = 0; s < n; s++) {
    FiniteField f = 1;
    map<int, int> color_count;
    for (int color : set_to_colors[s]) {
      color_count[color]++;
    }

    int count_sum = 0;
    for (const auto [color, count] : color_count) {
      count_sum += count;
      f /= factorials[count];
    }
    f *= factorials[count_sum];

    ans *= f;
  }
  cout << ans << endl;
}

Measured memory_bytes: 30860