#include <bits/stdc++.h>
using ll = long long;
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(e, c) for (auto e = c.begin(); e != c.end(); ++e)
using namespace std;
template <typename T> using vec = vector<T>;
using V = vec<int>;

using Weight = int;
using Flow = int;
struct Edge {
    int src, dst;
    Flow cap;
    Edge() : src(0), dst(0) {}
    Edge(int s, int d) : src(s), dst(d) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;

void add_edge(Graph &g, int a, int b) {
    g[a].emplace_back(a, b);
    g[b].emplace_back(b, a);
}
void add_arc(Graph &g, int a, int b) { g[a].emplace_back(a, b); }


#define EVEN(x) (mu[x] == x || (mu[x] != x && phi[mu[x]] != mu[x]))
#define ODD(x)  (mu[x] != x && phi[mu[x]] == mu[x] && phi[x] != x)
#define OUTER(x) (mu[x] != x && phi[mu[x]] == mu[x] && phi[x] == x)
int maximumMatching(const Graph &g, Edges &matching) {
    int n = g.size();
    vector<int> mu(n), phi(n), rho(n), scanned(n);
    REP(v,n) mu[v] = phi[v] = rho[v] = v; // (1) initialize
    for (int x = -1; ; ) {
        if (x < 0) {                        // (2) select even
            for (x = 0; x < n && (scanned[x] || !EVEN(x)); ++x);
            if (x == n) break;
        }
        int y = -1;                         // (3) select incident
        FOR(e, g[x]) if (OUTER(e->dst) || (EVEN(e->dst) && rho[e->dst] != rho[x])) y = e->dst;
        if (y == -1) scanned[x] = true, x = -1;
        else if (OUTER(y)) phi[y] = x;      // (4) growth
        else {
            vector<int> dx(n, -2), dy(n, -2); // (5,6), !TRICK! x % 2 --> x >= 0
            for (int k = 0, w = x; dx[w] < 0; w = k % 2 ? mu[w] : phi[w]) dx[w] = k++;
            for (int k = 0, w = y; dy[w] < 0; w = k % 2 ? mu[w] : phi[w]) dy[w] = k++;
            bool vertex_disjoint = true;
            REP(v,n) if (dx[v] >= 0 && dy[v] > 0) vertex_disjoint = false;
            if (vertex_disjoint) {            // (5) augment
                REP(v,n) if (dx[v] % 2) mu[phi[v]] = v, mu[v] = phi[v];
                REP(v,n) if (dy[v] % 2) mu[phi[v]] = v, mu[v] = phi[v];
                mu[x] = y; mu[y] = x; x = -1;
                REP(v,n) phi[v] = rho[v] = v, scanned[v] = false;
            } else {                          // (6) shrink
                int r = x, d = n;
                REP(v,n) if (dx[v] >= 0 && dy[v] >= 0 && rho[v] == v && d > dx[v]) d = dx[v], r = v;
                REP(v,n) if (dx[v] <= d && dx[v] % 2 && rho[phi[v]] != r) phi[phi[v]] = v;
                REP(v,n) if (dy[v] <= d && dy[v] % 2 && rho[phi[v]] != r) phi[phi[v]] = v;
                if (rho[x] != r) phi[x] = y;
                if (rho[y] != r) phi[y] = x;
                REP(v,n) if (dx[rho[v]] >= 0 || dy[rho[v]] >= 0) rho[v] = r;
            }
        }
    }
    matching.clear();
    REP(u,n) if (u < mu[u]) matching.push_back( Edge(u, mu[u]) );
    return matching.size(); // make explicit matching
}


int N, A, B;
int a[1000], b[1000];

bool range(int x) {
    return abs(x) <= A || (B <= abs(x) && abs(x) <= 2 * A);
}

bool check(int i) {
    return range(a[i] - b[i]);
}

bool check(int i, int j) {
    return range(a[i] + a[j] - b[i] - b[j]);
}

int pnode(int i, int j) {
    assert(i <= j);
    return N + i * N + j;
}

int main() {
    while (cin >> N >> A >> B && N) {
        REP(i, N) cin >> a[i] >> b[i];
        vec<int> use(N);
        int cnt = 0;
        REP(i, N) if (check(i)) use[i] = true, cnt++;
        Graph g(N);
        REP(i, N) REP(j, i) {
            if (use[i] || use[j]) continue;
            if (check(i, j)) {
                add_edge(g, i, j);
            }
        }
        vec<Edge> m;
        cout << cnt + maximumMatching(g, m) << endl;
    }
}



Measured memory_bytes: 4228