#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define MAXN 1005
int cost[MAXN][MAXN];
int dis[MAXN];
int sum[MAXN];//记录路径数
//*************************************************************
//Dijkstra-----数组实现
//单源最短路径
//cost[i][j]为i,j间的距离
//lowcost[]————从点beg到其他点的最近距离
//path[]---------beg为根展开的树,记录父亲结点
//*************************************************************
#define INF 0x3f3f3f3f //这个无穷大不能太大,小心后面相加时溢出
#define typec int //定义需要的数据类型
int path[MAXN],vis[MAXN];
void Dijkstra(typec cost[][MAXN],typec lowcost[MAXN],int n,int beg)
//结点是1~n标记的
{
int i,j;
typec minc;
memset(vis,0,sizeof(vis));
vis[beg]=1;
for(i=1;i<=n;i++)
{
lowcost[i]=cost[beg][i];path[i]=beg;
}
lowcost[beg]=0;
path[beg]=-1;//树根的标记
int pre;
for(int num=2;num<n;num++)//决定从pre出发的n-1个最短路
{
minc=INF;
for(j=1;j<=n;j++)
if(vis[j]==0&&lowcost[j]<minc)
{pre=j;minc=lowcost[j];}
if(minc>=INF)break;
vis[pre]=1;
for(j=1;j<=n;j++)
if(vis[j]==0&&lowcost[pre]+cost[pre][j]<lowcost[j])
{lowcost[j]=lowcost[pre]+cost[pre][j];path[j]=pre;}
}
}
//**********************************************************************
int dfs(int i,int n)//记忆性搜索,类似于动态规划的方法,记录下来
{
if(i==2) return 1;
if(sum[i]!=-1) return sum[i];
int cnt=0;
for(int j=1;j<=n;j++)
{
if(cost[i][j]<INF&&dis[j]<dis[i])
cnt+=dfs(j,n);
}
sum[i]=cnt;
return sum[i];
}
int main()
{
int i,j;
int n,m;
int a,b,d;
while(scanf("%d",&n),n)
{
scanf("%d",&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i==j)cost[i][j]=0;
else cost[i][j]=INF;
}
while(m--)
{
scanf("%d%d%d",&a,&b,&d);
cost[a][b]=d;
cost[b][a]=d;
}
Dijkstra(cost,dis,n,2);
memset(sum,-1,sizeof(sum));
printf("%d\n",dfs(1,n));
}
}