// Ho-kago Tea Time

#include <bits/stdc++.h>

using namespace std;

#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define fst first
#define snd second
#define SZ(u) ((int) (u).size())
#define ALL(u) (u).begin(), (u).end()

inline void proc_status()
{
	ifstream t("/proc/self/status");
	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}

template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline T read()
{
	register T sum(0), fg(1);
	register char ch(getchar());
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') fg = -1;
	for(;  isdigit(ch); ch = getchar()) sum = sum * 10 - '0' + ch;
	return sum * fg;
}

typedef long long LL;
typedef pair<int, int> pii;

const int MOD = (int) 1e9 + 7;

inline int fpm(int x, int y)
{
	int res = 1;
	for(; y; y >>= 1, x = (LL) x * x % MOD) if(y & 1) res = (LL) res * x % MOD;
	return res;
}

const int MAXN = (int) 1e5, MAXM = (int) 2e5;

struct edge
{
	int u, v, w;

	inline bool operator < (const edge &rhs) const { return this->w < rhs.w; }

	edge() { }
	edge(int _u, int _v, int _w): u(_u), v(_v), w(_w) { }
};

int n, m;
LL X;

edge E[MAXM + 5];

inline void input()
{
	n = read<int>(), m = read<int>(), X = read<LL>();
	for(int i = 1; i <= m; ++i) E[i].u = read<int>(), E[i].v = read<int>(), E[i].w = read<int>();
}

namespace SET
{
	int fa[MAXN + 5];

	inline void init(int N) { for(int i = 1; i <= N; ++i) fa[i] = i; }
	inline int get_fa(int u) { return u == fa[u] ? u : fa[u] = get_fa(fa[u]); }
	inline bool p(int u, int v) { return get_fa(u) == get_fa(v); }
	inline void link(int u, int v) { fa[get_fa(u)] = get_fa(v); }
}

vector<pii> adj[MAXN + 5];

const int MAX_LOG = 20;

int dep[MAXN + 5], w[MAXN + 5];
int anc[MAX_LOG + 1][MAXN + 5], mx[MAX_LOG + 1][MAXN + 5];

inline void dfs(int u, int fa)
{
	dep[u] = dep[fa] + 1;
	anc[0][u] = fa, mx[0][u] = w[u];
	for(int i = 1; (1 << i) < dep[u]; ++i)
	{
		anc[i][u] = anc[i - 1][anc[i - 1][u]];
		mx[i][u] = max(mx[i - 1][u], mx[i - 1][anc[i - 1][u]]);
	}

	for(int i = 0; i < SZ(adj[u]); ++i)
	{
		int v = adj[u][i].fst;
		if(v != fa) w[v] = adj[u][i].snd, dfs(v, u);
	}
}

inline int query(int u, int v)
{
	if(dep[u] < dep[v]) swap(u, v);

	int res = 0;
	for(int k = dep[u] - dep[v], i = 0; (1 << i) <= k; ++i) if(k >> i & 1) chkmax(res, mx[i][u]), u = anc[i][u];
	if(u == v) return res;

	for(int i = MAX_LOG; i >= 0; --i) if((1 << i) < dep[u] && anc[i][u] != anc[i][v])
	{
		chkmax(res, mx[i][u]), u = anc[i][u];
		chkmax(res, mx[i][v]), v = anc[i][v];
	}
	return max(res, max(w[u], w[v]));
}

inline void solve()
{
	sort(E + 1, E + m + 1);

	static int chosen[MAXM + 5];

	LL sum = 0;
	SET::init(n);
	for(int i = 1; i <= n; ++i) adj[i].clear();
	for(int i = 1; i <= m; ++i) chosen[i] = 0;
	for(int i = 1; i <= m; ++i) if(!SET::p(E[i].u, E[i].v))
	{
		chosen[i] = 1;
		SET::link(E[i].u, E[i].v), sum += E[i].w;
		adj[E[i].u].push_back(mp(E[i].v, E[i].w));
		adj[E[i].v].push_back(mp(E[i].u, E[i].w));
	}

	w[1] = 0, dfs(1, 0);

	if(sum > X) puts("0");
	else
	{
		int t = 0, k = 0;
		for(int i = 1; i <= m; ++i) if(!chosen[i])
		{
			LL res = sum + E[i].w - query(E[i].u, E[i].v);
			if(res == X) ++t;
			else if(res > X) ++k;
		}

		if(sum == X)
		{
			int ans = (LL) (fpm(2, m) - 2ll * fpm(2, m - (n - 1) - t) % MOD) % MOD;
			printf("%d\n", (ans + MOD) % MOD);
			return;
		}

		int ans = (LL) (fpm(2, t) - 1) % MOD * fpm(2, k + 1) % MOD;
		printf("%d\n", (ans + MOD) % MOD);
	}
}

int main()
{
#ifdef K_ON // K-ON!
	freopen("zhuzhu.in", "r", stdin);
	freopen("zhuzhu.out", "w", stdout);
#endif

	input();
	solve();

	return 0;
}



Measured memory_bytes: 12672