#include <iostream>
#include <fstream>
#include <cmath>  
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <numeric>
#include <functional>
#include <string> 
#include <vector>
#include <bitset>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;

#define REP(i,n) for(int i = 0; i < int(n); i++)
#define REREP(i,n) for(int i = int(n - 1); i >= 0; i--)
#define FOR(i, m, n) for(int i = int(m);i < int(n);i++)
#define REFOR(i, m, n) for(int i = int(n - 1);i >= int(m);i--)
#define ALL(obj) (obj).begin(),(obj).end()
#define fi first 
#define se second

#define VI vector<int>
#define VVI vector<vector<int>>
#define VVVI vector<vector<vector<int>>>
#define VD vector<double>
#define VVD vector<vector<double>>
#define VVVD vector<vector<vector<double>>>
#define VL vector<ll>
#define VVL vector<vector<ll>>
#define VVVL vector<vector<vector<ll>>>
#define VB vector<bool>
#define VVB vector<vector<bool>>
#define VVVB vector<vector<vector<bool>>>
#define VS vector<string>
#define VVS vector<vector<string>>
#define VVVS vector<vector<vector<string>>>

#define PII pair<int,int>
#define PDD pair<double,double>
#define PLL pair<ll,ll>
#define VPII vector<pair<int,int>>
#define VVPII vector<vector<pair<int,int>>>
#define VVVPII vector<vector<vector<pair<int,int>>>>
#define VPLL vector<pair<ll,ll>>
#define VVPLL vector<vector<pair<ll,ll>>>
#define VVVPLL vector<vector<vector<pair<ll,ll>>>>

const ll MOD = (ll)1e9 + 7;
const ll HINF = (ll)1e18;
const ll LINF = (ll)1e9;
const long double PI = 3.1415926535897932384626433;


void YN(bool flag) {
	cout << ((flag) ? "YES" : "NO") << endl;
}

void Yn(bool flag) {
	cout << ((flag) ? "Yes" : "No") << endl;
}

void yn(bool flag) {
	cout << ((flag) ? "yes" : "no") << endl;
}

template<class T> class Union_Find {
public:
	vector<int> prnt;
	vector<int> rank;
	vector<T> dist;

	Union_Find(int N = 1):prnt(vector<int>(N)),rank(vector<int>(N,0)),dist(vector<int>(N, 0)) {
		for (int i = 0; i < N; ++i) prnt[i] = i;
	}

	int root(int x) {
		if (prnt[x] == x) return x;
		else {
			int r = root(prnt[x]);
			dist[x] += dist[prnt[x]];
			return prnt[x] = r;
		}
	}

	T updated_dist(int x) {
		root(x);
		return dist[x];
	}

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

	bool merge(int x, int y, T d) {
		d += updated_dist(x); 
		d -= updated_dist(y);
		x = root(x); y = root(y);
		if (x == y) return false;
		if (rank[x] < rank[y]) {
			swap(x, y);
			d = -d;
		}
		if (rank[x] == rank[y]) ++rank[x];
		prnt[y] = x;
		dist[y] = d;
		return true;
	}

	T diff(int x, int y) {
		return updated_dist(y) - updated_dist(x);
	}
};

int main() {
	ll N, M, X; cin >> N >> M >> X;
	vector<pair<ll, pair<int, int>>> edge(M);

	REP(i, M) {
		int U, V;
		ll W;
		cin >> U >> V >> W;
		U--;
		V--;
		edge[i] = { W, {U,V} };
	}
	sort(ALL(edge));

	if (N <= 2 || M < 2) {
		cout << 0 << endl;
		return 0;
	}

	VL pow2(M + 1,1);
	FOR(i, 1, M + 1) pow2[i] = (pow2[i - 1] * 2) % MOD;
	
	ll weight = 0;
	VB org(M,false);
	Union_Find<int> UForg(N);
	REP(i, M) {
		int U = edge[i].se.fi;
		int V = edge[i].se.se;
		ll W = edge[i].fi;

		if (UForg.same(U, V)) continue;

		UForg.merge(U, V, 1);
		weight += W;
		org[i] = true;
	}
		
	ll ans = 0;
	if(weight == X) (ans += (((pow2[N-1] - 2)*pow2[M - (N - 1)]) % MOD)) %= MOD;

	if (M == N - 1) {
		cout << ans << endl;
		return 0;
	}

	int cnt = 0;
	VL sum(M - (N - 1), LINF);

	FOR(i, 1, M) {
		if (org[i]) continue;

		Union_Find<int> UF(N);
		weight = edge[0].fi + edge[i].fi;
		UF.merge(edge[0].se.fi, edge[0].se.se, 1);
		UF.merge(edge[i].se.fi, edge[i].se.se, 1);
		cnt++;
		
		FOR(j, 1, M) {
			int U = edge[j].se.fi;
			int V = edge[j].se.se;
			ll W = edge[j].fi;

			if (UF.same(U, V)) continue;
			
			UF.merge(U, V, 1);
			weight += W;
		}

		bool flg = true;
		FOR(j, 1, N) if (flg && !UF.same(0, j)) flg = false;

		if (flg) sum[cnt - 1] = weight;

		//if (flg && weight == X && M - (N - 1) - cnt >= 0) {
		//	(ans += ((2 * pow2[M - (N - 1) - cnt]) % MOD)) %= MOD;
		//}
		//cout << i << " " << weight << " " << (2 * pow2[M - (N - 1) - cnt]) << endl;
	}

	sort(ALL(sum));
	REP(i, M - (N - 1)) if(sum[i] == X) (ans += ((2 * pow2[M - (N - 1) - (i + 1)]) % MOD)) %= MOD;
	cout << ans << endl;
	
	return 0;
}


Measured memory_bytes: 384