/********************************************************************************
	
	Code by a weak man who named CYJian, and he hopes the code can get more points.

	Algorithm: 

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

//{{{ FAST IO AND SOME FUNCTIONS
const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s"in", "r", stdin), freopen(s"out", "w", stdout), freopen(s"log", "w", stderr)

template<typename T>
inline void read(T &x) {
	char ch, t = 0; x = 0;
	while(!isdigit(ch = ge)) t |= ch == '-';
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = ge;
	x = t ? -x : x;
}
inline int read_int() { int x; return read(x), x; }
inline ll read_ll() { ll x; return read(x), x; }

template<typename T> inline void chkmin(T&a, T b) { a = a < b ? a : b; }
template<typename T> inline void chkmax(T&a, T b) { a = a > b ? a : b; }
//}}}

const int mod = 1e9 + 7;
const int MAXM = 2010;
const int MAXN = 1010;

inline int fsp(int x, int k = mod - 2) {
	int s = 1;
	while(k) {
		if(k & 1) s = 1LL * s * x % mod;
		x = 1LL * x * x % mod, k >>= 1;
	} return s;
}

int tot;
int fi[MAXM];
int ne[MAXM];
int to[MAXM];
int le[MAXM];

struct Edge {
	int u, v, used, w;

	friend bool operator < (Edge a, Edge b) { return a.used == b.used ? a.w < b.w : a.used > b.used; }

	inline void Link() {
		tot++, le[tot] = w, to[tot] = v, ne[tot] = fi[u], fi[u] = tot;
		tot++, le[tot] = w, to[tot] = u, ne[tot] = fi[v], fi[v] = tot;
	}
}E[MAXM];

struct UFS {
	int fa[MAXN];

	inline void init(int n) { for(int i = 1; i <= n; i++) fa[i] = i; }
	inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
	inline int Merge(int u, int v) { return find(u) == find(v) ? 0 : (fa[find(u)] = find(v), 1); }
}ufs;

int dep[MAXN];
int fa[13][MAXN];
int mx[13][MAXN];

inline void dfs(int x, int la) {
	fa[0][x] = la, dep[x] = dep[la] + 1;
	for(int i = 1; i < 13; i++) {
		fa[i][x] = fa[i - 1][fa[i - 1][x]];
		mx[i][x] = max(mx[i - 1][x], mx[i - 1][fa[i - 1][x]]);
	}
	for(int i = fi[x]; i; i = ne[i]) {
		int u = to[i];
		if(u == la) continue;
		mx[0][u] = le[i];
		dfs(u, x);
	}
}

inline int Qmx(int u, int v) {
	if(dep[u] < dep[v]) swap(u, v);
	int k = dep[u] - dep[v], res = 0;
	for(int i = 0; i < 13; i++)
		if(k & (1 << i)) {
			chkmax(res, mx[i][u]);
			u = fa[i][u];
		}
	if(u == v) return res;
	for(int i = 12; ~i; --i)
		if(fa[i][u] != fa[i][v]) {
			chkmax(res, max(mx[i][u], mx[i][v]));
			u = fa[i][u], v = fa[i][v];
		}
	return max(res, max(mx[0][u], mx[0][v]));
}

int main() {
#ifdef LOCAL
	FILE("");
#endif

	int n = ri, m = ri;
	ll X = rl;

	for(int i = 1; i <= m; i++)
		E[i].u = ri, E[i].v = ri, E[i].w = ri;
	sort(E + 1, E + 1 + m);

	ll sum = 0; ufs.init(n);
	for(int i = 1, ct = 0; i <= m && ct < n - 1; i++)
		if(ufs.Merge(E[i].u, E[i].v)) E[i].used = 1, sum += E[i].w, ++ct, E[i].Link();

	int res = 0;

	if(sum > X) return puts("0"), 0;
	if(sum == X) res = (fsp(2, m) - fsp(2, m - n + 2) + mod) % mod;

	dfs(1, 0);

	for(int i = 1; i <= m; i++) if(!E[i].used) E[i].w -= Qmx(E[i].u, E[i].v);
	sort(E + 1, E + 1 + m);
	for(int i = n; i <= m; i++)
		if(E[i].w + sum == X)
			res += fsp(2, m - i + 1), res -= res >= mod ? mod : 0;
	cout << res << endl;
	return 0;
}

Measured memory_bytes: 3860