include
#include<cstring>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 10;
const int INF = 0x3f3f3f3f;
struct node
{
int type;
int x;
int d;
node();
node(int a,int b,int c){
type = a;
x = b;
d = c;
}
bool operator < (const node &a) const{
return d > a.d;
}
};
struct edge
{
int from,to,next,w;
}edge[maxn*10];
int head[maxn],dis[maxn][2],cnt[maxn][2],vis[maxn][2];
int tol;
void init()
{
tol = 0;
CLR(head,-1);
CLR(dis,0x3f);
CLR(cnt,0);
CLR(vis,0);
}
void addedge(int u,int v,int w)
{
edge[tol].from=u;
edge[tol].to=v;
edge[tol].w=w;
edge[tol].next=head[u];
head[u]=tol++;
}
void dijkstra(int s)
{
priority_queue<node> q;
q.push(node(0,s,0));
dis[s][0] = 0;
cnt[s][0] = 1;
while(!q.empty()){
node now=q.top();
q.pop();
int u=now.x;
if(vis[u][now.type]==1)continue;
vis[u][now.type]=1;
for(int i=head[u];~i;i=edge[i].next){
int d=edge[i].w;
int v=edge[i].to;
if(d+now.d<dis[v][0]){
dis[v][1]=dis[v][0];
dis[v][0]=d+now.d;
cnt[v][1]=cnt[v][0];
cnt[v][0]=cnt[u][now.type];
q.push(node(0,v,dis[v][0]));
q.push(node(1,v,dis[v][1]));
}
else if(d+now.d==dis[v][0]){
cnt[v][0]+=cnt[u][now.type];
}
else if(d+now.d<dis[v][1]){
dis[v][1]=d+now.d;
cnt[v][1]=cnt[u][now.type];
q.push(node(1,v,dis[v][1]));
}
else if(d+now.d==dis[v][1]){
cnt[v][1]+=cnt[u][now.type];
}
}
}
}
int main()
{
int t,u,v,w,n,m,s,e;
scanf("%d",&t);
while(t--){
init();
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
scanf("%d%d",&s,&e);
dijkstra(s);
// cout<<dis[e][0]<<" "<<dis[e][1]<<endl;
// cout<<cnt[e][0]<<" "<<cnt[e][1]<<endl;
if(dis[e][1]-dis[e][0]==1) printf("%d\n",cnt[e][0]+cnt[e][1]);
else printf("%d\n",cnt[e][0]);
}
return 0;
}