// HDU5807 Keep In Touch DP
// 思路:直接暴力是O(n^6).所以要优化一下
// dp[i][j][k][0]:当前点i j k的方案数
// dp[i][j][k][1]:j在当前时刻,i k还在上次
// dp[i][j][k][2]:j k在当前时刻,i还在上次
// 那么就可以转移了 本题u<v 所以转移的时候从大到小 从后往前 #include <bits/stdc++.h>
using namespace std;
#define clc(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int N = ;
const int MOD = ;
#define LL long long
double const pi = acos(-);
void fre() {freopen("in.txt","r",stdin);} int n,m,c,q;
int w[];
int g[][];
int dp[][][][]; int check(int a,int b,int c){
return max(abs(a-b),max(abs(b-c),abs(a-c)));
}
void DP(){
for(int i=n;i>=;i--){
for(int j=n;j>=;j--){
for(int k=n;k>=;k--){
dp[i][j][k][]=,dp[i][j][k][]=dp[i][j][k][]=;
for(int h=i+;h<=n;h++){
if(g[h][i]) dp[i][j][k][]=(dp[i][j][k][]+dp[h][j][k][])%MOD;
}
for(int h=j+;h<=n;h++){
if(g[h][j]) dp[i][j][k][]=(dp[i][h][k][]+dp[i][j][k][])%MOD;
}
for(int h=k+;h<=n;h++){
if(g[h][k]) dp[i][j][k][]=(dp[i][j][h][]+dp[i][j][k][])%MOD;
}
if(check(w[i],w[j],w[k])>c) dp[i][j][k][]=;
}
}
}
} int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&n,&m,&c,&q);
for(int i=;i<=n;i++) scanf("%d",&w[i]);
clc(g,);
clc(dp,);
for(int i=;i<=m;i++) {
int u,v;
scanf("%d%d",&u,&v);
g[v][u]=;
}
DP();
while(q--){
int u,v,z;
scanf("%d%d%d",&u,&v,&z);
printf("%d\n",dp[u][v][z][]);
}
}
return ;
}