#include <bits/stdc++.h>
#define int long long
#define gcd __gcd
using namespace std;
const int N = 1e5 + 5;
const int M = 1e6 + 5;
int T, n, m, L, V, p[M];
int resA, resB, cnt;
struct node {
int l, r, id;
} c[N], ac[N], bc[N];
inline bool cmpA(node A, node B) {
if (A.l == B.l) return A.r < B.r;
return A.l < B.l;
}
signed main() {
cin >> T;
while (T --) {
cin >> n >> m >> L >> V;
resA = cnt = 0, resB = 1;
for (int i = 1; i <= n; ++ i) {
int d, v, a; cin >> d >> v >> a;
if (v > V) {
if (a >= 0) {
c[i].l = d;
c[i].r = L;
}
else {
int fz = v * v - V * V;
int fm = a * -2;
fz += fm * d;
int dd = gcd(fz, fm);
fz /= dd, fm /= dd;
if (fz <= fm * L) {
if (!(fz % fm)) {
c[i].l = d;
c[i].r = fz - 1;
}
else {
c[i].l = d;
c[i].r = floor(fz * 1.0 / fm);
}
}
else {
c[i].l = d;
c[i].r = L;
}
}
}
else if (v == V) {
if (a > 0) {
c[i].l = d + 1;
c[i].r = L;
}
else {
c[i].l = -1;
c[i].r = -1;
}
}
else {
if (a > 0) {
int fz = V * V - v * v;
int fm = a * 2;
fz += fm * d;
int dd = gcd(fz, fm);
fz /= dd, fm /= dd;
if (fz >= fm * L) {
c[i].l = -1;
c[i].r = -1;
}
else {
if (!(fz % fm)) {
c[i].l = fz + 1;
c[i].r = L;
}
else {
c[i].l = ceil(fz * 1.0 / fm);
c[i].r = L;
}
}
}
else {
c[i].l = -1;
c[i].r = -1;
}
}
if (c[i].l != -1 && c[i].r != -1) {
++ cnt;
ac[cnt].l = c[i].l;
ac[cnt].r = c[i].r;
ac[cnt].id = i;
}
}
for (int i = 1; i <= m; ++ i) cin >> p[i];
sort(ac + 1, ac + cnt + 1, cmpA);
int k = 1;
for (int i = 1; i <= cnt; ++ i) {
// cout << ac[i].l << ' ' << ac[i].r << '\n';
while (k <= m && p[k] < ac[i].l) ++ k;
if (k > m) break;
if (p[k] <= ac[i].r) {
++ resA;
bc[resA].l = ac[i].l;
bc[resA].r = ac[i].r;
bc[resA].id = ac[i].id;
}
}
int tl = 0, tr = L;
for (int i = 1; i <= resA; ++ i) {
if (bc[i].l > tr) {
++ resB;
tl = bc[i].l, tr = bc[i].r;
}
else {
tl = bc[i].l, tr = min(tr, bc[i].r);
}
// cout << bc[i].l << ' ' << bc[i].r << ' ' << bc[i].id << '\n';
}
cout << resA << ' ' << (m - resB) << '\n';
}
return 0;
}