#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios { fast_ios(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
template<typename T> istream& operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }
template<typename T> ostream& operator<<(ostream &os, vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream& operator<<(ostream &os, set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T1, typename T2> ostream& operator<<(ostream &os, pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }
template<typename TK, typename TV> ostream& operator<<(ostream &os, map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

int N, X, Y;
vector<int> c, w;
constexpr lint MOD = 1000000007;

template <int mod>
struct ModInt
{
    using lint = long long;
    int val;
    ModInt() : val(0) {}
    void _setval(lint v) { v = (v % mod) + mod; val = v >= mod ? v - mod : v; }
    ModInt(lint v) { _setval(v); }
    ModInt operator+(const ModInt &x) const { return ModInt((lint)val + x.val); }
    ModInt operator-(const ModInt &x) const { return ModInt((lint)val - x.val); }
    ModInt operator*(const ModInt &x) const { return ModInt((lint)val * x.val); }
    ModInt operator/(const ModInt &x) const { return ModInt((lint)val * x.inv().val); }
    ModInt operator-() const { return ModInt(-val); }
    ModInt &operator+=(const ModInt &x) { return *this = *this + x; }
    ModInt &operator-=(const ModInt &x) { return *this = *this - x; }
    ModInt &operator*=(const ModInt &x) { return *this = *this * x; }
    ModInt &operator/=(const ModInt &x) { return *this = *this / x; }
    bool operator==(const ModInt &x) { return val == x.val; }
    bool operator!=(const ModInt &x) { return val != x.val; }
    friend ostream &operator<<(ostream &os, const ModInt &x) { os << x.val;  return os; }

    lint power(lint n) const {
        ModInt ans(1), tmp(val);
        while (n) {
            if (n & 1) ans *= tmp;
            tmp *= tmp;
            n /= 2;
        }
        return ans.val;
    }
    ModInt inv() const { return this->power(mod - 2); }
    
    ModInt fac() const {
        static vector<ModInt> facs;
        int l0 = facs.size();
        if (l0 > this->val) return facs[this->val];

        facs.resize(this->val + 1);
        for (int i = l0; i <= this->val; i++) facs[i] = (i == 0 ? 1 : facs[i - 1] * i);
        return facs[this->val];
    }

    ModInt nCr(const ModInt &r) const {
        if (this->val < r.val) return ModInt(0);
        return this->fac() / ((*this - r).fac() * r.fac());
    }
};
using mint = ModInt<MOD>;


struct UnionFind // UnionFind Tree (0-indexed)
{
    vector<int> par, rank;
    UnionFind(int N) : par(N), rank(N) { REP(i, N) par[i] = i; }
    int find(int x) { return (par[x] == x) ? x : (par[x] = find(par[x])); }
    void unite(int x, int y) {
        x = find(x), y = find(y); if (x == y) return;
        if (rank[x] < rank[y]) par[x] = y; else par[y] = x;
        if (rank[x] == rank[y]) rank[x]++;
    }
    bool same(int x, int y) { return find(x) == find(y); }
};



int main()
{
    cin >> N >> X >> Y;
    c.resize(N);
    w.resize(N);

    UnionFind uf(N);

    map<int, int> ec_min_pos;
    priority_queue<pint, vector<pint>, greater<pint>> pq;

    REP(i, N)
    {
        cin >> c[i] >> w[i];
        pq.push(pint(w[i], i));
        if (ec_min_pos.count(c[i]))
        {
            if (w[ec_min_pos[c[i]]] > w[i]) ec_min_pos[c[i]] = i;
        }
        else ec_min_pos[c[i]] = i;
    }

    if (ec_min_pos.size() == 1) cout << 1 << endl, exit(0);

    int w1, i1, w2, i2;
    tie(w1, i1) = pq.top();
    while (c[pq.top().second] == c[i1]) pq.pop();
    tie(w2, i2) = pq.top();
    if (w1 + w2 > Y) cout << 1 << endl, exit(0);

    uf.unite(i1, i2);
    REP(i, N)
    {
        if (w[ec_min_pos[c[i]]] + w[i] <= X) uf.unite(i, ec_min_pos[c[i]]);
        if (c[i] != c[i1] and w[i] + w1 <= Y) uf.unite(i1, i);
        if (c[i] != c[i2] and w[i] + w2 <= Y) uf.unite(i2, i);
    }

    map<int, int> movable_ec;
    int num = 0;
    REP(i, N) if (uf.same(i1, i))
    {
        movable_ec[c[i]]++;
        num++;
    }

    mint ans = mint(num).fac();
    for (auto pa : movable_ec) ans /= mint(pa.second).fac();
    cout << ans << endl;
}


Measured memory_bytes: 17904