#include <iostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <cstring>
#include <chrono>
#include <vector>
#include <map>
#include <random>
#include <set>
#include <algorithm>
#include <math.h>
#include <cstdio>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <cstdlib>
#include <deque>
#include <cassert>
#include <stack>
using namespace std;
 
#define mp make_pair
#define f first
#define se second
#define pb push_back
#define ppb pop_back
#define emb emplace_back
#define ll long long
#define ull unsigned long long
#define cntbit(x) __builtin_popcount(x)
#define endl '\n'
#define uset unordered_set
#define umap unordered_map
#define pii pair<int, int>
#define ld long double
#define pll pair<long long, long long>
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
 
template <typename T> inline T range(T l, T r) {
    return uniform_int_distribution<T>(l, r)(rng);
}
 
inline void setin(string s) {
    freopen(s.c_str(), "r", stdin);
}
 
inline void setout(string s) {
    freopen(s.c_str(), "w", stdout);
}
 
template <typename T> void Min(T &a, T b) {
    a = min(a, b);
}
 
template <typename T> void Max(T &a, T b) {
    a = max(a, b);
}

#define int long long

const int mod = 1e9 + 7;
const int inf = 2e9;
const int N = 2e3 + 15;
int n, m, x, s, d;

struct edge {
    int u, v, w;
    bool operator < (const edge &rhs) const {
        return w < rhs.w;
    }
} e[N];

struct dsu {
    int p[N];
    dsu() {
        for(int i = 0; i < N; ++i)
            p[i] = i;
    }
    inline int find(int v) {
        if(v == p[v])
            return v;
        return p[v] = find(p[v]);
    }
    inline void unio(int a, int b) {
        a = find(a);
        b = find(b);
        p[b] = a;
    }
} js;

int diff[N];
vector <int> g[N];
bool mst[N];
int pw[N];
int eq, upper;
int p[N];
int ans;

void dfs(int v) {
    for(int ind : g[v]) {
        if(ind == p[v])
            continue;
        int to = e[ind].u == v ? e[ind].v : e[ind].u;
        p[to] = ind;
        dfs(to);
    }
}

inline int get_max(int u, int v) {
    p[u] = -1;
    dfs(u);
    int res = 0;
    while(v != u) {
        int ind = p[v];
        Max(res, e[ind].w);
        v = e[ind].u == v ? e[ind].v : e[ind].u;
    }
    return res;
}

inline int add(int a, int b) {
    return (((a + b) % mod) + mod) % mod;
}

inline void add_t(int &a, int b) {
    a = add(a, b);
}

inline int mt(int a, int b) {
    return 1ll * a * b % mod;
}

main() {
    pw[0] = 1;
    for(int i = 1; i < N; ++i)
        pw[i] = add(pw[i-1], pw[i-1]);
    ios_base::sync_with_stdio(0); cout.tie(0); cin.tie(0);
    // setin("input.txt");
    cin >> n >> m >> x;
    for(int i = 0; i < m; ++i)
        cin >> e[i].u >> e[i].v >> e[i].w;
    sort(e, e + m);
    for(int i = 0; i < m; ++i) {
        int u = e[i].u, v = e[i].v;
        if(js.find(u) != js.find(v)) {
            mst[i] = true;
            js.unio(u, v);
            g[u].pb(i);
            g[v].pb(i);
            s += e[i].w;
        }
    }
    d = x - s;
    if(d < 0)
        return cout << 0 << endl, 0;
    for(int i = 0; i < m; ++i) {
        if(mst[i])
            continue;
        diff[i] = e[i].w - get_max(e[i].u, e[i].v);
        eq += diff[i] == d;
        upper += diff[i] > d;
    }

    if(d == 0)
        ans = mt(add(pw[n - 1], -2), pw[m - n + 1]);
    add_t(ans, mt(2, mt(pw[eq] - 1, pw[upper])));
    cout << ans << endl;
    return 0;
}

Measured memory_bytes: 3844