#include <bits/stdc++.h>
using namespace std;
 
#define debug(x) cerr << #x << " = " << x << '\n';
#define BP() cerr << "OK!\n";
#define PR(A, n) cerr << #A << " = "; for (int i=1; i<=n; ++i) cerr << A[i] << ' '; cerr << '\n';
#define PR0(A, n) cerr << #A << " = "; for (int i=0; i<n; ++i) cerr << A[i] << ' '; cerr << '\n';

const int maxn = 2002;
const int MOD = 1000000007;

int n, m, lab[maxn], l[maxn];
bool inTree[maxn], visited[maxn];
pair<int, int> p[12][maxn];
vector<pair<int, int> > tr[maxn];
int64_t x;
vector<int> sameColor[maxn], difColor[maxn];

struct edge {
	int u, v, w, id;

	edge() {}
	edge(int u, int v, int w, int id):
		u(u), v(v), w(w), id(id)
	{}

	bool operator<(const edge e) {
		return w<e.w;
	} 
};
vector<edge> e;

int findset(int u) {
	return lab[u]<=0 ? u : lab[u] = findset(lab[u]);
}

void uni(int s, int t) {
	if (lab[s]<lab[t]) lab[t] = s;
	else if (lab[s]>lab[t]) lab[s] = t;
	else {
		lab[s] = t; --lab[t];
	}
}

int fixRoot(int u) {
	for (int i=0; i<tr[u].size(); ++i) {
		int v = tr[u][i].first, w = tr[u][i].second;
		if (v!=p[0][u].first) {
			l[v] = l[u] + 1;
			p[0][v] = make_pair(u, w);
			fixRoot(v);
		}
	}
}

void initTree(int edgeID) {
	memset(l, 0, sizeof(l));
	for (int i=1; i<=n; ++i)
		tr[i].clear();
	for (int i=0; i<e.size(); ++i)
		if (inTree[e[i].id]) {
			int w = e[i].id==edgeID ? 0 : e[i].w;
			tr[e[i].u].push_back(make_pair(e[i].v, w));
			tr[e[i].v].push_back(make_pair(e[i].u, w));
		}
	for (int i=1; i<=10; ++i)
		for (int j=1; j<=n; ++j)
			p[i][j] = make_pair(0, 0);
	fixRoot(1);
	for (int i=1; i<=10; ++i) {
		for (int j=1; j<=n; ++j) {
			p[i][j].first = p[i-1][p[i-1][j].first].first;
			p[i][j].second = max(p[i-1][j].second, p[i-1][p[i-1][j].first].second);
		}
	}
}

int getMax(int u, int v) {
	int res = 0;
	for (int k=10; k>=0; --k)
		if (l[p[k][u].first]>=l[v]) {
			res = max(res, p[k][u].second);
			u = p[k][u].first;
		}
	for (int k=10; k>=0; --k) {
		if (l[p[k][v].first]>=l[u]) {
			res = max(res, p[k][v].second);
			v = p[k][v].first;
		}
	}
	for (int k=10; k>=0; --k) {
		if (p[k][u].first!=p[k][v].first) {
			res = max(res, p[k][u].second);
			res = max(res, p[k][v].second);
			u = p[k][u].first; v = p[k][v].first;
		}
	}
	while (u!=v) {
		res = max(res, p[0][u].second);
		res = max(res, p[0][v].second);
		u = p[0][u].first; v = p[0][v].first;
	}
	return res;
}

int processEdge(edge e) {
	int s = findset(e.u), t = findset(e.v);
	if (s==t)
		return 0;
	uni(s, t);
	inTree[e.id] = true;
	return e.w;
}

void initEdge(int edgeID) {
	sort(e.begin(), e.end());
	memset(inTree, false, sizeof(inTree));
	memset(lab, 0, sizeof(lab));
	int64_t MST = 0;
	for (int i=0; i<e.size(); ++i)
		if (e[i].id==edgeID)
			MST += processEdge(e[i]);
	for (int i=0; i<e.size(); ++i)
	 	MST += processEdge(e[i]);
	initTree(edgeID);
	//debug(MST);
	for (int i=0; i<e.size(); ++i) {
		if (e[i].id==edgeID)
			continue;
		int64_t newMST = MST - getMax(e[i].u, e[i].v) + e[i].w;
		if (newMST<x)
			sameColor[edgeID].push_back(e[i].id);
		else if (newMST==x)
			difColor[edgeID].push_back(e[i].id);
	}
}

void dfs1(int u) {
	visited[u] = true;
	for (int i=0; i<sameColor[u].size(); ++i) {
		int v = sameColor[u][i];
		if (!visited[v])
			dfs1(v);
	}
}

void dfs2(int u) {
	visited[u] = true;
	for (int i=0; i<sameColor[u].size(); ++i) {
		int v = sameColor[u][i];
		if (!visited[v])
			dfs2(v);
	}
	for (int i=0; i<difColor[u].size(); ++i) {
		int v = difColor[u][i];
		if (!visited[v])
			dfs2(v);
	}
}

int64_t pw(int n, int k) {
	if (k==0)
		return 1;
	int64_t tmp = pw(n, k/2);
	return k%2 ? tmp*tmp%MOD*n%MOD : tmp*tmp%MOD;
}

void solve() {
	int nCC = 0;
	for (int i=1; i<=m; ++i) {
		if (!visited[i]) {
			++nCC;
			dfs1(i);
		}
	}
	int64_t res = pw(2, nCC);
	nCC = 0;
	memset(visited, false, sizeof(visited));
	for (int i=1; i<=m; ++i) {
		if (!visited[i]) {
			++nCC;
			dfs2(i);
		}
	}
	cout << (res - pw(2, nCC) + MOD) % MOD;
}

int main() {
	//freopen("sol.inp", "r", stdin);
	//freopen("sol.out", "w", stdout);
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m >> x;
	for (int i=1; i<=m; ++i) {
		int u, v, w;
		cin >> u >> v >> w;
		e.push_back(edge(u, v, w, i));
	}
	//initEdge(3);
	for (int i=1; i<=m; ++i)
		initEdge(i);
	//PR0(difColor[3], difColor[3].size());
	solve();
}

Measured memory_bytes: 18304