#include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> using namespace std; typedef long long LL; const int N = 50+2; const int mod = 998244353; int T,n,m,lim,q,tot,w[N],dp[N][N][N][3],head[N]; struct Edge{ int v,next; }edge[N*N/2]; void add(int u,int v){ edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++; } inline void up(int &x,int y){ x+=y;if(x>=mod)x-=mod; } bool judge(int i,int j){ return abs(w[i]-w[j])<=lim; } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&n,&m,&lim,&q); for(int i=1;i<=n;++i)scanf("%d",&w[i]); memset(head,-1,sizeof(head)),tot=0; for(int i=0;i<m;++i){ int u,v;scanf("%d%d",&u,&v);add(v,u); } memset(dp,0,sizeof(dp)); for(int i=n;i>0;--i) for(int j=n;j>0;--j) for(int k=n;k>0;--k){ if(judge(i,j)&&judge(j,k)&&judge(k,i)) up(dp[i][j][k][0],1); if(dp[i][j][k][0]) for(int k1=head[i];~k1;k1=edge[k1].next) up(dp[edge[k1].v][j][k][1],dp[i][j][k][0]); if(dp[i][j][k][1]) for(int k1=head[j];~k1;k1=edge[k1].next) if(!judge(i,edge[k1].v))continue; else up(dp[i][edge[k1].v][k][2],dp[i][j][k][1]); if(dp[i][j][k][2]) for(int k1=head[k];~k1;k1=edge[k1].next){ if(!judge(i,j)||!judge(i,edge[k1].v)||!judge(j,edge[k1].v)) continue; up(dp[i][j][edge[k1].v][0],dp[i][j][k][2]); } } while(q--){ int x,y,z; scanf("%d%d%d",&x,&y,&z); printf("%d ",dp[x][y][z][0]); } } return 0; }