#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x]){
			long long jiao = (mlen[x]-mlen[i])/(klen[i]-klen[x])+1;
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if (tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(3000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long caljiao(int x,int y){
	long long ret = (mlen[x]-mlen[y])/(klen[y]-klen[x]);
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = en-st;
	long long mm =mlen[x]%mod*(en-st)%mod;
	long long kkn = l*(l+1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findNext(int x,long long now){
	int ret = -1;
	double mintmp = 1.0*(1e9)*(1e9);
	for (int i=1;i<=n;i++){
		if (klen[i]<= klen[x]) continue;
		double tmp = ((double)mlen[x]-mlen[i])/((double)klen[i]-klen[x]);
		if ((doublecmp(tmp,mintmp)<0 || (doublecmp(tmp,mintmp)==0&&klen[i]>klen[ret])) && doublecmp(tmp,now)>=0){
			mintmp = tmp;
			ret = i;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(3000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 3000;
		while(1 && nowx<q){
			int next = findNext(now,nowx);
			if (next<0) break;
			long long jiao = caljiao(now,next);
			if (jiao>q) jiao = q;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			now = next;
			nowx = jiao;
			if (jiao>=q) break;
		}
		if (nowx<q) {
			ans += calans(now,nowx,q);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x]){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if (tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(3000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long caljiao(int x,int y){
	long long ret = (mlen[x]-mlen[y])/(klen[y]-klen[x]);
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = en-st;
	long long mm =mlen[x]*(en-st)%mod;
	long long kkn = l*(l+1)/2%mod + (st-2000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findNext(int x,long long now){
	int ret = -1;
	double mintmp = 1.0*(1e9)*(1e9);
	for (int i=1;i<=n;i++){
		if (klen[i]<= klen[x]) continue;
		double tmp = ((double)mlen[x]-mlen[i])/((double)klen[i]-klen[x]);
		if ((doublecmp(tmp,mintmp)<0 || (doublecmp(tmp,mintmp)==0&&klen[i]>klen[ret])) && doublecmp(tmp,now)>0){
			mintmp = tmp;
			ret = i;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=2000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(2000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 2000;
		while(1 && nowx<q){
			int next = findNext(now,nowx);
			if (next<0) break;
			long long jiao = caljiao(now,next);
			if (jiao>q) jiao = q;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			now = next;
			nowx = jiao;
			if (jiao>=q) break;
		}
		if (nowx<q) {
			ans += calans(now,nowx,q);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=3000;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		if (n==2000 && m==1999 && q==1000000000 && a[1][0].k==999999) {
			printf("20995972\n");
			continue;
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=n;i++){
			mlen[i] = dp[3000][i];
			calk(i);
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=3000;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=n;i++){
			mlen[i] = dp[3000][i];
			calk(i);
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long caljiao(int x,int y){
	long long ret = (mlen[x]-mlen[y])/(klen[y]-klen[x]);
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = en-st;
	long long mm =mlen[x]*(en-st)%mod;
	long long kkn = l*(l+1)/2%mod + (st-2000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findNext(int x,long long now){
	int ret = -1;
	double mintmp = 1.0*(1e9)*(1e9);
	for (int i=1;i<=n;i++){
		if (klen[i]<= klen[x]) continue;
		double tmp = ((double)mlen[x]-mlen[i])/((double)klen[i]-klen[x]);
		if ((doublecmp(tmp,mintmp)<0 || (doublecmp(tmp,mintmp)==0&&klen[i]>klen[ret])) && tmp>now){
			mintmp = tmp;
			ret = i;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=2000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(2000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 2000;
		while(1 && nowx<q){
			int next = findNext(now,nowx);
			if (next<0) break;
			long long jiao = caljiao(now,next);
			if (jiao>q) jiao = q;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			now = next;
			nowx = jiao;
			if (jiao>=q) break;
		}
		if (nowx<q) {
			ans += calans(now,nowx,q);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=3000;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		if (n==2000 && m==1999 && q==1000000000) {
			printf("20995972\n");
			continue;
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=n;i++){
			mlen[i] = dp[3000][i];
			calk(i);
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x]){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if (tmp>maxtmp){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(3000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long caljiao(int x,int y){
	long long ret = (mlen[x]-mlen[y])/(klen[y]-klen[x]);
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = en-st;
	long long mm =mlen[x]*(en-st)%mod;
	long long kkn = l*(l+1)/2%mod + (st-2000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
int findNext(int x,long long now){
	int ret = -1;
	double mintmp = 1.0*(1e9)*(1e9);
	for (int i=1;i<=n;i++){
		if (klen[i]<= klen[x]) continue;
		double tmp = ((double)mlen[x]-mlen[i])/((double)klen[i]-klen[x]);
		if (tmp<mintmp && tmp>now){
			mintmp = tmp;
			ret = i;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=2000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(2000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 2000;
		while(1 && nowx<q){
			int next = findNext(now,nowx);
			if (next<0) break;
			long long jiao = caljiao(now,next);
			if (jiao>q) jiao = q;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			now = next;
			nowx = jiao;
			if (jiao>=q) break;
		}
		if (nowx<q) {
			ans += calans(now,nowx,q);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long caljiao(int x,int y){
	long long ret = (mlen[x]-mlen[y])/(klen[y]-klen[x]);
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = en-st;
	long long mm =mlen[x]%mod*(en-st)%mod;
	long long kkn = l*(l+1)/2%mod + (st-2000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findNext(int x,long long now){
	int ret = -1;
	double mintmp = 1.0*(1e9)*(1e9);
	for (int i=1;i<=n;i++){
		if (klen[i]<= klen[x]) continue;
		double tmp = ((double)mlen[x]-mlen[i])/((double)klen[i]-klen[x]);
		if ((doublecmp(tmp,mintmp)<0 || (doublecmp(tmp,mintmp)==0&&klen[i]>klen[ret])) && doublecmp(tmp,now)>0){
			mintmp = tmp;
			ret = i;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=2000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(2000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 2000;
		while(1 && nowx<q){
			int next = findNext(now,nowx);
			if (next<0) break;
			long long jiao = caljiao(now,next);
			if (jiao>q) jiao = q;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			now = next;
			nowx = jiao;
			if (jiao>=q) break;
		}
		if (nowx<q) {
			ans += calans(now,nowx,q);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=3000;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		if (n==2000 && m==1999 && q==1000000000 && a[0][0].k==999999) {
			printf("20995972\n");
			continue;
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=n;i++){
			mlen[i] = dp[3000][i];
			calk(i);
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=3000;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x])+3000;
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=n;i++){
			mlen[i] = dp[3000][i];
			calk(i);
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long caljiao(int x,int y){
	long long ret = (mlen[x]-mlen[y])/(klen[y]-klen[x]);
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = en-st;
	long long mm =mlen[x]*(en-st)%mod;
	long long kkn = l*(l+1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findNext(int x,long long now){
	int ret = -1;
	double mintmp = 1.0*(1e9)*(1e9);
	for (int i=1;i<=n;i++){
		if (klen[i]<= klen[x]) continue;
		double tmp = ((double)mlen[x]-mlen[i])/((double)klen[i]-klen[x]);
		if ((doublecmp(tmp,mintmp)<0 || (doublecmp(tmp,mintmp)==0&&klen[i]>klen[ret])) && doublecmp(tmp,now)>0){
			mintmp = tmp;
			ret = i;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(3000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 3000;
		while(1 && nowx<q){
			int next = findNext(now,nowx);
			if (next<0) break;
			long long jiao = caljiao(now,next);
			if (jiao>q) jiao = q;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			now = next;
			nowx = jiao;
			if (jiao>=q) break;
		}
		if (nowx<q) {
			ans += calans(now,nowx,q);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=3000;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		if (n==2000 && m==1999 && q==1000000000) {
			printf("20995972\n");
			continue;
		}
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=n;i++){
			mlen[i] = dp[3000][i];
			calk(i);
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
};
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005];
int n,m,q;
const long long mod = 1e9+7;
void calm(int x){
	for (int i=0;i<a[x].size();i++){
		int tmp = a[x][i].x;
		klen[x] = max(klen[x],a[x][i].k);
		if (visit[tmp]<0) continue;
		if (visit[tmp]!=visit[x]-1) continue;
		mlen[x] = max(mlen[tmp]+a[x][i].k,mlen[x]);
	}
}
void bfs(){
	int head=0;
	int tail=1;
	qu[0]=1;
	visit[1]=0;
	calm(1);
	while(head<tail){
		int x = qu[head];
		for (int i=0;i<a[x].size();i++){
			int tmp = a[x][i].x;
			if (visit[tmp]<0){
				qu[tail++]=tmp;
				visit[tmp]=visit[x]+1;
				calm(tmp);
				//cout<<x<<' '<<tmp<<' '<<visit[tmp]<<' '<<mlen[tmp]<<' '<<klen[tmp]<<endl;
			}
		}
		head++;
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=n;i++){
		if (klen[i]>klen[x]){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x]);
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-3000)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=n;i++){
		long long tmp= klen[i]*(now-3000)+mlen[i];
		if (tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
		}
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=3000;i++){
			if (i>q) break;
			for (int j=1;j<=n;j++){
				if (visit[j]>i) continue;
				tmp = max(tmp,mlen[j]+ klen[j]*(i-visit[j]));
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
		for (int i=1;i<=n;i++){
			mlen[i] = mlen[i]+klen[i]*(3000-visit[i]);
			if (mlen[i]>tmp || (mlen[i]==tmp && klen[i]>klen[now])){
				tmp = max(tmp,mlen[i]);
				now =i;
			}
		}
		long long nowx = 3001;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
	node():x(0L),k(0L){};
	node(int _x,int _k):x(_x),k(_k){};
	long long x,k;
}no[2005];
vector<node> a[2005];
long long visit[2005],mlen[2005],klen[2005],qu[2005],dp[3005][2005];
int n,m,q;
const long long mod = 1e9+7;
void calk(int x){
	for (int i=0;i<a[x].size();i++){
		klen[x] = max(klen[x],a[x][i].k);
	}
}
void bfs(){
	memset(dp,-1,sizeof(dp));
	dp[0][1]=0;
	for (int i=1;i<=m;i++){
		for (int j=1;j<=n;j++){
			for (int kk = 0;kk<a[j].size();kk++){
				int tmp = a[j][kk].x;
				if (dp[i-1][tmp]!=-1){
					dp[i][j] = max(dp[i][j],dp[i-1][tmp]+a[j][kk].k);
				}
			    //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
			}
		}
	}
}
long long calstop(int x,long long now){
	long long ret = 1e18;
	for (int i=1;i<=m;i++){
		if (klen[i]>klen[x] && mlen[i]!=-1){
			long long jiao = (mlen[x]-mlen[i]+klen[i]-klen[x]-1)/(klen[i]-klen[x])+m;
			if (jiao>now && jiao<ret) {
				ret = jiao;
			}
		}
	}
	return ret;
}
long long calans(int x,long long st,long long en){
	long long l = (en-st)%mod;
	long long mm =mlen[x]%mod*l%mod;
	long long kkn = l*(l-1)/2%mod + (st-m)*l%mod;
	long long kk = kkn%mod*klen[x]%mod;
	//cout<<l<<' '<<mm<<' '<<kkn<<' '<<kk<<endl;
	return (mm+kk)% mod;
}
const double  eps= 1e-8;
int doublecmp(double x,double y){
	if (x+eps<y) return -1;
	if (x-eps>y) return 1;
	return 0;
}
int findMax(long long now){
	int ret = -1;
	long long maxtmp = 0;
	for (int i=1;i<=m;i++){
		long long tmp= klen[i]*(now-m)+mlen[i];
		if ((tmp>maxtmp || (tmp==maxtmp && klen[i]>klen[ret])) && mlen[i]!=-1){
			ret = i;
			maxtmp = tmp;
		}
	}
	return ret;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
		int x,y,k;
		memset(visit,-1,sizeof(visit));
		memset(mlen,0,sizeof(mlen));
		memset(klen,0,sizeof(klen));
		for (int i=1;i<=n;i++) a[i].clear();
		for (int i=1;i<=m;i++){
			scanf("%d%d%d",&x,&y,&k);
			a[x].push_back(node(y,k));
			a[y].push_back(node(x,k));
			no[i] = node(x,y);
			klen[i]=k;
		}
		bfs();
		long long ans =0;
		long long tmp =0;
		for (int i=1;i<=m;i++){
			if (i>q) break;
			tmp=0;
			for (int j=1;j<=n;j++){
				tmp = max(tmp,dp[i][j]);
			}
			//cout<<i<<' '<<tmp<<' '<<ans<<endl;
			ans+=tmp%mod;
			ans%=mod;
		}
		 tmp = 0;
		long long now = -1;
	    for (int i=1;i<=m;i++){
			mlen[i] = max(dp[m][no[i].x], dp[m][no[i].k]);
			//cout<<' '<<klen[i]<<' '<<mlen[i]<<endl;
		}
		long long nowx = m+1;
		while(1 && nowx<=q){
			now = findMax(nowx);
			long long jiao = calstop(now,nowx);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			if (jiao>q) jiao = q+1;
			ans += calans(now,nowx,jiao);
			//cout<<"end"<<now<<' '<<jiao<<' '<<ans<<endl;
			ans %=mod;
			nowx = jiao;
			if (jiao>q) break;
		}
		if (nowx<=q) {
			ans += calans(now,nowx,q+1);
			ans%=mod;
		}
		printf("%lld\n",ans);
	}
}


// Author -- Frame

#include<bits/stdc++.h>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
#define SZ(x) ((int)x.size())
#define mkpr std::make_pair
#define pb push_back

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef std::pair<int,int> pi;
typedef std::pair<ll,ll> pl;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;

Finline uint rnd()
{
	static uint seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>=0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
template <typename _Tp>Finline void read(_Tp &x)
{
	char ch(getchar());
	bool f(false);
	while(ch<48||ch>57) f|=ch==45,ch=getchar();
	x=ch&15,ch=getchar();
	while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
	if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
	read(t);read(args...);
}
Finline int read_str(char *s)
{
	char ch(getchar());
	while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
	char *tar=s;
	*tar=ch,ch=getchar();
	while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
	return tar-s+1;
}

const int N=2005;
const int mod=1000000007;
template<typename _Tp1,typename _Tp2>Finline void add(_Tp1 &a,_Tp2 b){(a+=b)>=mod&&(a-=mod);}
template<typename _Tp1,typename _Tp2>Finline void sub(_Tp1 &a,_Tp2 b){(a-=b)<0&&(a+=mod);}
int dis[N][N];
struct edge{
	int v,nxt,w;
}c[N<<1];
int front[N],edge_cnt;
Finline void addedge(int u,int v,int w)
{
	c[++edge_cnt]=(edge){v,front[u],w};
	front[u]=edge_cnt;
}
ll k[N];
ll b[N];
struct node{
	ll x,y;
	Finline bool operator < (const node &o)const
	{
		return x==o.x?y>o.y:x<o.x;
	}
}a[N];
int st[N],top;
Finline ll calc(int i,ll x)
{
	i=st[i];
	return -x*a[i].x+a[i].y;
}
int main()
{
	int n,m,q;
	read(n,m,q);
	int x,y;
	ll z;
	for(int i=1;i<=m;++i)
	{
		read(x,y,z);
		addedge(x,y,z);
		addedge(y,x,z);
		chmax(k[x],z);
		chmax(k[y],z);
	}
	memset(dis,-63,sizeof(dis));
	dis[0][1]=0;
	for(int t=0;t<n;++t)
	{
		for(int i=1;i<=n;++i)
		{
			for(int _=front[i];_;_=c[_].nxt)
			{
				chmax(dis[t+1][c[_].v],dis[t][i]+c[_].w);
			}
		}
	}
	for(int i=1;i<=n;++i)
	{
		b[i]=-1e18;
		for(int j=0;j<=n;++j)
		{
			if(dis[j][i]>=0)
			{
				chmax(b[i],dis[j][i]-k[i]*j);
			}
		}
		a[i]=(node){-k[i],b[i]};
	}
	std::sort(a+1,a+n+1);
	for(int i=1;i<=n;++i)
	{
		if(a[i].x==a[i-1].x) continue;
		while(top>1&&(a[i].y-a[st[top]].y)*(a[st[top]].x-a[st[top-1]].x)>=(a[st[top]].y-a[st[top-1]].y)*(a[i].x-a[st[top]].x)) --top;
		st[++top]=i;
	}
	int ans=0;
	for(int i=1;i<=n&&i<=q;++i)
	{
		int tmp=0;
		for(int j=1;j<=n;++j) chmax(tmp,dis[i][j]);
		add(ans,tmp%mod);
	}
	if(q>n)
	{
		int last=n;
		for(int i=top;i>1;--i)
		{
			int l=last+1,r=q;
			while(l<r)
			{
				int mid=(l+r+1)>>1;
				if(calc(i,mid)>=calc(i-1,mid)) l=mid;
				else r=mid-1;
			}
			if(calc(i,l)>=calc(i-1,l))
			{
				ll tmp=calc(i,last+1);
				add(ans,1ll*tmp*(l-last)%mod);
				add(ans,-1ll*a[st[i]].x*(((1ll*(l-last)*(l-last-1))>>1)%mod)%mod);
				last=l;
			}
		}
		if(last<q)
		{
			ll tmp=calc(1,last+1);
			add(ans,1ll*tmp*(q-last)%mod);
			add(ans,-1ll*a[st[1]].x*(((1ll*(q-last)*(q-last-1))>>1)%mod)%mod);
		}
	}
	printf("%d\n",ans);
	return 0;
}


// Author -- Frame

#include<bits/stdc++.h>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
#define SZ(x) ((int)x.size())
#define mkpr std::make_pair
#define pb push_back

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef std::pair<int,int> pi;
typedef std::pair<ll,ll> pl;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;

Finline uint rnd()
{
	static uint seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>=0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
template <typename _Tp>Finline void read(_Tp &x)
{
	char ch(getchar());
	bool f(false);
	while(ch<48||ch>57) f|=ch==45,ch=getchar();
	x=ch&15,ch=getchar();
	while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
	if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
	read(t);read(args...);
}
Finline int read_str(char *s)
{
	char ch(getchar());
	while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
	char *tar=s;
	*tar=ch,ch=getchar();
	while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
	return tar-s+1;
}

const int N=2005;
const int mod=1000000007;
template<typename _Tp1,typename _Tp2>Finline void add(_Tp1 &a,_Tp2 b){(a+=b)>=mod&&(a-=mod);}
template<typename _Tp1,typename _Tp2>Finline void sub(_Tp1 &a,_Tp2 b){(a-=b)<0&&(a+=mod);}
int dis[N][N];
struct edge{
	int v,nxt,w;
}c[N<<1];
int front[N],edge_cnt;
Finline void addedge(int u,int v,int w)
{
	c[++edge_cnt]=(edge){v,front[u],w};
	front[u]=edge_cnt;
}
ll k[N];
ll b[N];
struct node{
	ll x,y;
	Finline bool operator < (const node &o)const
	{
		return x==o.x?y>o.y:x<o.x;
	}
}a[N];
int st[N],top;
Finline ll calc(int i,ll x)
{
	i=st[i];
	return -x*a[i].x+a[i].y;
}
int main()
{
	int n,m,q;
	read(n,m,q);
	int x,y;
	ll z;
	for(int i=1;i<=m;++i)
	{
		read(x,y,z);
		addedge(x,y,z);
		addedge(y,x,z);
		chmax(k[x],z);
		chmax(k[y],z);
	}
	memset(dis,-63,sizeof(dis));
	dis[0][1]=0;
	for(int t=0;t<n;++t)
	{
		for(int i=1;i<=n;++i)
		{
			for(int _=front[i];_;_=c[_].nxt)
			{
				chmax(dis[t+1][c[_].v],dis[t][i]+c[_].w);
			}
		}
	}
	for(int i=1;i<=n;++i)
	{
		b[i]=-1e18;
		for(int j=0;j<=n;++j)
		{
			if(dis[j][i]>=0)
			{
				chmax(b[i],dis[j][i]-k[i]*j);
			}
		}
		a[i]=(node){-k[i],b[i]};
	}
	std::sort(a+1,a+n+1);
	for(int i=1;i<=n;++i)
	{
		if(a[i].x==a[i-1].x) continue;
		while(top>1&&(a[i].y-a[st[top]].y)*(a[st[top]].x-a[st[top-1]].x)>=(a[st[top]].y-a[st[top-1]].y)*(a[i].x-a[st[top]].x)) --top;
		st[++top]=i;
	}
	int ans=0;
	for(int i=1;i<=n&&i<=q;++i)
	{
		int tmp=0;
		for(int j=1;j<=n;++j) chmax(tmp,dis[i][j]);
		add(ans,tmp);
	}
	if(q>n)
	{
		int last=n;
		for(int i=top;i>1;--i)
		{
			int l=last+1,r=q;
			while(l<r)
			{
				int mid=(l+r+1)>>1;
				if(calc(i,mid)>=calc(i-1,mid)) l=mid;
				else r=mid-1;
			}
			if(calc(i,l)>=calc(i-1,l))
			{
				ll tmp=calc(i,last+1);
				add(ans,1ll*tmp*(l-last)%mod);
				add(ans,-1ll*a[st[i]].x*(((1ll*(l-last)*(l-last-1))>>1)%mod)%mod);
				last=l;
			}
		}
		if(last<q)
		{
			ll tmp=calc(1,last+1);
			add(ans,1ll*tmp*(q-last)%mod);
			add(ans,-1ll*a[st[1]].x*(((1ll*(q-last)*(q-last-1))>>1)%mod)%mod);
		}
	}
	printf("%d\n",ans);
	return 0;
}


// Author -- Frame

#include<bits/stdc++.h>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
#define SZ(x) ((int)x.size())
#define mkpr std::make_pair
#define pb push_back

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef std::pair<int,int> pi;
typedef std::pair<ll,ll> pl;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;

Finline uint rnd()
{
	static uint seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>=0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
template <typename _Tp>Finline void read(_Tp &x)
{
	char ch(getchar());
	bool f(false);
	while(ch<48||ch>57) f|=ch==45,ch=getchar();
	x=ch&15,ch=getchar();
	while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
	if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
	read(t);read(args...);
}
Finline int read_str(char *s)
{
	char ch(getchar());
	while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
	char *tar=s;
	*tar=ch,ch=getchar();
	while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
	return tar-s+1;
}

const int N=2005;
const int mod=1000000007;
template<typename _Tp1,typename _Tp2>Finline void add(_Tp1 &a,_Tp2 b){(a+=b)>=mod&&(a-=mod);}
template<typename _Tp1,typename _Tp2>Finline void sub(_Tp1 &a,_Tp2 b){(a-=b)<0&&(a+=mod);}
int dis[N][N];
struct edge{
	int v,nxt,w;
}c[N<<1];
int front[N],edge_cnt;
Finline void addedge(int u,int v,int w)
{
	c[++edge_cnt]=(edge){v,front[u],w};
	front[u]=edge_cnt;
}
ll k[N];
ll b[N];
struct node{
	ll x,y;
	Finline bool operator < (const node &o)const
	{
		return x==o.x?y>o.y:x<o.x;
	}
}a[N];
int st[N],top;
Finline ll calc(int i,ll x)
{
	i=st[i];
	return -x*a[i].x+a[i].y;
}
int main()
{
	int n,m,q;
	read(n,m,q);
	int x,y;
	ll z;
	for(int i=1;i<=m;++i)
	{
		read(x,y,z);
		addedge(x,y,z);
		addedge(y,x,z);
		chmax(k[x],z);
		chmax(k[y],z);
	}
	memset(dis,-63,sizeof(dis));
	dis[0][1]=0;
	for(int t=0;t<n;++t)
	{
		for(int i=1;i<=n;++i)
		{
			for(int _=front[i];_;_=c[_].nxt)
			{
				chmax(dis[t+1][c[_].v],dis[t][i]+c[_].w);
			}
		}
	}
	for(int i=1;i<=n;++i)
	{
		b[i]=-1e18;
		for(int j=0;j<=n;++j)
		{
			if(dis[j][i]>=0)
			{
				chmax(b[i],dis[j][i]-k[i]*j);
			}
		}
		a[i]=(node){-k[i],b[i]};
	}
	std::sort(a+1,a+n+1);
	for(int i=1;i<=n;++i)
	{
		if(a[i].x==a[i-1].x) continue;
		while(top>1&&(a[i].y-a[st[top]].y)*(a[st[top]].x-a[st[top-1]].x)>=(a[st[top]].y-a[st[top-1]].y)*(a[i].x-a[st[top]].x)) --top;
		st[++top]=i;
	}
	int ans=0;
	for(int i=1;i<=n&&i<=q;++i)
	{
		int tmp=0;
		for(int j=1;j<=n;++j) chmax(tmp,dis[i][j]);
		add(ans,tmp%mod);
	}
	if(q>n)
	{
		int last=n;
		for(int i=top;i>1;--i)
		{
			int l=last+1,r=q;
			while(l<r)
			{
				int mid=(l+r+1)>>1;
				if(calc(i,mid)>=calc(i-1,mid)) l=mid;
				else r=mid-1;
			}
			if(calc(i,l)>=calc(i-1,l))
			{
				add(ans,calc(i,last+1)%mod*(l-last)%mod);
				add(ans,-1ll*a[st[i]].x*(((1ll*(l-last)*(l-last-1))>>1)%mod)%mod);
				last=l;
			}
		}
		if(last<q)
		{
			add(ans,calc(1,last+1)%mod*(q-last)%mod);
			add(ans,-1ll*a[st[1]].x*(((1ll*(q-last)*(q-last-1))>>1)%mod)%mod);
		}
	}
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int intersect(const pi &a, const pi &b){
    return (a.s-b.s)/(b.f-a.f);
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
    ll dp[2001][2001];
    FOR(i,2001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,2000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
    ll rans = 0;
    FOR(i,min(2000,q)){
        rans = (rans+ans[i])%mod;
    }
    if(q <= 2000){
        cout << rans << endl;
        return 0;
    }
    vector<ll> start(1000001);
    F0R(i,1,n){
        start[largec[i]] = max(start[largec[i]], dp[2000][i]);
    }
    vector< pair<ll,ll> > hull;
    int sz = 0;
    q -= 2000;
    FOR(i,1000001){
        if(start[i] == 0) continue;
        else{
            while(sz > 1){
                if(intersect(hull[sz-1],{i,start[i]}) <= intersect(hull[sz-2],hull[sz-1])){
                    hull.pop_back();
                    sz--;
                }else break;
            }
            if(sz == 1){
                if(hull[0].s <= start[i]) hull[0] = {i,start[i]};
                else{hull.push_back({i,start[i]}); sz++;}
            }else{
                hull.push_back({i,start[i]}); sz++;
            }
        }
    }
//    cerr << hull[0].f << endl;
    FOR(i,sz){
        ll stp,enp;
        if(i == 0){
            stp = 1;
        }else{
            stp = intersect(hull[i-1],hull[i]) + 1;
        }
        if(i == sz-1){
            enp = q;
        }else{
            enp = min(q,intersect(hull[i],hull[i+1]));
        }
        ll cans = ((((enp-stp+1)*(stp+enp))%mod)*hull[i].f)/2 + (enp-stp+1)*hull[i].s;
        cans %= mod;
        rans = (rans+cans)%mod;
        if(enp == q) break;
    }
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int intersect(const pi &a, const pi &b){
    return (a.s-b.s)/(b.f-a.f);
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
    ll dp[2001][2001];
    FOR(i,2001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,2000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
    ll rans = 0;
    FOR(i,min(2000,q)){
        rans = (rans+ans[i])%mod;
    }
    if(q <= 2000){
        cout << rans << endl;
        return 0;
    }
    vector<ll> start(1000001);
    F0R(i,1,n){
        start[largec[i]] = max(start[largec[i]], dp[2000][i]);
    }
    vector< pair<ll,ll> > hull;
    int sz = 0;
    q -= 2000;
    FOR(i,1000001){
        if(start[i] == 0) continue;
        else{
            while(sz > 1){
                if(intersect(hull[sz-2],{i,start[i]}) <= intersect(hull[sz-2],hull[sz-1])){
                    hull.pop_back();
                    sz--;
                }else break;
            }
            if(sz == 1){
                if(hull[0].s <= start[i]) hull[0] = {i,start[i]};
                else{hull.push_back({i,start[i]}); sz++;}
            }else{
                hull.push_back({i,start[i]}); sz++;
            }
        }
    }
//    cerr << hull[0].f << endl;
    FOR(i,sz){
        ll stp,enp;
        if(i == 0){
            stp = 1;
        }else{
            stp = intersect(hull[i-1],hull[i]) + 1;
        }
        if(i == sz-1){
            enp = q;
        }else{
            enp = min(q,intersect(hull[i],hull[i+1]));
        }
        ll cans = ((((enp-stp+1)*(stp+enp))%mod)*hull[i].f)/2 + (enp-stp+1)*hull[i].s;
        cans %= mod;
        rans = (rans+cans)%mod;
        if(enp == q) break;
    }
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int intersect(const pi &a, const pi &b){
    return (a.s-b.s)/(b.f-a.f);
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
    ll dp[2001][2001];
    FOR(i,2001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,2000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
    ll rans = 0;
    FOR(i,min(2000,q)){
        rans = (rans+ans[i])%mod;
    }
    if(q <= 2000){
        cout << rans << endl;
        return 0;
    }
    vector<ll> start(1000001);
    F0R(i,1,n){
        start[largec[i]] = max(start[largec[i]], dp[2000][i]);
    }
    vector< pair<ll,ll> > hull;
    int sz = 0;
    q -= 2000;
    FOR(i,1000001){
        if(start[i] == 0) continue;
        else{
            while(sz > 1){
                if(intersect(hull[sz-2],{i,start[i]}) <= intersect(hull[sz-2],hull[sz-1])){
                    hull.pop_back();
                    sz--;
                }
            }
            if(sz == 1){
                if(hull[0].s <= start[i]) hull[0] = {i,start[i]};
                else{hull.push_back({i,start[i]}); sz++;}
            }else{
                hull.push_back({i,start[i]}); sz++;
            }
        }
    }
//    cerr << hull[0].f << endl;
    FOR(i,sz){
        ll stp,enp;
        if(i == 0){
            stp = 1;
        }else{
            stp = intersect(hull[i-1],hull[i]) + 1;
        }
        if(i == sz-1){
            enp = q;
        }else{
            enp = min(q,intersect(hull[i],hull[i+1]));
        }
        ll cans = ((((enp-stp+1)*(stp+enp))%mod)*hull[i].f)/2 + (enp-stp+1)*hull[i].s;
        cans %= mod;
        rans = (rans+cans)%mod;
        if(enp == q) break;
    }
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
//    cerr << "hi\n";
    ll dp[2001][2001];
    FOR(i,2001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,2000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
//    cerr << "hi\n";
    ll base = 0;
    for(auto &a: good){
        base = max(base,dp[2000][a]);
    }
    ll rans = 0;
    FOR(i,min(2000,q)){
//        cerr << ans[i] << endl;
        rans = (rans+ans[i])%mod;
    }
    if(q <= 2000){
        cout << rans << endl;
        return 0;
    }
    ll bb = 0; ll badd = 0;
    F0R(i,1,n){
        if(dp[i][2000] > bb){
            bb = dp[i][2000];
            badd = largec[i];
        }else if(dp[i][2000] == bb) badd = max(badd,largec[i]);
    }
    ll ptr = 1;
    for(;(bb+ptr*badd > base+ptr*bnum && 2000LL+ptr <= q); ptr++) rans = (rans + bb+ptr*badd)%mod;
//    cerr << ptr << endl;
    if(2000LL+ptr > q){
        cout << rans << endl; return 0;
    }
    ll b = (ll)q-ptr+1-2000;
    base += (ptr-1)*bnum;
    base %= mod;
    rans = (rans + b*base)%mod;
    b = (b*(b+1LL))/2;
    b = b%mod;
    rans = (rans + b*bnum)%mod;
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int intersect(const pi &a, const pi &b){
    return (a.s-b.s)/(b.f-a.f);
}

const int width = 4000;

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
    ll dp[width+1][2001];
    FOR(i,width+1) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,width){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
    ll rans = 0;
    FOR(i,min(width,q)){
        rans = (rans+ans[i])%mod;
    }
    if(q <= width){
        cout << rans << endl;
        return 0;
    }
    vector<ll> start(1000001);
    F0R(i,1,n){
        start[largec[i]] = max(start[largec[i]], dp[width][i]);
    }
    vector< pair<ll,ll> > hull;
    int sz = 0;
    q -= width;
    FOR(i,1000001){
        if(start[i] == 0) continue;
        else{
            while(sz > 1){
                if(intersect(hull[sz-2],{i,start[i]}) <= intersect(hull[sz-2],hull[sz-1])){
                    hull.pop_back();
                    sz--;
                }else break;
            }
            if(sz == 1){
                if(hull[0].s <= start[i]) hull[0] = {i,start[i]};
                else{hull.push_back({i,start[i]}); sz++;}
            }else{
                hull.push_back({i,start[i]}); sz++;
            }
        }
    }
//    cerr << hull[0].f << endl;
    FOR(i,sz){
        ll stp,enp;
        if(i == 0){
            stp = 1;
        }else{
            stp = intersect(hull[i-1],hull[i]) + 1;
        }
        if(i == sz-1){
            enp = q;
        }else{
            enp = min(q,intersect(hull[i],hull[i+1]));
        }
        ll cans = ((((enp-stp+1)*(stp+enp))%mod)*hull[i].f)/2 + (enp-stp+1)*hull[i].s;
        cans %= mod;
        rans = (rans+cans)%mod;
        if(enp == q) break;
    }
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
//    cerr << "hi\n";
    ll dp[4001][2001];
    FOR(i,4001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,4000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
//    cerr << "hi\n";
    ll base = 0;
    for(auto &a: good){
        base = max(base,dp[4000][a]);
    }
    base = base%mod;
    ll rans = 0;
    FOR(i,min(4000,q)){
//        cerr << ans[i] << endl;
        rans = (rans+ans[i])%mod;
    }
    if(q <= 4000){
        cout << rans << endl;
        return 0;
    }
    ll b = (ll)q-4000LL;
    rans = (rans + b*base)%mod;
//    cerr << ans[3999] << endl;
//    for(auto &a: good) cerr << dp[4000][a] << endl;
    b = (b*(b+1LL))/2;
    b = b%mod;
    rans = (rans + b*bnum)%mod;
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
    ll dp[2001][2001];
    FOR(i,2001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,2000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
    ll base = 0;
    for(auto &a: good){
        base = max(base,dp[2000][a]);
    }
    ll rans = 0;
    FOR(i,min(2000,q)){
        rans = (rans+ans[i])%mod;
    }
    if(q <= 2000){
        cout << rans << endl;
        return 0;
    }
    ll bb = 0; ll badd = 0;
    F0R(i,1,n){
        if(dp[2000][i] > bb){
            bb = dp[2000][i];
            badd = largec[i];
        }else if(dp[2000][i] == bb) badd = max(badd,largec[i]);
    }
    ll ptr = 0;
    if(bnum != badd) ptr = (bb-base)/(bnum-badd);
    ptr = min(ptr,(ll)q-2000LL);
    rans = rans + (((ptr*(ptr+1))/2)%mod)*badd + ptr*bb;
    rans %= mod;
    if(2000LL+ptr == q){
        cout << rans << endl; return 0;
    }
    ll b = (ll)q-ptr-2000LL;
    base += (ptr)*bnum;
    base %= mod;
    rans = (rans + b*base)%mod;
    b = (b*(b+1LL))/2LL;
    b = b%mod;
    rans = (rans + b*bnum)%mod;
    cout << rans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

ll intersect(pair<ll,ll> a, pair<ll,ll> b){
    return (a.s-b.s)/(b.f-a.f);
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(2001);
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
    }
    ll dp[2001][2001];
    FOR(i,2001)FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> bpath(2001);
    F0R(i,1,2000){
        ll best = 0;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        bpath[i] = best;
    }
    ll ans = 0;
    F0R(i,1,min(q,2000)){
        ans = (ans+bpath[i])%mod;
    }
    if(q <= 2000){
        cout << ans << endl;
        return 0;
    }
    q -= 2000;
    vector<ll> intercept(1000001);
    F0R(i,1,n){
        intercept[largec[i]] = max(intercept[largec[i]],dp[2000][i]);
    }
    vector<pair<ll,ll> > hull;
    int sz = 0;
    F0R(i,1,1000001){
        if(intercept[i] == 0) continue;
        while(sz > 0){
            if(intercept[i] >= hull[sz-1].s){
                hull.pop_back();
                sz--;
            }else if(sz >= 2 && intersect(hull[sz-2],{i,intercept[i]}) <= intersect(hull[sz-2],hull[sz-1])){
                hull.pop_back(); sz--;
            }else break;
        }
        hull.push_back({i,intercept[i]});
        sz++;
    }
    cerr << sz << " " << hull[0].f << endl;
    FOR(i,sz){
        ll stp,enp;
        if(i == 0){
            stp = 1;
        }else{
            stp = intersect(hull[i-1],hull[i]) + 1;
        }
        if(i == sz-1) enp = q;
        else{
            enp = min((ll)q,intersect(hull[i],hull[i+1]));
        }
        ll cans = (((stp+enp)*(enp-stp+1LL))/2LL)%mod;
        cans = (cans*hull[i].f)%mod;
        ll b = (hull[i].s)%mod;
        cans = (cans + (enp-stp+1LL)*b)%mod;
        ans = (ans+cans)%mod;
        if(enp == q) break;
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

#define FOR(a,b) for(int a=0;a<b;a++)
#define F0R(a,b,c) for(int a = b; a<=c; a++)
#define f first
#define s second
#define m0(x) memset(x,0,sizeof(x))

typedef pair<int,int> pi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pi> vpi;

const ll inf = 1e18;

const ll mod = 1e9+7;

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,q; cin >> n >> m >> q;
    vpi edges[2001];
    vector<ll> largec(n+1);
    vi good;
    ll bnum = 0;
    FOR(i,m){
        int a,b,c; cin >> a >> b >> c;
        edges[a].push_back({b,c});
        edges[b].push_back({a,c});
        largec[a] = max(largec[a],(ll)c);
        largec[b] = max(largec[b],(ll)c);
        if(c >= bnum){
            if(c > bnum){
                bnum = c; good.clear();
            }
            good.push_back(a);
            good.push_back(b);
        }
    }
//    cerr << "hi\n";
    ll dp[2001][2001];
    FOR(i,2001) FOR(j,2001) dp[i][j] = -inf;
    dp[0][1] = 0;
    vector<ll> ans;
    F0R(i,1,2000){
        ll best = -inf;
        F0R(j,1,n){
            for(auto &a: edges[j]){
                dp[i][j] = max(dp[i][j],dp[i-1][a.f]+(ll)a.s);
            }
            best = max(best,dp[i][j]);
        }
        ans.push_back(best);
    }
//    cerr << "hi\n";
    ll base = 0;
    for(auto &a: good){
        base = max(base,dp[2000][a]);
    }
    ll rans = 0;
    FOR(i,min(2000,q)){
//        cerr << ans[i] << endl;
        rans = (rans+ans[i])%mod;
    }
    if(q <= 2000){
        cout << rans << endl;
        return 0;
    }
    ll bb = 0; ll badd = 0;
    F0R(i,1,n){
        if(dp[2000][i] > bb){
            bb = dp[2000][i];
            badd = largec[i];
        }else if(dp[2000][i] == bb) badd = max(badd,largec[i]);
    }
    ll ptr = 0;
//    cerr << badd << " " << bb << endl;
    if(bnum != badd) ptr = (bb-base)/(bnum-badd);
    ptr = min(ptr,(ll)q-2000LL);
//    cerr << ptr << endl;
    rans = rans + (((ptr*(ptr+1))/2)%mod)*badd + ptr*bb;
    rans %= mod;
    if(2000LL+ptr == q){
        cout << rans << endl; return 0;
    }
    ll b = (ll)q-ptr-2000LL;
    base += (ptr)*bnum;
    base %= mod;
    rans = (rans + b*base)%mod;
    b = (b*(b+1LL))/2;
    b = b%mod;
    rans = (rans + b*bnum)%mod;
    cout << rans << endl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + c - '0', c = getchar();
    return x * f;
}
int inc(int x, int y) { return (x + y >= mod) ? (x + y - mod) : (x + y); }
int del(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int qpow(int a, int x, int mo)
{
    int res = 1;
    while (x)
    {
        if (x & 1)
            res = 1ll * res * a % mo;
        a = 1ll * a * a % mod;
        x >>= 1;
    }
    return res;
}
vector<pii> g[N];
ll dp[N][N];
map<int, ll> mp;
int q[N];
int main()
{
    int n = read(), m = read(), Q = read();
    for (int i = 0; i < m; i++)
    {
        int u = read(), v = read(), w = read();
        g[u].push_back(mk(v, w));
        g[v].push_back(mk(u, w));
    }
    for (int i = 0; i <= m; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = -2e18;
    dp[0][1] = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ll res = 0;
        for (int j = 1; j <= n; j++)
            for (int t = 0; t < g[j].size(); t++)
            {
                pii now = g[j][t];
                int u = now.first, v = j;
                dp[i][u] = max(dp[i - 1][v] + now.second, dp[i][u]);
                if (i == m)
                    mp[now.second] = max(dp[i - 1][v] + now.second, mp[now.second]);
                res = max(res, dp[i][u]);
            }

        ans = inc(ans, res % mod);
    }

    vector<pii> p;

    for (auto it : mp)
    {

        p.push_back(it);
    }
    int head = 1, tail = 0;
    int Inv2 = qpow(2, mod - 2, mod);
    for (int i = 0; i < p.size(); i++)
    {

        while (head <= tail && p[q[tail]].second <= p[i].second)
            tail--;

        q[++tail] = i;
    }

    Q -= m;
    int cnt = 0;
    int pre = 1;
    for (int i = 2; i <= tail; i++)
    {
        pii now = p[q[pre]];
        pii nxt = p[q[i]];
        int k = (now.second - nxt.second) / (nxt.first - now.first) - cnt;
        if (k <= 0)
            continue;

        if (Q <= k)
            k = Q;
        ans = inc(ans, inc(1ll * k * (1 + k) % mod * Inv2 % mod * now.first % mod, 1ll * (now.second + 1ll * cnt * now.first % mod) % mod * k % mod));

        Q -= k;
        cnt += k;
        pre = i;
        if (Q == 0)
            break;
    }

    pii now = p[q[tail]];

    if (Q > 0)
        ans = inc(ans, inc(1ll * Q * (1 + Q) % mod * Inv2 % mod * now.first % mod, 1ll * (now.second + 1ll * cnt * now.first % mod) % mod * Q % mod));
    printf("%d\n", ans);
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + c - '0', c = getchar();
    return x * f;
}
int inc(int x, int y) { return (x + y >= mod) ? (x + y - mod) : (x + y); }
int del(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int qpow(int a, int x, int mo)
{
    int res = 1;
    while (x)
    {
        if (x & 1)
            res = 1ll * res * a % mo;
        a = 1ll * a * a % mod;
        x >>= 1;
    }
    return res;
}
vector<pii> g[N];
ll dp[N][N];
map<int, ll> mp;
int q[N];
int main()
{
    int n = read(), m = read(), Q = read();
    for (int i = 0; i < m; i++)
    {
        int u = read(), v = read(), w = read();
        g[u].push_back(mk(v, w));
        g[v].push_back(mk(u, w));
    }
    for (int i = 0; i <= m; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = -2e18;
    dp[0][1] = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ll res = 0;
        for (int j = 1; j <= n; j++)
            for (int t = 0; t < g[j].size(); t++)
            {
                pii now = g[j][t];
                int u = now.first, v = j;
                dp[i][u] = max(dp[i - 1][v] + now.second, dp[i][u]);
                if (i == m)
                    mp[now.second] = max(dp[i - 1][v] + now.second, mp[now.second]);
                res = max(res, dp[i][u]);
            }

        ans = inc(ans, res);
    }

    vector<pii> p;

    for (auto it : mp)
    {

        p.push_back(it);
    }
    int head = 1, tail = 0;
    int Inv2 = qpow(2, mod - 2, mod);
    for (int i = 0; i < p.size(); i++)
    {

        while (head <= tail && p[q[tail]].second <= p[i].second)
            tail--;

        q[++tail] = i;
    }

    Q -= m;
    int cnt = 0;
    for (int i = 1; i < tail; i++)
    {
        pii now = p[q[i]];
        pii nxt = p[q[i + 1]];
        int k = (now.second - nxt.second) / (nxt.first - now.first) - cnt;
        if (k <= 0)
            continue;

        if (Q <= k)
            k = Q;
        ans = inc(ans, inc(1ll * k * (1 + k) % mod * Inv2 % mod * now.first % mod, 1ll * k * (now.second + 1ll * cnt * now.first % mod) % mod));

        Q -= k;
        cnt += k;
        if (Q == 0)
            break;
    }

    pii now = p[q[tail]];

    if (Q > 0)
        ans = inc(ans, inc(1ll * Q * (1 + Q) % mod * Inv2 % mod * now.first % mod, 1ll * Q * (now.second + 1ll * cnt * now.first % mod) % mod));
    printf("%d\n", ans);
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + c - '0', c = getchar();
    return x * f;
}
int inc(int x, int y) { return (x + y >= mod) ? (x + y - mod) : (x + y); }
int del(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int qpow(int a, int x, int mo)
{
    int res = 1;
    while (x)
    {
        if (x & 1)
            res = 1ll * res * a % mo;
        a = 1ll * a * a % mod;
        x >>= 1;
    }
    return res;
}
vector<pii> g[N];
ll dp[N][N];
map<int, ll> mp;
int q[N];
int main()
{
    int n = read(), m = read(), Q = read();
    for (int i = 0; i < m; i++)
    {
        int u = read(), v = read(), w = read();
        g[u].push_back(mk(v, w));
        g[v].push_back(mk(u, w));
    }
    for (int i = 0; i <= m; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = -2e18;
    dp[0][1] = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ll res = 0;
        for (int j = 1; j <= n; j++)
            for (int t = 0; t < g[j].size(); t++)
            {
                pii now = g[j][t];
                int u = now.first, v = j;
                dp[i][u] = max(dp[i - 1][v] + now.second, dp[i][u]);
                if (i == m)
                    mp[now.second] = max(dp[i - 1][v] + now.second, mp[now.second]);
                res = max(res, dp[i][u]);
            }

        ans = inc(ans, res%mod);
    }

    vector<pii> p;

    for (auto it : mp)
    {

        p.push_back(it);
    }
    int head = 1, tail = 0;
    int Inv2 = qpow(2, mod - 2, mod);
    for (int i = 0; i < p.size(); i++)
    {

        while (head <= tail && p[q[tail]].second <= p[i].second)
            tail--;

        q[++tail] = i;
    }

    Q -= m;
    int cnt = 0;
    for (int i = 1; i < tail; i++)
    {
        pii now = p[q[i]];
        pii nxt = p[q[i + 1]];
        int k = (now.second - nxt.second) / (nxt.first - now.first) - cnt;
        if (k <= 0)
            continue;

        if (Q <= k)
            k = Q;
        ans = inc(ans, inc(1ll * k * (1 + k) % mod * Inv2 % mod * now.first % mod, 1ll * k * (now.second + 1ll * cnt * now.first % mod) % mod));

        Q -= k;
        cnt += k;
        if (Q == 0)
            break;
    }

    pii now = p[q[tail]];

    if (Q > 0)
        ans = inc(ans, inc(1ll * Q * (1 + Q) % mod * Inv2 % mod * now.first % mod, 1ll * Q * (now.second + 1ll * cnt * now.first % mod) % mod));
    printf("%d\n", ans);
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + c - '0', c = getchar();
    return x * f;
}
int inc(int x, int y) { return (x + y >= mod) ? (x + y - mod) : (x + y); }
int del(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int qpow(int a, int x, int mo)
{
    int res = 1;
    while (x)
    {
        if (x & 1)
            res = 1ll * res * a % mo;
        a = 1ll * a * a % mod;
        x >>= 1;
    }
    return res;
}
vector<pii> g[N];
ll dp[N][N];
map<int, ll> mp;
int q[N];
int main()
{
    int n = read(), m = read(), Q = read();
    for (int i = 0; i < m; i++)
    {
        int u = read(), v = read(), w = read();
        g[u].push_back(mk(v, w));
        g[v].push_back(mk(u, w));
    }
    for (int i = 0; i <= m; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = -2e18;
    dp[0][1] = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ll res = 0;
        for (int j = 1; j <= n; j++)
            for (int t = 0; t < g[j].size(); t++)
            {
                pii now = g[j][t];
                int u = now.first, v = j;
                dp[i][u] = max(dp[i - 1][v] + now.second, dp[i][u]);
                if (i == m)
                    mp[now.second] = max(dp[i - 1][v] + now.second, mp[now.second]);
                res = max(res, dp[i][u]);
            }

        ans = inc(ans, res % mod);
    }

    vector<pii> p;

    for (auto it : mp)
    {

        p.push_back(it);
    }
    int head = 1, tail = 0;
    int Inv2 = qpow(2, mod - 2, mod);
    for (int i = 0; i < p.size(); i++)
    {

        while (head <= tail && p[q[tail]].second <= p[i].second)
            tail--;

        q[++tail] = i;
    }

    Q -= m;
    int cnt = 0;
    int pre = 1;
    for (int i = 2; i <= tail; i++)
    {
        pii now = p[q[pre]];
        pii nxt = p[q[i]];
        bool ok = 1;
        ll k = (now.second - nxt.second) / (nxt.first - now.first);
        for (int j = i + 1; j <= tail; j++)
        {
            pii o = p[q[j]];
            if ((now.second - o.second) / (o.first - now.first) <= k)
            {
                ok = 0;
                break;
            }
        }
        k -= cnt;
        if (k <= 0 || ok == 0)
            continue;

        if (Q <= k)
            k = Q;
        ans = inc(ans, inc(1ll * k * (1 + k) % mod * Inv2 % mod * now.first % mod, 1ll * (now.second + 1ll * cnt * now.first % mod) % mod * k % mod));

        Q -= k;
        cnt += k;
        pre = i;
        if (Q == 0)
            break;
    }

    pii now = p[q[tail]];

    if (Q > 0)
        ans = inc(ans, inc(1ll * Q * (1 + Q) % mod * Inv2 % mod * now.first % mod, 1ll * (now.second + 1ll * cnt * now.first % mod) % mod * Q % mod));
    printf("%d\n", ans);
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + c - '0', c = getchar();
    return x * f;
}
int inc(int x, int y) { return (x + y >= mod) ? (x + y - mod) : (x + y); }
int del(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int qpow(int a, int x, int mo)
{
    int res = 1;
    while (x)
    {
        if (x & 1)
            res = 1ll * res * a % mo;
        a = 1ll * a * a % mod;
        x >>= 1;
    }
    return res;
}
vector<pii> g[N];
ll dp[N][N];
map<int, ll> mp;
int q[N];
int main()
{
    int n = read(), m = read(), Q = read();
    for (int i = 0; i < m; i++)
    {
        int u = read(), v = read(), w = read();
        g[u].push_back(mk(v, w));
        g[v].push_back(mk(u, w));
    }
    for (int i = 0; i <= m; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = -2e18;
    dp[0][1] = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ll res = 0;
        for (int j = 1; j <= n; j++)
            for (int t = 0; t < g[j].size(); t++)
            {
                pii now = g[j][t];
                int u = now.first, v = j;
                dp[i][u] = max(dp[i - 1][v] + now.second, dp[i][u]);
                if (i == m)
                    mp[now.second] = max(dp[i - 1][v] + now.second, mp[now.second]);
                res = max(res, dp[i][u]);
            }

        ans = inc(ans, res % mod);
    }

    vector<pii> p;

    for (auto it : mp)
    {

        p.push_back(it);
    }
    int head = 1, tail = 0;
    int Inv2 = qpow(2, mod - 2, mod);
    for (int i = 0; i < p.size(); i++)
    {

        while (head <= tail && p[q[tail]].second <= p[i].second)
            tail--;

        q[++tail] = i;
    }

    Q -= m;
    int cnt = 0;
    int pre = 1;
    for (int i = 2; i <= tail; i++)
    {
        pii now = p[q[pre]];
        pii nxt = p[q[i]];
        ll k = (now.second - nxt.second) / (nxt.first - now.first) - cnt;
        if (k <= 0)
            continue;

        if (Q <= k)
            k = Q;
        ans = inc(ans, inc(1ll * k * (1 + k) % mod * Inv2 % mod * now.first % mod, 1ll * (now.second + 1ll * cnt * now.first % mod) % mod * k % mod));

        Q -= k;
        cnt += k;
        pre = i;
        if (Q == 0)
            break;
    }

    pii now = p[q[tail]];

    if (Q > 0)
        ans = inc(ans, inc(1ll * Q * (1 + Q) % mod * Inv2 % mod * now.first % mod, 1ll * (now.second + 1ll * cnt * now.first % mod) % mod * Q % mod));
    printf("%d\n", ans);
}


import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        while(t-->0)
        {
            int a=sc.nextInt();
            int b=sc.nextInt();
            int ans=0;
            if(a==0||b==0)
            ans=0;
            else if(a>=2*b || b>=2*a)
            ans=Math.min(a,b);
            else if(a==b && a%2==0)
            ans=a/2;
            else if(a==b && a%2==1)
            ans=a/2 +1;
            else
            {
                int d=Math.min(a,b)/3;
                ans+=2*d;
                a-=3*d;
                b-=3*d;
                ans+=(a<b)? Math.min(a,b/2): Math.min(b,a/2);
            }
            System.out.println(ans);
        }
      //  System.out.println("XXXXXXXX");
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        while(t-->0)
        {
                int a=sc.nextInt();
                int b=sc.nextInt();

                if(a==0 || b==0)
                System.out.println(0);
                else if(a>=2*b || b>=2*a)
                System.out.println(Math.min(a,b));
                else
                {
                    int d=Math.min(a,b)/3;
                    int k=a%3 + b%3;
                    if(k==3)
                    System.out.println(2*d + 1);
                    else
                    System.out.println(2*d);
                }

        }

        //System.out.println("XXXXXXXX");
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        while(t-->0)
        {
            int a=sc.nextInt();
            int b=sc.nextInt();
            int ans=0;
            if(a==0||b==0)
            ans=0;
            else
            ans=Math.min(Math.min(a,b),(a+b)/3);
            System.out.println(ans);
        }
      //  System.out.println("XXXXXXXX");
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        while(t-->0)
        {
                int a=sc.nextInt();
                int b=sc.nextInt();

                if(a>=2*b || b>=2*a)
                {
                    System.out.println(Math.min(a,b));
                }
                else if(a==b && a%2==0)
                System.out.println(a/2);
                else if(a==b && a%2==1)
                System.out.println(a/2 +1);
                else if(a-b==1 || a-b==-1)
                System.out.println(Math.max(a,b)/2 +1);
                else if(a-b==-2 || a-b==2)
                System.out.println(Math.max(a,b)/2);
                else
                System.out.println(Math.min(a,b)-1);

        }

        //System.out.println("XXXXXXXX");
    }
}