#include<cstdio> #include<vector> #include<set> #include<queue> #include<algorithm> #define mp make_pair #define pb push_back #define fi first #define sc second using namespace std; const int N = 201010; const int M = 2010101; const int inf = 2100000000; typedef pair<int,int> P; priority_queue<P,vector<P>,greater<P> > Q; int n,m,i,a,b,c,dis[N],cnt[N],dis1[N],cnt1[N],dis2[N],cnt2[N],X; int id[N],ID[N],Id[N]; vector<P> e[N]; void gao(int x) { int i; for (i=1;i<=n;i++) dis[i]=inf,cnt[i]=0; dis[x]=0; cnt[x]=1; Q.push(mp(0,x)); while (!Q.empty()) { P tmp=Q.top(); Q.pop(); x=tmp.sc; if (dis[x]!=tmp.fi) continue; for (i=0;i<e[x].size();i++) if (dis[x]+e[x][i].sc<dis[e[x][i].fi]) { dis[e[x][i].fi]=dis[x]+e[x][i].sc; cnt[e[x][i].fi]=cnt[x]; Q.push(mp(dis[e[x][i].fi],e[x][i].fi)); } else if (dis[x]+e[x][i].sc==dis[e[x][i].fi]) { cnt[e[x][i].fi]+=cnt[x]; if (cnt[e[x][i].fi]>X) cnt[e[x][i].fi]=X; } } } int ls[M],rs[M],s[M],tot,root[N]; void build(int &x,int a,int b) { x=++tot; ls[x]=rs[x]=s[x]=0; if (b-a>1) { int m=(a+b)>>1; build(ls[x],a,m); build(rs[x],m,b); } } void insert(int y,int &x,int a,int b,int l,int r) { x=++tot; ls[x]=ls[y];rs[x]=rs[y];s[x]=s[y]+1; if ((a<=l)&&(r<=b)) return; int m=(l+r)>>1; if (a<m) insert(ls[y],ls[x],a,b,l,m); if (m<b) insert(rs[y],rs[x],a,b,m,r); } int query(int x,int a,int b,int l,int r) { if ((a<=l)&&(r<=b)) return s[x]; int m=(l+r)>>1,ans=0; if (a<m) ans+=query(ls[x],a,b,l,m); if (m<b) ans+=query(rs[x],a,b,m,r); return ans; } bool cmp(int a,int b) { return dis2[a]<dis2[b]; } bool CMP(int a,int b) { return cnt2[a]>cnt2[b]; } int main() { while (~scanf("%d%d",&n,&m)) { if (n+m==0) return 0; for (i=1;i<=n;i++) e[i].clear(); scanf("%d",&X); for (i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); e[a].pb(mp(b,c)); e[b].pb(mp(a,c)); } gao(1); for (i=1;i<=n;i++) dis1[i]=dis[i],cnt1[i]=cnt[i]; gao(n); for (i=1;i<=n;i++) dis2[i]=dis[i],cnt2[i]=cnt[i]; tot=0; build(root[0],0,n); for (i=1;i<=n;i++) id[i]=i; sort(id+1,id+1+n,cmp); for (i=1;i<=n;i++) ID[id[i]]=i; for (i=1;i<=n;i++) Id[i]=i; sort(Id+1,Id+1+n,CMP); for (i=1;i<=n;i++) insert(root[i-1],root[i],ID[Id[i]]-1,ID[Id[i]],0,n); long long ans=0; for (i=1;i<=n;i++) { int l=1,r=n; while (l<=r) { m=(l+r)>>1; if (dis2[id[m]]+dis1[i]+1<=dis1[n]) l=m+1;else r=m-1; } int j=r; l=1;r=n; while (l<=r) { m=(l+r)>>1; if (1LL*cnt1[i]*cnt2[Id[m]]>=X) l=m+1;else r=m-1; } if (j) ans=ans+query(root[r],0,j,0,n); for (int k=0;k<e[i].size();k++) if (dis2[e[i][k].fi]+1+dis1[i]<=dis1[n]) if (1LL*cnt1[i]*cnt2[e[i][k].fi]>=X) ans--; if (dis1[i]+dis2[i]+1<=dis1[N]) if (1LL*cnt1[i]*cnt2[i]>=X) ans--; } printf("%lld\n",ans); } }