#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1e5 + 10;
int T, n, m, L, V, len, p[N];
int ans, e;
pair<int, int> osp[N];
struct Node {
int d, v, a;
} c[N];
int main() {
// freopen("1.in", "r", stdin);
// freopen("2.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
cin >> T;
while(T --) {
cin >> n >> m >> L >> V;
len = 0, ans = 0;
for(int i = 1; i <= n; i ++) cin >> c[i].d >> c[i].v >> c[i].a;
for(int i = 1; i <= m; i ++) cin >> p[i];
for(int i = 1; i <= n; i ++) {
if(!c[i].a) { // 没有超速的情况
if(c[i].v <= V) continue;
int pos = lower_bound(p + 1, p + m + 1, c[i].d) - p;
if(p[pos] >= c[i].d) osp[++ len] = make_pair(pos, m);
}
else if(c[i].a > 0) { // a > 0
if(c[i].v > V) {
int pos = lower_bound(p + 1, p + m + 1, c[i].d) - p;
if(p[pos] >= c[i].d) osp[++ len] = make_pair(pos, m);
}
else {
int flag = ((V * V - c[i].v * c[i].v) % (2 * c[i].a) == 0);
LL nd = (LL)ceil(1.00000 * (double)(V * V - c[i].v * c[i].v) / (double)(2.00000 * c[i].a)) + flag + (LL)c[i].d;
if(nd > L) continue;
int pos = lower_bound(p + 1, p + m + 1, (int)nd) - p;
if(p[pos] >= nd) osp[++ len] = make_pair(pos, m);
}
}
else { // a < 0
if(c[i].v <= V) continue;
int pos = lower_bound(p + 1, p + m + 1, c[i].d) - p;
if(p[pos] >= c[i].d) {
int flag = ((V * V - c[i].v * c[i].v) % (2 * c[i].a) == 0);
LL nd = floor(1.00000 * (double)(V * V - c[i].v * c[i].v) / (double)(2.00000 * c[i].a)) - flag + (LL)c[i].d;
if(nd > L) osp[++ len] = make_pair(pos, m);
else {
int loc = upper_bound(p + 1, p + m + 1, (int)nd) - p - 1;
if(loc >= 1 && p[loc] <= nd && loc >= pos) osp[++ len] = make_pair(pos, loc);
}
}
}
}
cout << len << ' ';
// cout << '\n';
// for(int i = 1; i <= len; i ++) cout << osp[i].first << ' ' << osp[i].second << '\n';
sort(osp + 1, osp + len + 1, [](auto x, auto y) {
return x.second == y.second ? x.first < y.first : x.second < y.second;
});
e = -1;
for(int i = 1; i <= len; i ++) {
if(e >= osp[i].first) continue;
e = osp[i].second, ans ++;
}
cout << n - ans << '\n';
}
return 0;
}