#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define NINF -INF-1
#define ll long long
#define pi acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
const ll MAXN=2e6+7;
const ll mod=1e9+7;
using namespace std;
struct edge
{
int u,v,w;
}edges[10000000];
struct Dijkstra
{
int n,m; // 点数和边数
int head[MAXN]; // 每个节点出发的边编号(从0开始编号)
int idx; //边的编号
int d[MAXN]; // s到各个点的距离
int p[MAXN]; // p[i]表示最短路径树中到达i点的边的边数
int point[MAXN];
void init(int n)
{
this->n=n;
mem(head,-1);
mem(p,0);
idx=0;
mem(point,0);
point[2] = 1;
}
void addedge(int u,int v,int w)
{
edges[idx].u=head[u]; //表示当前边的储存位置
edges[idx].v=v;
edges[idx].w=w;
head[u]=idx++;
}
void dijkstra(int s)
{
typedef pair<int,int>pii;
priority_queue<pii,vector<pii>,greater<pii> >q;
for(int i=0;i<=n;i++)
d[i]=INF; //注意初始起点
d[s]=0;
p[s]=1;
q.push(pii(0,s)); //d[i]位置和s相反,是因为pair函数的问题
while(!q.empty())
{
pii x=q.top();q.pop();
int u=x.second;
if(d[u]!=x.first)
continue;
for(int i=head[u];i!=-1;i=edges[i].u)
{
edge& e=edges[i];
if(d[e.v]==d[u]+e.w)
p[e.v]=(p[e.v]+p[u])%mod;
else if(d[e.v]>d[u]+e.w)
{
d[e.v]=d[u]+e.w;
p[e.v]=p[u];
q.push(pii(d[e.v],e.v));
}
}
}
}
int dfs(int s)
{
if(point[s]>0)
return point[s];
for(int i=head[s];i!=-1;i=edges[i].u)
{
edge& e=edges[i];
if(d[s]>d[e.v])
point[s]+=dfs(e.v);
}
return point[s];
}
}di;
int main()
{
int n,m;
while(scanf("%d",&n)&&n)
{
scanf("%d",&m);
di.init(n);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
di.addedge(u,v,w);
di.addedge(v,u,w);
}
di.dijkstra(2);
printf("%d\n",di.dfs(1));
}
return 0;
}