#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
struct edge {
	int to, cost;
};
int main() {
	int N, M, mod = 1000000007; long long X;
	cin >> N >> M >> X;
	vector<int> a(M), b(M), c(M), p(M);
	int all = 1;
	for (int i = 0; i < M; i++) cin >> a[i] >> b[i] >> c[i], p[i] = i, a[i]--, b[i]--;
	sort(p.begin(), p.end(), [&](int i, int j) { return c[i] < c[j]; });
	vector<vector<edge> > G(N);
	function<int(int, int, int)> dfs = [&](int pos, int pre, int tar) {
		if (pos == tar) return -(1 << 30);
		for (edge i : G[pos]) {
			if (i.to != pre) {
				int res = dfs(i.to, pos, tar);
				if (res != -1) return max(res, i.cost);
			}
		}
		return -1;
	};
	long long sum = 0;
	vector<long long> candy;
	for (int i = 0; i < M; i++) {
		int res = dfs(a[p[i]], -1, b[p[i]]);
		if (res == -1) {
			G[a[p[i]]].push_back(edge{ b[p[i]], c[p[i]] });
			G[b[p[i]]].push_back(edge{ a[p[i]], c[p[i]] });
			sum += c[p[i]];
			all = 2 * all % mod;
		}
		else candy.push_back(c[p[i]] - res);
	}
	int m1 = 1, m2 = 1, m3 = 1;
	for (long long i : candy) {
		long long val = i + sum;
		if (val >= X) m1 = 2 * m1 % mod;
		if (val > X) m2 = 2 * m2 % mod;
		m3 = 2 * m3 % mod;
	}
	int ret = 2LL * (m1 - m2 + mod) % mod;
	if (sum == X) ret = (ret + 1LL * (all + mod - 2) * m3) % mod;
	cout << ret << endl;
	return 0;
}