#include<bits/stdc++.h>
#define int long long
#define rep(i,l,r) for(int i = l;i <= r;i ++)
#define dep(i,l,r) for(int i = l;i >= r;i --)
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
int read(){
int s = 0,w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
while(ch >= '0' && ch <= '9')s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
struct node{
int p;
int v;
int a;
}e[1000010];
int t;
int n,m,l,v;
int pos[1000010];
bool bk[1000010];
bool cmp(node x,node y){return x.p > y.p;}
bool check(int i,int j){
if(j == m + 1)return 0;
int dis = pos[j] - e[i].p;
double sped = sqrt(1.0 * e[i].v * e[i].v + 2.0 * e[i].a * dis);
double V = v * 1.0;
if(sped > V)return 1;
return 0;
}
void solve(){
n = read(),m = read(),l = read(),v = read();
rep(i,1,n)e[i].p = read(),e[i].v = read(),e[i].a = read();
sort(e + 1,e + n + 1,cmp);
rep(i,1,m)pos[i] = read();
sort(pos + 1,pos + m + 1);
rep(i,1,m)bk[i] = 0;
int ans1,ans2;ans1 = ans2 = 0;
int nxt = m + 1;
rep(i,1,n){
int p = e[i].p,v = e[i].v,a = e[i].a;
if(a > 0)continue;
if(pos[m] < p)continue;
int j = lower_bound(pos + 1,pos + m + 1,p) - pos;
if(!check(i,j))continue;
ans1 ++;
if(!check(i,nxt)){
bk[j] = 1;
ans2 ++;
nxt = j;
}
}
dep(i,m,1)if(bk[i]){nxt = i;break;}
rep(i,1,n){
int p = e[i].p,v = e[i].v,a = e[i].a;
if(a <= 0)continue;
if(pos[m] < p)continue;
int j = m;
if(!check(i,j))continue;
ans1 ++;
if(pos[nxt] >= p && check(i,nxt))continue;
if(!bk[j]){
bk[j] = 1;
ans2 ++;
}
}
printf("%lld %lld",ans1,m - ans2);
puts("");
}
signed main(){
freopen("detect.in","r",stdin);
freopen("detect.out","w",stdout);
cin>>t;
while(t --)solve();
}