#include <bits/stdc++.h>
using namespace std;
using Int = long long;
int PREP = (cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(9), 0);
//int SEGV = getenv("D") || (exit(system("D= SEGFAULT_SIGNALS=all catchsegv ./prog.exe") >> 8), 0);
template <class T, class Merge>
struct UnionFindWithMerge {
    vector<int> A;
    vector<T> values;
    Merge merge;
    UnionFindWithMerge(const vector<T>& init, Merge func)
        : A(init.size(), -1), values(init), merge(func) {}
    int find(int x) {
        if (A[x] < 0) return x;
        return A[x] = find(A[x]);
    }
    T& value(int x) {
        return values[find(x)];
    }
    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return false;
        if (A[x] > A[y]) swap(x, y);
        A[x] += A[y];
        values[x] = merge(values[x], values[y]);
        A[y] = x;
        return true;
    }
};
const Int MOD = 1000000007;
const Int MAX = 300000;
Int fac[MAX], finv[MAX], inv[MAX];
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++) {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}
Int COM(int n, int k) {
    if (n < k || n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
int main() {
    COMinit();
    int N, X, Y; cin >> N >> X >> Y;
    vector<int> color(N), weight(N);
    vector<map<int, int>> init(N);
    for (int i = 0; i < N; i++) {
        int c, w; cin >> c >> w;
        color[i] = c;
        weight[i] = w;
        init[i][c] = 1;
    }
    auto merge = [](map<int, int>& x, map<int, int>& y) {
        map<int, int> ans;
        if (x.size() >= y.size()) {
            ans.swap(x);
            for (auto p : y) ans[p.first] += p.second;
        } else {
            ans.swap(y);
            for (auto p : x) ans[p.first] += p.second;
        }
        return ans;
    };
    UnionFindWithMerge<map<int, int>, decltype(merge)> uf(init, merge);
    map<int, int> light;
    for (int i = 0; i < N; i++) {
        if (!light.count(color[i])) {
            light[color[i]] = i;
        } else if (weight[light[color[i]]] > weight[i]) {
            light[color[i]] = i;
        }
    }
    int lightest, lightest2;
    {
        vector<int> A;
        for (auto &p : light) A.push_back(p.second);
        sort(begin(A), end(A), [&](int i, int j) {
            return weight[i] < weight[j];
        });
        lightest = lightest2 = A[0];
        if (A.size() >= 2) lightest2 = A[1];
    }
    for (int i = 0; i < N; i++) {
        if (weight[i] + weight[light[color[i]]] <= X) {
            uf.unite(i, light[color[i]]);
        }
        if (weight[i] + weight[lightest] <= Y && color[i] != color[lightest]) {
            uf.unite(i, lightest);
        }
        if (weight[i] + weight[lightest2] <= Y && color[i] != color[lightest2]) {
            uf.unite(i, lightest2);
        }
    }
    Int ans = 1;
    for (int i = 0; i < N; i++) {
        if (i == uf.find(i)) {
            auto &m = uf.value(i);
            int sum = 0;
            for (auto &p : m) sum += p.second;
            for (auto &p : m) {
                ans = ans * COM(sum, p.second) % MOD;
                sum -= p.second;
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


Measured memory_bytes: 59352