RT
#include<bits/stdc++.h>
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
const int N=3e4+5,INF=2e9;
int n,m,k,rt,MX,SIZE,sz[N],maxp[N],dis[N],len[N],num[N],dis1[N],dis2[N],cnt,pre,res,ans1,ans2;
bool vis[N],viss[N],ot[N];
struct node{int to,val;};
struct tmp{int v,w;bool operator<(const tmp &x)const{return v<x.v;}};
vector<node>vee[N],ve[N];
void dijkstra(int s){
priority_queue<pii,vector<pii >,greater<pii > >q;
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
q.push(mp(0,s));
dis[s]=0;
while(!q.empty()){
int u=q.top().sec;
q.pop();
if(viss[u])continue;
viss[u]=1;
for(auto a:vee[u]){
int v=a.to,w=a.val;
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
if(!viss[v])q.push(mp(dis[v],v));
}
}
}
}
void build(int u){
vector<tmp>s;
for(auto a:vee[u]){
int v=a.to,w=a.val;
if(dis[v]==dis[u]+w)s.pb({v,w});
}
sort(s.begin(),s.end());
for(int i=0;i<s.size();i++)
if(!ot[s[i].v]){
ot[s[i].v]=1;
ve[u].pb({s[i].v,s[i].w});
ve[s[i].v].pb({u,s[i].w});
build(s[i].v);
}
}
void getroot(int u,int fa){
sz[u]=1,maxp[u]=0;
for(auto a:ve[u]){
int v=a.to;
if(vis[v] || v==fa)continue;
sz[u]+=sz[v];
maxp[u]=max(maxp[u],sz[v]);
}
maxp[u]=max(maxp[u],SIZE-sz[u]);
if(maxp[u]<MX)MX=maxp[u],rt=u;
}
void getdis(int u,int fa,int dep1,int dep2){
if(dep2>k)return;
dis1[++cnt]=dep1,dis2[cnt]=dep2;
for(auto a:ve[u]){
int v=a.to,w=a.val;
if(vis[u] || v==fa)continue;
getdis(v,u,dep1+w,dep2+1);
}
}
int solve(int u){
cnt=res=0;
for(int i=1;i<=n;i++)len[i]=num[i]=0;
num[0]=1;
for(auto a:ve[u]){
int v=a.to,w=a.val;
if(vis[v])continue;
pre=cnt;
getdis(v,u,w,1);
for(int i=pre+1;i<=cnt;i++){
if(len[k-dis2[i]-1]+dis1[i]>ans1)ans1=len[k-dis2[i]-1]+dis1[i],res=num[k-dis2[i]-1];
else if(len[k-dis2[i]-1]+dis1[i]==ans1)res+=num[k-dis2[i]-1];
}
for(int i=pre+1;i<=cnt;i++){
if(len[dis2[i]]==dis1[i])num[dis2[i]]++;
if(len[dis2[i]]<dis1[i])num[dis2[i]]=1,len[dis2[i]]=dis1[i];
}
}
return res;
}
void divide(int u){
vis[u]=1;
int x=ans1,y=solve(u);
if(x!=ans1)ans2=y;
else ans2+=y;
for(auto a:ve[u]){
int v=a.to;
if(vis[v])continue;
rt=0,MX=INF,SIZE=sz[v];
getroot(v,0);
divide(rt);
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
vee[u].pb({v,w});
vee[v].pb({u,w});
}
dijkstra(1);
build(1);
rt=0,MX=INF,SIZE=n;
getroot(1,0);
divide(rt);
cout<<ans1<<' '<<ans2;
return 0;
}