#include<bits/stdc++.h>
#define ll long long
using namespace std;
void read(int &x){
	x=0; char c=getchar(); int p=1;
	for (;c<48;c=getchar())if (c=='-')p=-1;
	for (;c>47;c=getchar())x=(x<<1)+(x<<3)+(c^48);
	x*=p;
}
void read(ll &x){
	x=0; char c=getchar(); int p=1;
	for (;c<48;c=getchar())if (c=='-')p=-1;
	for (;c>47;c=getchar())x=(x<<1)+(x<<3)+(c^48);
	x*=p;
}
void Max(int &x,int y){
	if (x<y)x=y;
}
void Max(ll &x,ll y){
	if (x<y)x=y;
}
#define mo 1000000007
#define M 4005
ll ksm(ll a,ll b){
	ll res=1;
	for (;b;b>>=1){
		if (b&1)res=res*a%mo;
		a=a*a%mo;
	}
	return res;
}
int n,m,top[M],cnt[M],son[M],de[M],L[M],tot,fa[M],id[M],nx[M],ecnt=1;
ll val,sum,len[M];
bool mark[M];
struct edg{
	int x,y;
	ll l;
	void init(){
		read(x); read(y); read(l);
	}
}edge[M];
bool cmp(edg a,edg b){
	return a.l<b.l;
}
struct ed{
	int x;
	ll l;
	int nx;
}e[M];
int get(int x){
	if (fa[x]==x)return x;
	return fa[x]=get(fa[x]);
}
void add(int x,int y,ll l){
	e[ecnt]=(ed){y,l,nx[x]};
	nx[x]=ecnt++;
}
void ins(int x,int y,ll l){
	add(x,y,l);
	add(y,x,l);
}
struct Reimu{
	ll f[M<<2];
	#define ls (p<<1)
	#define rs (p<<1|1)
	void build(int l,int r,int p){
		if (l==r){
			f[p]=len[id[l]];
			return;
		}
		int mid=(l+r)>>1;
		build(l,mid,ls);
		build(mid+1,r,rs);
		f[p]=max(f[ls],f[rs]);
	}
	ll qu(int l,int r,int x,int y,int p){
		if (l==x&&r==y){
			return f[p];
		}
		int mid=(l+r)>>1;
		if (y<=mid)return qu(l,mid,x,y,ls);
		if (x>mid)return qu(mid+1,r,x,y,rs);
		return max(qu(l,mid,x,mid,ls),qu(mid+1,r,mid+1,y,rs));
	}
}T;
void dfs1(int f,int x){
	cnt[x]=1; de[x]=de[f]+1; fa[x]=f;
	for (int i=nx[x];i;i=e[i].nx)if (e[i].x!=f){
		len[e[i].x]=e[i].l;
		dfs1(x,e[i].x);
		cnt[x]+=cnt[e[i].x];
		if (cnt[e[i].x]>cnt[son[x]]){
			son[x]=e[i].x;
		}
	}
}
void dfs2(int f,int x){
	L[x]=++tot; top[x]=f; id[tot]=x;
	if (son[x]){
		dfs2(f,son[x]);
		for (int i=nx[x];i;i=e[i].nx)if (e[i].x!=fa[x]&&e[i].x!=son[x]){
			dfs2(e[i].x,e[i].x);
		}
	}
}
ll chk(edg e){
	int x=e.x,y=e.y;
	ll res=0;
	for (;top[x]!=top[y];){
		if (de[top[x]]<de[top[y]])swap(x,y);
		Max(res,T.qu(1,n,L[top[x]],L[x],1));
		x=fa[top[x]];
	}
	if (de[x]>de[y])swap(x,y);
	if (L[x]<L[y])Max(res,T.qu(1,n,L[x]+1,L[y],1));
	return sum+e.l-res;
}
void solve1(){
	int i,tot=0;
	ll res;
	for (i=1;i<=m;i++){
		if (chk(edge[i])==val){
			tot++;
		}
	}
	res=ksm(2,m-tot)*(ksm(2,tot)-2)%mo;
	res=(res+mo)%mo;
	printf("%lld\n",res);
}
void solve2(){
	int i,tot1=0,tot2=0;
	ll res,tmp;
	for (i=1;i<=m;i++){
		tmp=chk(edge[i]);
		if (tmp==val){
			tot2++;
		}
		else if (tmp>val){
			tot1++;
		}
	}
	res=2*ksm(2,tot1)*(ksm(2,tot2)-1)%mo;
	res=(res+mo)%mo;
	printf("%lld\n",res);
}
int main(){
//	freopen("mysterium.in","r",stdin);
//	freopen("mysterium.out","w",stdout);
	read(n); read(m); read(val);
	int i,x,y;
	for (i=1;i<=m;i++)edge[i].init();
	for (i=1;i<=n;i++)fa[i]=i;
	sort(edge+1,edge+m+1,cmp);
	for (i=1;i<=m;i++){
		x=get(edge[i].x);
		y=get(edge[i].y);
		if (x!=y){
			fa[x]=y;
			sum+=edge[i].l;
			mark[i]=1;
			ins(edge[i].x,edge[i].y,edge[i].l);
		}
	}
	if (sum>val){
		printf("0\n");
	}
	else {
		dfs1(1,1);
		dfs2(1,1);
		T.build(1,n,1);
		if (sum==val){
			solve1();
		}
		else {
			solve2();
		}
	}
	return 0;
}

Measured memory_bytes: 512