#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1000000007
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)

class UnionFind {
private:
    int sz;
    vector<int> par, nrank;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), nrank(sz, 0){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
    	if(nrank[x] < nrank[y]) swap(x,y);
        par[y] = x;
        if(nrank[x] == nrank[y]) nrank[x]++;
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};

vector<pair<ll,pair<int,int> > > e;
int n,m;
vector<bool> flag;
vector<vector<pair<int,ll> > > g;
ll calc(){
    UnionFind uf(n);
    ll res = 0;
    rep(i,m){
        int u = e[i].second.first;
        int v = e[i].second.second;
        if(!uf.same(u,v)){
            res += e[i].first;
            uf.unite(u,v);
            g[u].push_back(MP(v,e[i].first));
            g[v].push_back(MP(u,e[i].first));
            flag[i] = true;
        }
        
    }
    return res;
}
ll calc(int a,int b){
    UnionFind uf(n);
    uf.unite(a,b);
    ll res = 0;
    rep(i,m){
        int u = e[i].second.first;
        int v = e[i].second.second;
        if(!uf.same(u,v)){
            res += e[i].first;
            uf.unite(u,v);
            g[u].push_back(MP(v,e[i].first));
            g[v].push_back(MP(u,e[i].first));
            flag[i] = true;
        }
        
    }
    return res;
}

ll ruijo(ll x,ll n){
	long long p,ans;
	if(n==0)return 1;
	if(n==1)return x;
	if(n%2){
		p = ruijo(x,n/2);
		ans = (x*p)%mod;
		ans = (ans*p)%mod;
		return ans;
	}else{
		p = ruijo(x,n/2);
		ans = (p*p)%mod;
		return ans;
	}
}

ll dfs(int a,int pre, int b){
    if(a==b){
        return 0;
    }
    ll res = -1;
    for(auto x:g[a]){
        if(x.first==pre)continue;
        ll p = dfs(x.first,a,b);
        if(p!=-1){
            p = max(p,x.second);
        }
        res = max(p,res);
    }
    return res;
}


int main(){
    
    cin >> n >> m;
    
    g.resize(n);
    flag.resize(m);
    ll x;
    cin >> x;
    if(n<=2){
        cout << 0 << endl;
        return 0;
    }
    rep(i,m){
        int u,v;
        ll w;
        cin >> u >> v >> w;
        u--;v--;
        e.push_back(MP(w,MP(u,v)));
    }
    sort(e.begin(),e.end());
    ll ss = calc();
    //cerr <<ss << endl;
    ll ans = 0;
    ll res = 1;
    int cnt = 0;
    int cc = 0;
    rep(i,m){
        if(i==0)continue;
        if(!flag[i]){
            int u = e[i].second.first;
            int v = e[i].second.second;
            ll d = e[i].first;
            ll P = calc(u,v);
            //cerr << x << " " << d+P << endl;
            if(x > d+P){
                cc++; 
            }
            if(x== d+P){
                cnt++;
            }
        }
    }
    ll t = ruijo(2,cc)+mod-1;
    t%=mod;
    t *= ruijo(2,m-n-cc+1);
    t %= mod;
    //cerr <<t << endl;
    res = ruijo(2,m-n-cc-cnt+1);
    res += t;
    res %= mod;
    ans = res;
    //cerr << ans << endl;
    if(x!=ss){
        ll tmp = ruijo(2,n-2);
        tmp--;
        tmp *= ruijo(2,m-n+1);
        tmp %= mod;
        ans += tmp;
        ans %= mod;
    }
    //cerr << ans << endl;
    cout << (ruijo(2,m)+mod-ans*2%mod)%mod << endl;
    return 0;
}

Measured memory_bytes: 36840