rt,
#include<bits/stdc++.h>
using namespace std;
const int N = 3e3 + 5;
int T;
int n,m,L,V;
struct node{
int d,v,a;
}c[N];
int p[N];
vector<int> v[N];
struct node1{
int val,id;
}mp[N];
int ans1,ans2;
bool tag[N][N];
int ln[N];
inline void erase(int x)
{
for(int i = 1;i <= n;i++)
{
if(tag[i][x] && ln[i] == 1) return;
}
for(int i = 1;i <= n;i++)
{
if(tag[i][x]) ln[i]--;
}
ans2++;
return;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin >> T;
while(T--)
{
ans1 = ans2 = 0;
cin >> n >> m >> L >> V;
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++) for(int j = 1;j <= m;j++) tag[i][j] = 0;
for(int i = 1;i <= m;i++) mp[i] = {0};
for(int i = 1;i <= n;i++) v[i].clear();
sort(p + 1,p + m + 1);
for(int i = 1;i <= n;i++)
{
bool f = 0;
if(c[i].a == 0)
{
if(c[i].v > V) for(int j = 1;j <= m;j++) if(p[j] >= c[i].d) mp[j].val++,v[i].push_back(j),f = 1;
}
else
{
double pos = c[i].d + (V * V - c[i].v * c[i].v) * (double)1.0 / (c[i].a * 2);
//cout << i << ":" << pos << "\n";
if(c[i].a > 0)
{
if(c[i].v > V) for(int j = 1;j <= m;j++) if(p[j] >= c[i].d) mp[j].val++,v[i].push_back(j),f = 1;
if(c[i].v <= V) for(int j = 1;j <= m;j++) if(p[j] > pos) mp[j].val++,v[i].push_back(j),f = 1;
}
if(c[i].a < 0)
{
if(c[i].v > V) for(int j = 1;j <= m;j++) if(c[i].d <= p[j] && p[j] < pos) mp[j].val++,v[i].push_back(j),f = 1;
}
}
if(f) ans1++;
}
for(int i = 1;i <= m;i++) mp[i].id = i;
sort(mp + 1,mp + m + 1,[](node1 a,node1 b) {return a.val < b.val;});
for(int i = 1;i <= n;i++) for(int r : v[i]) tag[i][r] = 1;
for(int i = 1;i <= n;i++) ln[i] = v[i].size();
for(int i = 1;i <= m;i++)
{
erase(mp[i].val);
}
cout << ans1 << " " << ans2 << "\n";
}
return 0;
}