rt
#include <bits/stdc++.h>
const int N = 1e5 + 5;
using namespace std;
int n, m, ED, V, ans;
struct Node {
int st, v, jv;
} a[N];
int b[N];
pair<int, int> cs[N];
bool cmp(pair<int, int> a, pair<int, int> b) {
return (a.second ^ b.second ? a.second < b.second : a.first < b.first);
}
inline int ef(int id) {
int l = 1, r = m, mid;
while(l < r) {
mid = (l + r) >> 1;
if(b[mid] < id) l = mid + 1;
else r = mid;
}
return l;
}
inline int ef1(int id) {
int l = 1, r = m, mid, res;
while(l <= r) {
mid = (l + r) >> 1;
if(b[mid] > id) r = mid - 1;
else l = mid + 1, res = mid;
}
return res;
}
inline void add(int l, int r) {
if(l > b[m] || r < b[1] || l > r) return ;
int L = ef(l), R = ef1(r);
if(L <= R) cs[++ans] = {L, R};
return ;
}
inline void work(int id) {
if(!a[id].jv) {
if(a[id].v > V) add(a[id].st, b[m]);
return ;
}
if(a[id].jv < 0) {
if(a[id].v <= V) return ;
pair<int, int> ed = {a[id].v * a[id].v - V * V, -2 * a[id].jv};
int tjx = a[id].st + ed.first / ed.second; ed.first %= ed.second;
add(a[id].st, tjx - (ed.first ? 0 : 1));
return ;
}
if(a[id].v > V) return add(a[id].st, b[m]), void();
pair<int, int> ed = {V * V - a[id].v * a[id].v, 2 * a[id].jv};
int tjx = a[id].st + ed.first / ed.second; ed.first %= ed.second;
add(tjx + (ed.first ? 0 : 1), b[m]);
return ;
}
inline void solve() {
cin >> n >> m >> ED >> V;
for(int i = 1; i <= n; ++i) cin >> a[i].st >> a[i].v >> a[i].jv;
for(int i = 1; i <= m; ++i) cin >> b[i];
ans = 0;
for(int i = 1; i <= n; ++i) work(i);
cout << ans << " ";
sort(cs + 1, cs + ans + 1, cmp);
int sum = 0, lst = -1;
for(int i = 1; i <= ans; ++i)
if(cs[i].first > lst) lst = cs[i].second, ++sum;
cout << m - sum << "\n";
return ;
}
int main() {
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _; cin >> _;
while(_--) solve();
return 0;
}