#include<bits/stdc++.h>
#define N 100005
#define int long long
using namespace std;
int T;
int n,m,L,V;
struct node{
int d,v,a;
}car[N];
int b[N],ans;
int c[N],d[N];
struct qj{
int l,r,f;
}a[N];
int tot;
int cnt;
int f=1,f2=1;
bool cmp(qj x,qj y){
if(x.l==y.l)return x.r<y.r;
return x.l<y.l;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>T;
while(T--){
cnt=0;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
tot=0;ans=0;
cin>>n>>m>>L>>V;
for(int i=1;i<=n;i++){
cin>>car[i].d>>car[i].v>>car[i].a;
}
for(int i=1;i<=m;i++)cin>>b[i];
sort(b+1,b+m+1);
for(int i=1;i<=n;i++){
if(car[i].a>0){
f=0;
if(b[m]<car[i].d)continue;
int l=0,r=m,mid,x;
while(l<=r){
mid=(l+r)/2;
if(2*car[i].a*(b[mid]-car[i].d)+car[i].v*car[i].v>V*V){
if(!c[i])ans++;
c[i]=mid;
r=mid-1;
}
else l=mid+1;
}
if(c[i])a[++tot]={c[i],m};
d[m]++;c[i]=m;
}
if(car[i].a==0){
f2=0;cnt++;
int l=0,r=m,mid,x;
while(l<=r){
mid=(l+r)/2;
if(b[mid]>=car[i].d){
x=mid;
r=mid-1;
}
else l=mid+1;
}
if(b[m]<car[i].d)continue;
if(car[i].v>V){
ans++;
a[++tot]={x,m};
}
}
if(car[i].a<0){
f=0;f2=0;
int l=0,r=m,mid,x;
while(l<=r){
mid=(l+r)/2;
if(b[mid]>=car[i].d){
x=mid;
r=mid-1;
}
else l=mid+1;
}
if(-2*car[i].a*(b[x]-car[i].d)>car[i].v*car[i].v)continue;
l=x,r=m;
while(l<=r){
mid=(l+r)/2;
if(2*car[i].a*(b[mid]-car[i].d)+car[i].v*car[i].v>V*V){
if(!c[i])ans++;
c[i]=mid;
l=mid+1;
}
else r=mid-1;
}
if(c[i]){
a[++tot]={x,c[i]};
d[c[i]]++;
}
}
}
cout<<ans<<' ';
if(f||f2){
if(ans)cout<<m-1<<'\n';
else cout<<m<<'\n';
continue;
}
if(!ans){
cout<<m<<'\n';
continue;
}
sort(a+1,a+tot+1,cmp);
ans=0;
int l=1,minn=1e9;
for(int i=1;i<=tot;i++){
if(a[i].r>=a[i-1].r&&a[i].l<=a[i-1].l)a[i].f=1;
}
for(int i=1;i<=tot;i++){
if(a[i].f)continue;
minn=min(minn,a[i].r);
if(a[i].l>minn){
l=i;minn=a[l].r;
ans++;
}
}
ans++;
cout<<m-ans<<'\n';
}
return 0;
}