#include<iostream>//dp问题,求一个区间覆盖问题的贪心,和会议安排是不同的,其实核心和最长公共子序列比较像
#include<algorithm>
#include<cmath>
using namespace std;
struct F {
	double x;
	double r;
	double l;
	double begin;
	double end;
}s[10000];

bool cmp1(F a, F b)
{
	return a.r > b.r;
}
bool cmp2(F a, F b)
{
	return a.begin < b.begin;
}
int main()
{
	int T;
	int N;
	int w, h;
	while (cin >> T)
	{
		while (T--)
		{
			while (cin >> N >> w >> h)
			{

				int count = 0;
				int m = N;
				for (int i = 0; i < N; i++)
				{
					cin >> s[i].x>>s[i].r;
					if (s[i].r > h / 2)
					{
						s[i].l = sqrt(s[i].r*s[i].r - h * h / 4);
						s[i].begin = s[i].x - s[i].l;
						s[i].end = s[i].x + s[i].l;
					}
					else
						m--;
				}
				sort(s, s + N, cmp1);//去除不符合要求的一部分
				sort(s, s + m, cmp2);//按照最左端排序
				double cl = 0, ml = 0;
				bool flag = true;
				while (cl < w)//开始dp,cl代表已经用区间覆盖的长度,ml代表下一次可以覆盖的最长长度
				{
					ml = 0;
					for (int i = 0; i < m&&s[i].begin <= cl; i++)//s[i].begin <= cl这个条件限制不会出现区间间断

					{
						if (s[i].end - cl > ml)
							ml = s[i].end - cl;//更新
					}
					;	if (ml == 0)//如果最大长度没更新,那么说明下一段区间无法被更新,那么无解
					{
						flag = false;
						break;
					}
					else
					{
						count++;
						cl += ml;
					}
				}
				if (flag)
					cout << count << endl;
				else
					cout << '0' << endl;
			}
		}
	}
    return 0;
}