import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;

class Main {
	public static void main(String[] args) {
		new Main().run();
	}

	final long MODULO = (long) (1e9 + 7);

	void run() {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		long X = sc.nextLong();
		long Y = sc.nextLong();
		int[] c = new int[N];
		long[] w = new long[N];
		long[][] c_min = new long[N][2];
		for (int i = 0; i < N; ++i) {
			c_min[i][0] = Long.MAX_VALUE / 16;
			c_min[i][1] = -1;
		}
		for (int i = 0; i < N; ++i) {
			c[i] = sc.nextInt() - 1;
			w[i] = sc.nextLong();
			c_min[c[i]][0] = Math.min(c_min[c[i]][0], w[i]);
			if (c_min[c[i]][0] == w[i])
				c_min[c[i]][1] = i;
		}
		DJSet ds = new DJSet(N, w);
		for (int i = 0; i < N; ++i) {
			if (Math.abs(w[i] + c_min[c[i]][0]) <= X) {
				ds.setUnion(i, (int) c_min[c[i]][1]);
			}
		}

		int v1 = 0;
		int v2 = 0;
		int v3 = 0;
		for (int i = 0; i < N; ++i) {
			if (ds.w[ds.root(i)] <= ds.w[ds.root(v1)]) {
				v1 = ds.root(i);
			}
		}
		while (v2 + 1 < N && c[v1] == c[v2])
			++v2;
		for (int i = 0; i < N; ++i) {
			if (ds.w[ds.root(i)] <= ds.w[ds.root(v2)] && c[ds.root(i)] != c[ds.root(v1)]) {
				v2 = ds.root(i);
			}
		}
		while (v3 + 1 < N && (c[v1] == c[ds.root(v3)] || c[v2] == c[ds.root(v3)]))
			++v3;
		v3 = ds.root(v3);
		for (int i = 0; i < N; ++i) {
			if (ds.w[ds.root(i)] <= ds.w[v3] && c[ds.root(i)] != c[v2] && c[ds.root(i)] != c[v1]) {
				v3 = ds.root(i);
			}
		}

		boolean[] vis = new boolean[N];
		for (int i = 0; i < N; ++i) {
			int rep = ds.root(i);
			if (vis[rep])
				continue;
			if (c[i] != c[v1]) {
				if (Math.abs(ds.w[rep] + ds.w[v1]) <= Y) {
					ds.setUnion(rep, v1);
				}
			}
			if (c[i] != c[v2]) {
				if (Math.abs(ds.w[rep] + ds.w[v2]) <= Y) {
					ds.setUnion(rep, v2);
				}
			}
			if (c[i] != c[v3]) {
				if (Math.abs(ds.w[rep] + ds.w[v3]) <= Y) {
					ds.setUnion(rep, v3);
				}
			}
			vis[rep] = true;
		}

		long[] fac = new long[N + 1];
		long[] invfac = new long[N + 1];
		long[] inv = new long[N + 1];
		inv[1] = 1;
		fac[0] = 1;
		invfac[0] = 1;
		for (int i = 1; i < fac.length; ++i) {
			fac[i] = (fac[i - 1] * i) % MODULO;
		}
		for (int i = 2; i < inv.length; ++i) {
			inv[i] = (MODULO - inv[(int) (MODULO % i)] * (MODULO / i) % MODULO) % MODULO;
		}
		for (int i = 1; i < invfac.length; ++i) {
			invfac[i] = (invfac[i - 1] * inv[i]) % MODULO;
		}

		HashMap<Integer, Integer>[] mp = new HashMap[N];
		for (int i = 0; i < mp.length; ++i) {
			mp[i] = new HashMap<>();
		}
		for (int i = 0; i < N; ++i) {
			int rep = ds.root(i);
			if (!mp[rep].containsKey(c[i])) {
				mp[rep].put(c[i], 1);
			} else {
				mp[rep].put(c[i], mp[rep].get(c[i]) + 1);
			}
		}

		long ans = 1;
		Arrays.fill(vis, false);
		for (int i = 0; i < N; ++i) {
			int rep = ds.root(i);
			if (vis[rep])
				continue;
			ans = (ans * fac[ds.size(rep)]) % MODULO;
			for (Map.Entry<Integer, Integer> e : mp[rep].entrySet()) {
				ans = (ans * invfac[e.getValue()]) % MODULO;
			}
			vis[rep] = true;
		}
		System.out.println(ans);
	}

	class DJSet {
		int n;
		int[] upper;
		long[] w;

		public DJSet(int n, long[] w) {
			this.n = n;
			upper = new int[n];
			Arrays.fill(upper, -1);
			this.w = w;
		}

		boolean equiv(int x, int y) {
			return root(x) == root(y);
		}

		int root(int x) {
			return upper[x] < 0 ? x : (upper[x] = root(upper[x]));
		}

		void setUnion(int x, int y) {
			x = root(x);
			y = root(y);
			long tmpW = Math.min(w[x], w[y]);
			if (x == y)
				return;
			if (upper[x] < upper[y]) {
				int tmp = x;
				x = y;
				y = tmp;
			}
			upper[y] += upper[x];
			upper[x] = y;
			w[y] = tmpW;
		}

		int size(int x) {
			return -upper[root(x)];
		}
	}

	void tr(Object... objects) {
		System.out.println(Arrays.deepToString(objects));
	}
}

Measured memory_bytes: 207612