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

#define MOD 1000000007

using namespace std;

typedef long long LL;

const int MAXN = 1000 + 10;
const int MAXM = 2000 + 10;

inline LL power (LL x, int p) {
	LL cnt = 1;
	while (p) {
		if (p & 1) cnt = cnt * x % MOD;
		x = x * x % MOD;
		p >>= 1;
	}
	return cnt;
}
LL pow2[MAXM]= {0};

struct LFS { int to, w, next; };
LFS Link[MAXM << 1];
int Head[MAXN]= {0}, sze = 0;
void Insert (int u, int v, int w) {
	Link[++ sze].to = v;
	Link[sze].w = w;
	Link[sze].next = Head[u];

	Head[u] = sze;
}

LL fact[MAXM]= {0}, invfact[MAXM]= {0};
LL inv[MAXM]= {0};
inline LL C (int n, int m) { return fact[n] * invfact[m] % MOD * invfact[n - m] % MOD; }

int N, M;
LL X;
struct Edge {
	int u, v, w;
	Edge (int u = 0, int v = 0, int w = 0) : u (u), v (v), w (w) {}
	bool operator < (const Edge& p) const { return w < p.w; }
} ;
Edge edge[MAXM];

int fa[MAXN]= {0};
int find (int x) { return fa[x] == x ? x : fa[x] = find (fa[x]); }
LL Kruskal () {
	LL ret = 0;
	for (int i = 1; i <= M; i ++) {
		int x = edge[i].u, y = edge[i].v, w = edge[i].w;
		int fx = find (x), fy = find (y);
		if (fx == fy) continue;
		fa[fx] = fy; ret += w;
		Insert (x, y, w), Insert (y, x, w);
	}
	return ret;
}
int white[MAXM]= {0}, black[MAXM]= {0};
int wn = 0, bn = 0;
LL cencus () {
	LL ret = 0;
	for (int q = 1; q <= bn; q ++) {
		int i = black[q];
		for (int j = 1; j <= N; j ++) { fa[j] = j; Head[j] = 0; }
		sze = 0;
		int u = edge[i].u, v = edge[i].v, w = edge[i].w;
		fa[u] = v;
		Insert (u, v, w), Insert (v, u, w);
		Kruskal ();
		LL add = 0;
		for (int j = 0; j <= bn - 1 - (! wn); j ++)
			add = (add + C (bn - 1, j) * inv[j + 1] % MOD) % MOD;
		ret = (ret + add) % MOD;
	}
	if (wn) ret = 2ll * ret % MOD;
	return ret;
}
LL solve () {
	LL ans = 0; int ext = 0;
	for (int i = 1; i <= M; i ++) {
		if (1ll * edge[i].w > X) { ext ++; continue; }
		for (int j = 1; j <= N; j ++) { fa[j] = j; Head[j] = 0; }
		sze = 0;
		int u = edge[i].u, v = edge[i].v, w = edge[i].w;
		fa[u] = v;
		LL x = w + Kruskal ();
		if (x < X) white[++ wn] = i;
		else if (x == X) black[++ bn] = i;
		else ext ++;
	}
	// cout << "first: " << wn << ' ' << bn << ' ' << ext << endl;
	ans = cencus ();
	ans = ans * pow2[ext] % MOD;
	return ans;
}

inline int getnum () {
	int num = 0; char ch = getchar ();
	while (! isdigit (ch)) ch = getchar ();
	while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar ();
	return num;
}

int main () {
	N = getnum (), M = getnum (); cin >> X;
	if (N == 1) { puts ("0"); return 0; }
	pow2[0] = 1;
	for (int i = 1; i <= max (N, M); i ++) pow2[i] = pow2[i - 1] * 2ll % MOD;
	fact[0] = invfact[0] = 1;
	inv[1] = fact[1] = invfact[1] = 1;
	for (int i = 2; i <= M; i ++) {
		inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
		fact[i] = fact[i - 1] * i % MOD;
		invfact[i] = invfact[i - 1] * inv[i] % MOD;
	}
	for (int i = 1; i <= M; i ++) {
		int u = getnum (), v = getnum (), w = getnum ();
		edge[i] = Edge (u, v, w);
	}
	sort (edge + 1, edge + M + 1);
	cout << solve () << endl;
	
	return 0;
}

/*
3 3
2
1 2 1
2 3 1
3 1 1
*/

/*
3 3
3
1 2 1
2 3 1
3 1 2
*/

/*
5 4
20
1 2 3
1 3 3
2 4 6
2 5 8
*/

/*
8 10
49
4 6 10
8 4 11
5 8 9
1 8 10
3 8 128773450
7 8 10
4 2 4
3 4 1
3 1 13
5 2 2
*/

/*
8 15
49
4 6 10
8 4 11
5 8 9
1 8 10
3 8 12
7 8 10
4 2 4
3 4 1
3 1 13
5 2 2
5 1 13
6 2 12
4 7 14
2 8 233333
2 7 233333
*/

Measured memory_bytes: 3780