#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

typedef long long ll;
const int N=1010,M=2020,MOD=1000000007;
ll qpow(ll a,ll b){ll c=1;for(;b;b>>=1,a=a*a%MOD)if(b&1)c=c*a%MOD;return c;}

struct dus
{
	int q[N];
	void reset(int n){for(int i=1;i<=n;i++)q[i]=i;}
	int ask(int p){return p==q[p]?p:q[p]=ask(q[p]);}
	bool uni(int u,int v){return ask(u)==ask(v);}
	void link(int u,int v){q[ask(u)]=ask(v);}
}d;

struct edge
{
	int u,v,w;
	edge(int u0=0,int v0=0,int w0=0):u(u0),v(v0),w(w0){}
	bool operator < (const edge &A)const {return w<A.w;}
};

int begin[N],next[M],to[M],w[M];
int n,m,e;
ll wmst,lim;

void add(int x,int y,int z,bool k=1)
{
	to[++e]=y;
	next[e]=begin[x];
	begin[x]=e;
	w[e]=z;
	if(k)add(y,x,z,0);
}

int dis[N][N];

void dfs(int p,int h)
{
	for(int i=begin[p],q;i;i=next[i])
		if(dis[h][q=to[i]]==0)
			dis[h][q]=std::max(dis[h][p],w[i]),dfs(q,h);
}


edge E[M],_E[M];
int tot;

int cnt0,cnt1;

void work_counter()
{
	cnt0=cnt1=0;
	for(int i=1;i<=tot;i++)
	{
		ll x=_E[i].w-dis[_E[i].u][_E[i].v];

		if(wmst+x==lim)cnt0++;
		else if(wmst+x>lim)cnt1++;
	}
}

int main()
{
	scanf("%d%d%lld",&n,&m,&lim);
	for(int i=1,u,v,h;i<=m;i++)
		scanf("%d%d%d",&u,&v,&h),E[i]=edge(u,v,h);
	std::sort(E+1,E+m+1);
	d.reset(n),wmst=0;
	for(int i=1;i<=m;i++)
		if(!d.uni(E[i].u,E[i].v))add(E[i].u,E[i].v,E[i].w),d.link(E[i].u,E[i].v),wmst+=E[i].w;
		else _E[++tot]=E[i];

	if(lim<wmst){printf("0\n");return 0;}

	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			dis[i][j]=0;
	for(int i=1;i<=n;i++)
		dis[i][i]=-1,dfs(i,i);

	work_counter();

	int ans=2ll*(qpow(2,cnt0)-1)%MOD*qpow(2,cnt1)%MOD;
	if(lim==wmst)ans=(ans+(qpow(2,n-1)-2)*qpow(2,m-n+1)%MOD)%MOD;

	ans=(ans+MOD)%MOD;
	printf("%d\n",ans);

	return 0;
}
