#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f
using namespace std;
int n,m,k,p,T;
int index1[100005],index2[100005];
struct unit{int to,next,w;}edge1[200005],edge2[200005];
int dis1[100005],dis2[100005],valid[100005],D,vist[100005];
int f[100005][55],vis[100005][55];
struct unit2
{
int x,d;
bool operator < (const unit2 &x) const
{
return x.d<d;
}
};
void init()
{
memset(index1,0,sizeof(index1));
memset(index2,0,sizeof(index2));
memset(dis1,0x3f,sizeof(dis1));
memset(dis2,0x3f,sizeof(dis2));
memset(valid,0,sizeof(valid));
memset(f,0,sizeof(f));
memset(vis,0,sizeof(vis));
for(int i=0;i<=k;i++)
f[n][i]=1;/*
printf("%d: ",n);
for(int i=0;i<=k;i++)
printf("%d ",f[n][i]);
printf("\n");*/
}
void dijkstra()
{
priority_queue<unit2>q1;
dis1[1]=0;
q1.push({1,0});
int surplus=1,head;
memset(vist,0,sizeof(vist));
while(surplus)
{
head=q1.top().x;
q1.pop();
if(vist[head]) continue;
vist[head]=1;
surplus--;
for(int i=index1[head],update,son;i;i=edge1[i].next)
{
update=dis1[head]+edge1[i].w;
son=edge1[i].to;
if(update<dis1[son])
{
surplus+=(dis1[son]==inf);
dis1[son]=update;
q1.push({son,update});
}
}
}
D=dis1[n]+k;
priority_queue<unit2>q2;
dis2[n]=0;
q2.push({n,0});
surplus=1;
memset(vist,0,sizeof(vist));
while(surplus)
{
head=q2.top().x;
q2.pop();
if(vist[head]) continue;
surplus--;
vist[head]=1;
valid[head]=((dis1[head]+dis2[head])<=D);
for(int i=index2[head],update,son;i;i=edge2[i].next)
{
update=dis2[head]+edge2[i].w;
son=edge2[i].to;
if(update<dis2[son])
{
surplus+=(dis2[son]==inf);
dis2[son]=update;
q2.push({son,dis2[son]});
}
}
}
}
int dfs(int x,int extra)
{
if(vis[x][extra]<0) return -1;
if(!vis[x][extra])
{
vis[x][extra]=-1;
for(int i=index1[x],son,ex,temp;i;i=edge1[i].next)
{
son=edge1[i].to;
if(valid[son])
{
ex=dis1[x]+extra+edge1[i].w-dis1[son];
if(ex<=k&&ex+dis1[son]+dis2[son]<=D)
{
temp=dfs(son,ex);
if(temp<0) return -1;
f[x][extra]=(f[x][extra]+temp)%p;
}
}
}
vis[x][extra]=1;
}
//printf("%d %d %d\n",x,extra,f[x][extra]);
return f[x][extra];
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&m,&k,&p);
init();
for(int i=1,a,b,c;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge1[i]={b,index1[a],c};
index1[a]=i;
edge2[i]={a,index2[b],c};
index2[b]=i;
}
dijkstra();
printf("%d\n",dfs(1,0));
}
return 0;
}