#include <bits/stdc++.h>
#define int long long
using namespace std;
const int M = 1000, LG = 11;
int binup[M][LG], weight[M][LG];
struct Edge{int u; int v; int w;};
struct Vertex{int f; int r;};
vector<Edge> edges;
vector<Vertex> snm;
vector<vector<pair<int, int> > > gr;
vector<vector<int> > bad, good, comm;
vector<int> tin, tout, h, comp;
vector<bool> us;
int timer, glu, glv;
int get(int v){
    if (snm[v].f == v) return v;
    snm[v].f = get(snm[v].f);
    return snm[v].f;
}
void un(int a, int b){
    if (snm[a].r > snm[b].r){
        snm[b].f = a;
    }
    else if (snm[a].r < snm[b].r){
        snm[a].f = b;
    }
    else{
        snm[b].f = a;
        snm[a].r++;
    }
}
void dfs(int vertex, int last, int R, int H){
    if (vertex == glu && last == glv) R = 0;
    if (vertex == glv && last == glu) R = 0;
    h[vertex] = H;
    tin[vertex]=timer;
    timer++;
    if (last != -1){
        binup[vertex][0] = last, weight[vertex][0] = R;
        int nv = last, lvl=0;
        while (binup[nv][lvl] != -1){
            binup[vertex][lvl+1] = binup[nv][lvl];
            weight[vertex][lvl+1] = max(weight[vertex][lvl], weight[nv][lvl]);
            nv = binup[nv][lvl];
            lvl++;
        }
    }
    for (int i=0; i < gr[vertex].size(); i++){
        int to = gr[vertex][i].first;
        if (last == to) continue;
        dfs(to, vertex, gr[vertex][i].second, H+1);
    }
    tout[vertex]=timer;
    timer++;
}
int lca(int u, int v){
    if (tin[u] <= tin[v] && tout[u] >= tout[v]) return u;
    if (tin[v] <= tin[u] && tout[v] >= tout[u]) return v;
    int nv = u;
    for (int i=LG-1; i >= 0; i--){
        if (binup[nv][i] == -1) continue;
        int cand = binup[nv][i];
        if (tin[cand] <= tin[v] && tout[cand] >= tout[v]) continue;
        nv = cand;
    }
    return binup[nv][0];
}
int G(int v, int sk){
    if (sk==0) return 0;
    int cd = 0;
    for (int i=0; i < LG; i++){
        int ba = sk & (1LL<<i);
        if (ba==0) continue;
        cd = max(cd, weight[v][i]);
        v = binup[v][i];
    }
    return cd;
}
void Dfs(int vertex){
    comp[vertex] = timer;
    for (int i=0; i < bad[vertex].size(); i++){
        int to = bad[vertex][i];
        if (comp[to] != -1) continue;
        Dfs(to);
    }
}
void dfs2(int vertex){
    us[vertex] = true;
    for (int i=0; i < comm[vertex].size(); i++){
        int to = comm[vertex][i];
        if (us[to]) continue;
        dfs2(to);
    }
}
bool cmp(Edge f, Edge s){
    return (f.w < s.w);
}
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m, x;
    cin >> n >> m >> x;
    for (int i=0; i < m; i++){
        int U, V, W;
        cin >> U >> V >> W;
        edges.push_back({U-1, V-1, W});
        vector<int> hh, hhh;
        bad.push_back(hh);
        good.push_back(hhh);
        comp.push_back(-1);
    }
    sort(edges.begin(), edges.end(), cmp);
    for (int i=0; i < n; i++){
        tin.push_back(-1);
        tout.push_back(-1);
        h.push_back(-1);
    }
    for (int i=0; i < edges.size(); i++){
        glu = edges[i].u, glv = edges[i].v;
        snm.clear();
        vector<int> nv;
        nv.push_back(i);
        for (int j=0; j < n; j++) snm.push_back({j, 1});
        un(edges[i].u, edges[i].v);
        for (int j=0; j < m; j++){
            if (j==i) continue;
            if (get(edges[j].u) == get(edges[j].v)) continue;
            nv.push_back(j);
            un(get(edges[j].u), get(edges[j].v));
        }
        int ost = 0;
        for (int j=0; j < nv.size(); j++) ost += edges[nv[j]].w;
        vector<bool> used(m);
        fill(used.begin(), used.end(), false);
        for (int j=0; j < nv.size(); j++) used[nv[j]] = true;
        gr.clear();
        for (int j=0; j < n; j++){
            vector<pair<int, int> > help;
            gr.push_back(help);
        }
        for (int j=0; j < nv.size(); j++){
            int uu = edges[nv[j]].u;
            int vv = edges[nv[j]].v;
            int ww = edges[nv[j]].w;
            gr[uu].push_back({vv, ww});
            gr[vv].push_back({uu, ww});
        }
        for (int j=0; j < n; j++) for (int p=0; p < LG; p++) binup[j][p] = -1;
        for (int j=0; j < n; j++) for (int p=0; p < LG; p++) weight[j][p] = -1;
        timer=0;
        dfs(0, -1, -1, 0);
        for (int j=0; j < m; j++){
            if (used[j]){
                if (ost < x){
                    bad[i].push_back(j);
                    bad[j].push_back(i);
                }
                if (ost==x){
                    good[i].push_back(j);
                    good[j].push_back(i);
                }
            }
            else{
                int U = edges[j].u, V = edges[j].v, W = edges[j].w;
                int L = lca(U, V);
                int mx = G(U, h[U] - h[L]);
                mx = max(mx, G(V, h[V] - h[L]));
                int O = ost + W - mx;
                if (O < x){
                    bad[i].push_back(j);
                    bad[j].push_back(i);
                }
                if (O==x){
                    good[i].push_back(j);
                    good[j].push_back(i);
                }
            }
        }
    }
    timer = 0;
    for (int i=0; i < m; i++){
        if (comp[i] == -1){
            Dfs(i);
            timer++;
        }
    }
    for (int i=0; i < timer; i++){
        vector<int> help;
        comm.push_back(help);
        us.push_back(false);
    }
    for (int i=0; i < m; i++){
        for (int j=0; j < good[i].size(); j++){
            int to = good[i][j];
            int A = comp[i], B = comp[to];
            if (A==B) continue;
            comm[A].push_back(B);
            comm[B].push_back(A);
        }
    }
    int MOD = 1000000007;
    int ans = 1, vc=1;
    for (int i=0; i < timer; i++){
        ans *= 2;
        ans %= MOD;
    }
    for (int i=0; i < timer; i++){
        if (us[i]) continue;
        dfs2(i);
        vc *= 2;
        vc %= MOD;
    }
    ans -= vc;
    ans %= MOD;
    if (ans < 0) ans += MOD;
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 119680