#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
using namespace std;
const int mo=1000000007;
const int N=2005;
int power(int x,int y){
	int s=1;
	for (;y;y/=2,x=1ll*x*x%mo)
		if (y&1) s=1ll*s*x%mo;
	return s;
}
struct Edge{
	int x,y,v;
	bool operator <(const Edge &a)const{
		return v<a.v;
	}
}E[N];
struct edge{
	int to,next,v;
}e[N];
int head[N],tot,n,m;
int fa[N],dep[N];
int fl[N],fav[N];
ll D;
void add(int x,int y,int v){
	e[++tot]=(edge){y,head[x],v};
	head[x]=tot;
}
void dfs(int x){
	for (int i=head[x];i;i=e[i].next)
		if (e[i].to!=fa[x]){
			fa[e[i].to]=x;
			dep[e[i].to]=dep[x]+1;
			fav[e[i].to]=e[i].v;
			dfs(e[i].to);
		}
}
int calc(int x,int y){
	int ans=0;
	for (;x!=y;){
		if (dep[x]<dep[y])
			swap(x,y);
		ans=max(ans,fav[x]);
		x=fa[x];
	}
	return ans;
}
int get(int x){
	return x==fa[x]?x:fa[x]=get(fa[x]);
}
void build_tree(){
	sort(E+1,E+m+1);
	For(i,1,n) fa[i]=i;
	For(i,1,m){
		int x=get(E[i].x);
		int y=get(E[i].y);
		if (x!=y){
			fl[i]=1; fa[x]=y;
			D-=E[i].v;
			add(E[i].x,E[i].y,E[i].v);
			add(E[i].y,E[i].x,E[i].v);
		}
	}
	For(i,1,n) fa[i]=0;
	dfs(1);
}
int main(){
	scanf("%d%d%lld",&n,&m,&D);
	For(i,1,m) scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].v);
	build_tree();
	if (D<0) return puts("0"),0;
	int eq=0,geq=0;
	For(i,1,m) if (!fl[i]){
		ll dif=E[i].v-calc(E[i].x,E[i].y);
		if (dif==D) ++eq; 
		if (dif>D) ++geq;
	}
	int ans=2ll*(power(2,eq)+mo-1)*power(2,geq)%mo;
	if (D==0) ans=(ans+1ll*(power(2,n-1)-2)*power(2,m-(n-1)))%mo;
	printf("%d\n",ans);
}