#include<iostream>
#include<cstdio>
#include<cstring>
#include <cstdlib>  
#include <math.h>
#include <cmath>
#include<cctype>
#include<string>
#include<set>
#include<iomanip>
#include <map>
#include<algorithm>
#include <functional>
#include<vector>
#include<climits>
#include<stack>
#include<queue>
#include<bitset>
#include <deque>
#include <climits>
#include <typeinfo>
#include <utility> 
using namespace std;
using ll = long long;
template<typename T>using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
const ll inf = 1145141919810364364LL;
#define all(x) (x).begin(),(x).end()
#define puts(x) cout << x << endl
#define rep(i,m,n) for(ll i = m;i < n;++i)
#define pb push_back
#define fore(i,a) for(auto &i:a)
#define rrep(i,m,n) for(ll i = m;i >= n;--i)

struct LCA {
	vector<vector<int>>table;
	vector<int>dep;
	vector<vector<int>>e;
	const int LOG = 25;
	void dfs(int now,int par,int d) {
		table[now][0] = par;
		dep[now] = d;
		fore(x,e[now]) {
			if (x != par)dfs(x,now,d + 1);
		}
	}
	//0-indexed
	//edgesは双方向
	void lcainit(int n,int root,vector<int>edges[]){
		e.resize(n);
		dep.resize(n);
		table.resize(n);
		for (int i = 0; i < n; i++) {
			fore(x, edges[i])e[i].pb(x);
		}
		for (int i = 0; i < n; i++)table[i].resize(LOG);
		dfs(root,-1,0);
		for (int k = 0; k + 1 < LOG; k++) {
			for (int i = 0; i < n; i++) {
				if (table[i][k] == -1)table[i][k + 1] = -1;
				else table[i][k + 1] = table[table[i][k]][k];
			}
		}
	}

	int query(int u, int v) {
		if (dep[u] > dep[v])swap(u, v);
		for (int i = LOG - 1; i >= 0; i--) {
			if(((dep[v]-dep[u]) >> i) & 1)v = table[v][i];
		}
		if (u == v)return v;
		for (int i = LOG - 1; i >= 0;i--) {
			if (table[u][i] != table[v][i]) {
				u = table[u][i];
				v = table[v][i];
			}
		}
		return table[u][0];
	}
	int retdep(int u) { return dep[u]; }
};

class UnionFind {
public:
	vector<int> r, p;

	UnionFind() {}
	UnionFind(int size) {
		r.resize(size, 0);
		p.resize(size, 0);
		rep(i, 0, size)makeSet(i);
	}

	void makeSet(int x) {
		p[x] = x;
		r[x] = 0;
	}

	bool same(int x, int y) {
		return findSet(x) == findSet(y);
	}

	void unite(int x, int y) {
		link(findSet(x), findSet(y));
	}

	void link(int x, int y) {
		if (r[x] > r[y]) {
			p[y] = x;
		}
		else {
			p[x] = y;
			if (x == y) {
				r[y]++;
			}
		}
	}


	int findSet(int x) {
		if (x == p[x]) {
			return x;
		}
		else {
			return p[x] = findSet(p[x]);
		}
	}
};

ll MOD = 1e9 + 7;
ll modpow(ll a, ll n) {
	ll res = 1;
	while (n > 0) {
		if (n & 1) res = res * a % MOD;
		a = a * a % MOD;
		n >>= 1;
	}
	return res;
}

int N, M;
ll X;
set<pair<int, int>>st;
vector<vector<ll>>e;
vector<int>et[1010];
vector<pair<ll,int>>etc[1010];

ll ret = -1;
ll dfs(int now, int pa,ll curma,int target) {
	if (now == target)ret = curma;
	fore(x, etc[now]) {
		if (x.second != pa) {
			dfs(x.second,now,max(x.first,curma),target);
		}
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);


	cin >> N >> M >> X;
	min_priority_queue<vector<ll>>q;
	for (int i = 0; i < M; i++) {
		int u, v;
		ll w;
		cin >> u >> v >> w;
		u--, v--;
		q.push({w,u,v});
		e.pb({w,u,v});
	}

	UnionFind un = UnionFind(N);
	ll W = 0;
	while (q.size()) {
		auto V = q.top();
		q.pop();
		ll w = V[0];
		int u = V[1];
		int v = V[2];
		if (un.same(u, v))continue;
		un.unite(u, v);
		W += w;
		et[u].pb(v);
		et[v].pb(u);
		etc[u].pb({w,v});
		etc[v].pb({w,u});
		st.insert({ min(u,v),max(u,v) });
	}
	LCA lca;
	lca.lcainit(N, 0, et);


	ll hi = 0;
	ll eq = 0;
	for (int i = 0; i < M; i++) {
		ll w = e[i][0];
		int u = e[i][1];
		int v = e[i][2];
		if (st.count({ min(u,v),max(u,v) }))continue;
		int r = lca.query(u, v);
		ret = -1;
		ll cost1 = dfs(r, -1, -1, u);
		ret = -1;
		ll cost2 = dfs(r, -1, -1, v);
		ll newcost = W - max(cost1,cost2) + w;
		if (newcost == X)eq++;
		if (newcost > X)hi++;
	}


	int K = N - 1;
	int L = M - K;
	ll num1 = modpow(2, L)*(modpow(2,K) - 2 + MOD);
	num1 %= MOD;
	ll num2 = 2LL * modpow(2, hi) * (modpow(2, eq) - 1 + MOD);
	num2 %= MOD;
	if (W > X)puts(0);
	else if (W == X)puts((num1 + num2)%MOD);
	else puts(num2 % MOD);

	return 0;
}

Measured memory_bytes: 896