#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <string>
#define _repargs(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define rep(...) _repargs(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define mod 1000000007
#define inf 2000000007
#define mp make_pair
#define pb push_back
typedef long long ll;
using namespace std;
template <typename T>
inline void output(T a, int p = 0) {
    if(p) cout << fixed << setprecision(p)  << a << "\n";
    else cout << a << "\n";
}
// end of template

struct edge{
    int f, t;
    ll cost;
    // define e1.cost < e2.cost : e1 < e2
    bool operator <(const edge &e) const {
        return cost < e.cost;
    }
};

// union find
class union_find {
public:
    int n;
    vector<int> parent, rnk, num;
    
    union_find(int n) : n(n), parent(n), rnk(n, 0), num(n, 1) {rep(i, n) parent[i] = i; }
    
    int root(int x){ return (parent[x] == x) ? x : root(parent[x]); }
    
    void unite(int x, int y){
        x = root(x);
        y = root(y);
        if (x == y) {
            return;
        }
        if (rnk[x] < rnk[y]) {
            parent[x] = y;
            num[y] += num[x];
        }
        else{
            parent[y] = x;
            num[x] += num[y];
            if (rnk[x] == rnk[y]) {
                rnk[x]++;
            }
        }
        n--;
    }
    
    bool same(int x, int y) {return root(x) == root(y);}
    
    int count(int x){ return num[root(x)]; }
};

class kruskal{
public:
    int v; // vertices
    vector<edge> e; // edges
    
    kruskal(int vt, vector<edge> e){
        v = vt;
        this->e = e;
    }
    
    ll mst(int first){
        sort(e.begin(), e.end());
        union_find uf(v);
        ll min_cost = 0;
        min_cost += e[first].cost;
        uf.unite(e[first].f, e[first].t);
        rep(i, e.size()){
            if(i == first) continue;
            edge &d = e[i];
            if (!uf.same(d.f, d.t)) {
                min_cost += d.cost;
                uf.unite(d.f, d.t);
            }
        }
        
        return min_cost;
    }
};

ll pow_mod(ll a, ll b, ll m){
    ll ret = 1;
    while (b > 0) {
        if (b & 1) {
            ret = ret * a % m;
        }
        a = a * a % m;
        b >>= 1;
    }
    return ret;
}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    // source code
    int N, M;
    cin >> N >> M;
    ll X;
    cin >> X;
    vector<edge> E;
    rep(i, M){
        int u, v;
        ll w;
        cin >> u >> v >> w;
        u--;
        v--;
        E.pb({u, v, w});
    }
    sort(all(E));
    vector<ll> C(M);
    int less = 0, just = 0;
    rep(i, M){
        kruskal K(N, E);
        C[i] = K.mst(i);
        if(C[i] < X) less++;
        else if(C[i] == X) just++;
    }
    ll ans;
    if(just == 0) {
        ans = 0;
    }
    else if(less == 0){
        ans = pow_mod(2, just, mod) - 2;
    }
    else {
        ans = 2 * pow_mod(2, just, mod) - 2;
    }
    (ans += mod) %= mod;
    ans *= pow_mod(2, M - less - just, mod);
    ans %= mod;
    
    output(ans);
    
    
    
    
    return 0;
}


Measured memory_bytes: 512