#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <set>
#include <queue>
#include <map>
#include <numeric>
#include <math.h>
#include <functional>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;

#define INF ((int)1e9)
#define INFLL ((ll)1e18)
#define MOD (1000000007LL)

class UnionFind
{
public:
    explicit UnionFind(int N)
    {
        m_par.reserve(N);
        for (int n = 0; n < N; ++n) {
            m_par.push_back(n);
        }
    }
    int Root(int n)
    {
        if (n == m_par[n]) return n;
        return m_par[n] = Root(m_par[n]);
    }
    void Unite(int n, int m)
    {
        if (Root(n) == Root(m)) return;
        m_par[Root(n)] = Root(m);
    }
    bool Same(int n, int m)
    {
        return Root(n) == Root(m);
    }
private:
    vector<int> m_par;
};

class mod {
public:
    mod() {m_n = 0;}
    mod(ll n) {if (n >= 0) m_n = n % MOD; else m_n = n % MOD + MOD;}
    friend bool operator== (const mod& a, const mod& b) {return a.m_n == b.m_n;}
    friend bool operator!= (const mod& a, const mod& b) {return !(a == b);}
    friend mod operator+ (const mod& a, const mod& b) {return (a.m_n + b.m_n) % MOD;}
    friend mod& operator+= (mod& a, const mod& b) {return a = a + b;}
    friend mod operator- (const mod& a) {return -a.m_n;}
    friend mod operator- (const mod& a, const mod& b) {return (a.m_n + (-b.m_n)) % MOD;}
    friend mod& operator-= (mod& a, const mod& b) {return a = a - b;}
    friend mod operator* (const mod& a, const mod& b) {return (a.m_n * b.m_n) % MOD;}
    friend mod& operator*= (mod& a, const mod& b) {return a = a * b;}
    friend mod pow(const mod& n, ll r) {
        if (r == 0) {
            return 1;
        } else if (r < 0) {
            return pow(n, (MOD - 2) * (-r));
        } else if (r % 2 == 0) {
            mod tmp = pow(n, r / 2);
            return tmp * tmp;
        } else {
            return n * pow(n, r - 1);
        }
    }
    friend mod operator/ (const mod& a, const mod& b) {return a * pow(b, -1);}
    friend mod& operator/= (mod& a, const mod& b) {return a = a / b;}
    friend ostream& operator<< (ostream& os, const mod& n) {os << n.m_n; return os;}
    friend istream& operator>> (istream& is, mod& n) {ll tmp; is >> tmp; n = mod(tmp); return is;}
private:
    ll m_n;
};

int main(int argc, const char * argv[]) {
    ios_base::sync_with_stdio(false);
    int N, M;
    cin >> N >> M;
    ll X;
    cin >> X;
    set<pair<ll, pii>> setEdges;
    for (int m = 0; m < M; ++m) {
        int U, V;
        ll W;
        cin >> U >> V >> W;
        --U; --V;
        setEdges.insert({W, {U, V}});
    }
    
    ll MinW = 0;
    UnionFind UF(N);
    vector<vector<pil>> vvzTree(N);
    set<pair<ll, pii>> setTree;
    for (auto e : setEdges) {
        ll w = e.first;
        int u = e.second.first;
        int v = e.second.second;
        if (UF.Same(u, v)) continue;
        UF.Unite(u, v);
        MinW += w;
        vvzTree[u].push_back({v, w});
        vvzTree[v].push_back({u, w});
        setTree.insert(e);
    }
    
    if (MinW > X) {
        cout << 0 << endl;
        return 0;
    }
    
    vector<vector<ll>> vvlDist(N, vector<ll>(N, 0));
    vector<int> viUsed(N, 0);
    function<void(int, int)> DFS = [&](int a, int b)
    {
        viUsed[b] = 1;
        for (auto e : vvzTree[b]) {
            int next = e.first;
            if (viUsed[next]) continue;
            ll w = e.second;
            vvlDist[a][next] = max(vvlDist[a][b], w);
            DFS(a, next);
        }
    };
    for (int n = 0; n < N; ++n) {
        viUsed = vector<int>(N, 0);
        DFS(n, n);
    }
    
    int nLow = 0, nEq = 0, nUp = 0;
    for (auto e : setEdges) {
        if (setTree.count(e) > 0) {
            continue;
        }
        
        ll w = e.first;
        int u = e.second.first;
        int v = e.second.second;
        
        if (w-vvlDist[u][v] == X-MinW) {
            ++nEq;
        } else if (w-vvlDist[u][v] > X-MinW) {
            ++nUp;
        } else {
            ++nLow;
        }
    }
    cerr << nLow << ' ' << nEq << ' ' << nUp << endl;
    
    if (MinW == X) {
        cout << pow(mod(2), M) - 2*pow(mod(2), nUp) << endl;
    } else {
        cout << 2 * (pow(mod(2), nEq) - 1) * pow(mod(2), nUp) << endl;
    }
    
    return 0;
}


Measured memory_bytes: 8448