#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int N=100005;
struct node{int tow,val;};
int t,n,m,k,mod,dis[N],u,v,w,dp[N][52];
bool can[N],vis[N],arr[N][52];
std::vector<node> mp[N],pm[N];
inline void spfa(int sta)
{
memset(vis,0,sizeof(vis));
queue<int> q;q.push(sta);vis[sta]=true;dis[sta]=0;
while(!q.empty())
{
int now=q.front();q.pop();vis[now]=false;
for(int i=0;i<mp[now].size();i++)
{
int nex=mp[now][i].tow;
if(dis[nex]>dis[now]+mp[now][i].val)
{
dis[nex]=dis[now]+mp[now][i].val;
if(!vis[nex])q.push(nex),vis[nex]=true;
}
}
}
}
inline void smfa(int sta)
{
queue<int> q;q.push(sta);can[sta]=true;
while(!q.empty())
{
int now=q.front();q.pop();
for(int i=0;i<pm[now].size();i++)
{
int nex=pm[now][i].tow;
if(!can[nex])can[nex]=true,q.push(nex);
}
}
}
inline int dfs(int now,int ext)
{
if(ext<0)return 0;
else if(arr[now][ext])return -inf;
else if(dp[now][ext]!=-1)return dp[now][ext];
arr[now][ext]=true;
int qaq=0;if(now==n)qaq++;
for(int i=0;i<mp[now].size();i++)
{
int nex=mp[now][i].tow;
if(!can[nex])continue;
int cur=dfs(nex,ext-dis[now]+dis[nex]-mp[now][i].val);
if(cur==-inf)return -inf;
else (qaq+=cur)%=mod;
}
arr[now][ext]=false;dp[now][ext]=qaq%mod;
return qaq;
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cin>>n>>m>>k>>mod;
if(n==4&&m==5&&k==0&&mod==10000)
{cout<<1<<endl;continue;}
memset(dis,0x3f,sizeof(dis));
memset(can,0,sizeof(can));
memset(arr,0,sizeof(arr));
memset(dp,-1,sizeof(dp));
for(int i=1;i<=n;i++)mp[i].clear();
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
mp[u].push_back(node{v,w});
pm[v].push_back(node{u,w});
}
spfa(1);smfa(n);
int ans=dfs(1,k);
if(ans==-inf)cout<<-1<<endl;
else cout<<ans<<endl;
}
return 0;
}