// Original C++ solution (slower):
//test https://blog.csdn.net/rising_shit/article/details/80739593

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define maxn 2005

#define _x1 x1

#define _x2 x2

using namespace std;

typedef long long ll;

const ll mod=1e9+7;

int n,m;

ll v;

int fa[maxn],id[maxn],x[maxn],y[maxn];

ll w[maxn];

int getfa(int now)

{

	return fa[now]==now ? now : fa[now]=getfa(fa[now]);

}

int cmp(int i,int j)

{

	return w[i]<w[j];

}

ll kruskal(int now)

{

	for(int i=1;i<=n;i++) fa[i]=i;

	ll ans=0;

	if(now)

		fa[x[now]]=y[now],ans+=w[now];

	for(int i=1;i<=m;i++)

	{

		int pos=id[i];

		int x1=getfa(x[pos]),y1=getfa(y[pos]);

		if(x1!=y1)

		{

			ans+=w[pos];

			fa[x1]=y1;

		}

	}

	return ans;

}

ll quickpow(ll p,ll k)

{

	ll ans=1;

	while(k)

	{

		if(k&1)

			ans=(ans*p)%mod;

		p=(p*p)%mod;

		k>>=1;

	}

	return ans;

}

int main()

{

	scanf("%d%d%lld",&n,&m,&v);

	for(int i=1;i<=m;i++)

		scanf("%d%d%lld",&x[i],&y[i],&w[i]),id[i]=i;

	sort(id+1,id+1+m,cmp);

 

	ll temp=kruskal(0);

 

	if(temp>v)

	return printf("0\n"),0;

 

	if(temp==v)

	{

		int cnt1=0,cnt2=0;

		for(int i=1;i<=m;i++)

		{

			if(kruskal(i)==temp)

				cnt1++;

			else

				cnt2++;

		}

		ll res1=(quickpow(2,cnt1)-2+mod)%mod;

		ll res2=quickpow(2,cnt2)%mod;

		return printf("%lld\n",res1*res2%mod),0;

	}

	else

	{

		int cnt1=0,cnt2=0;

		for(int i=1;i<=m;i++)

		{

			ll res1=kruskal(i);

			if(res1==v)

				cnt1++;

			else if(res1>v)

				cnt2++;

		}

		ll res1=2ll*((quickpow(2,cnt1)-1+mod)%mod)%mod;

		ll res2=quickpow(2,cnt2);

		printf("%lld\n",res1*res2%mod);

	}

}


// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>

#define ll long long

#define MOD 1000000007



//define

ll X;

int n, m;

struct Data{

	int x, y, v;

	bool operator<(const Data a)const{

		return v < a.v;

	}

}d[2333];



void input(){

	scanf("%d %d", &n, &m);

	scanf("%lld", &X);

	for(int i = 1; i <= m; i++)

		scanf("%d %d %d", &d[i].x, &d[i].y, &d[i].v);

	std::sort(d + 1, d + m + 1);

}



//work

ll ans;

int fa[1111];

int ls, mr, eq;



int find(int a){

	if(fa[a] == a) return a;

	return fa[a] = find(fa[a]);

}



void Kruskal(int a){

	ans = 0;

	for(int i = 1; i <= n; i++) fa[i] = i;

	ans = d[a].v;

	fa[d[a].x] = d[a].y;

	for(int i = 1; i <= m; i++){

		if(i == a) continue;

		int u = find(d[i].x), v = find(d[i].y);

		if(u == v) continue;

		fa[u] = v;

		ans = ans + d[i].v;

	}

	if(ans < X) ls++;

	if(ans == X) eq++;

	if(ans > X) mr++;

}



int Ans;



ll quickpow(ll p,ll k)

{

	ll tmp=1;

	while(k)

	{

		if(k&1)

			tmp=(tmp*p)%MOD;

		p=(p*p)%MOD;

		k>>=1;

	}

	return tmp;

}



void work(){

	/*p[0] = 1;

	for(int i = 1; i <= n; i++)

		p[i] = p[i - 1] * 2 % MOD;*/

	for(int i = 1; i <= m; i++) Kruskal(i);

	if(eq == 0) puts("0");

	else if(ls == 0)

		printf("%lld\n", 1ll * ((quickpow(2, eq) - 2 + MOD) % MOD) * quickpow(2, mr) % MOD);

	else

		printf("%lld\n", 2ll * ((quickpow(2, eq) - 1 + MOD) % MOD) % MOD * quickpow(2, mr) % MOD);

}



int main(){

	input();

	work();

	return 0;

}

// Fastest known solution for this problem: