#include <bits/stdc++.h>
#define FOR(i, a, n) for(ll i = (ll)a; i < (ll)n; i++)
#define FORR(i, n) for(ll i = (ll)n - 1LL; i >= 0LL; i--)
#define rep(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)
using namespace std;
using ll = long long;
constexpr ll Mod = 998244353;
constexpr ll mod = 1e9 + 7;
constexpr ll inf = 1LL << 60;
const double PI = acos(-1);
template <typename T> constexpr bool chmax(T &a, const T &b) {
    if(a >= b) return false;
    a = b;
    return true;
}
template <typename T> constexpr bool chmin(T &a, const T &b) {
    if(a <= b) return false;
    a = b;
    return true;
}

/*-------------------------------------------*/

template <int M> class ModInt {
    int x;

  public:
    constexpr ModInt() : x(0) {}
    constexpr ModInt(int64_t y) : x(y >= 0 ? y % M : (M - (-y) % M) % M) {}
    constexpr ModInt &operator+=(const ModInt p) {
        if((x += p.x) >= M) x -= M;
        return *this;
    }
    constexpr ModInt &operator-=(const ModInt p) {
        if((x += M - p.x) >= M) x -= M;
        return *this;
    }
    constexpr ModInt &operator*=(const ModInt p) {
        x = (int)(1LL * x * p.x % M);
        return *this;
    }
    constexpr ModInt &operator/=(const ModInt p) {
        *this *= p.inverse();
        return *this;
    }
    constexpr ModInt operator-() const { return ModInt(-x); }
    constexpr ModInt operator+(const ModInt p) const {
        return ModInt(*this) += p;
    }
    constexpr ModInt operator-(const ModInt p) const {
        return ModInt(*this) -= p;
    }
    constexpr ModInt operator*(const ModInt p) const {
        return ModInt(*this) *= p;
    }
    constexpr ModInt operator/(const ModInt p) const {
        return ModInt(*this) /= p;
    }
    constexpr bool operator==(const ModInt p) const { return x == p.x; }
    constexpr bool operator!=(const ModInt p) const { return x != p.x; }
    constexpr ModInt inverse() const {
        int a = x, b = M, u = 1, v = 0, t = 0;
        while(b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return ModInt(u);
    }
    constexpr ModInt pow(int64_t k) const {
        ModInt ret(1), mul(x);
        while(k > 0) {
            if(k & 1) ret *= mul;
            mul *= mul;
            k >>= 1;
        }
        return ret;
    }
    constexpr friend ostream &operator<<(ostream &os, const ModInt &p) {
        return os << p.x;
    }
    constexpr friend istream &operator>>(istream &is, ModInt &a) {
        int64_t t = 0;
        is >> t;
        a = ModInt(t);
        return (is);
    }
};
using mint = ModInt<mod>;

class UnionFind {
    vector<int> par;
    int c;

  public:
    UnionFind(int n) { init(n); }
    void init(int n) {
        par.assign(n, -1);
        c = n;
    }
    int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
    int size(int x) { return -par[find(x)]; }
    int count() const { return c; }
    bool same(int x, int y) { return find(x) == find(y); }
    bool unite(int x, int y) {
        if((x = find(x)) == (y = find(y))) return false;
        if(par[x] < par[y]) swap(x, y);
        par[y] += par[x];
        par[x] = y;
        return c--;
    }
};

struct edge {
    int a, b;
    ll c;
};

int n, m;
ll x;
vector<edge> es;

int main() {
    cin >> n >> m >> x;
    rep(i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        es.push_back(edge{a, b, c});
    }
    sort(ALL(es), [](edge &a, edge &b) { return a.c < b.c; });

    UnionFind uf(n);
    for(auto &&e : es)
        if(uf.unite(e.a, e.b)) x -= e.c;

    if(x < 0) {
        cout << 0 << endl;
        return 0;
    }

    vector<int> l(m, 0), r(m, es.back().c + 1);
    vector<pair<int, int>> mid(m);

    rep(_, 40) {
        rep(i, m) mid[i] = make_pair((l[i] + r[i]) >> 1, i);
        sort(ALL(mid));
        int i = 0;
        uf.init(n);
        for(auto &&p : mid) {
            while(es[i].c <= p.first) {
                uf.unite(es[i].a, es[i].b);
                i++;
            }
            int j = p.second;
            (uf.same(es[j].a, es[j].b) ? r[j] : l[j]) = p.first;
        }
    }

    if(x == 0) {
        int eq = -(n - 1), up = 0;
        rep(i, m) {
            if(r[i] == es[i].c) eq++;
            if(r[i] < es[i].c) up++;
        }
        mint ans;
        ans += (mint(2).pow(n - 1) - 2) * mint(2).pow(m - n + 1);
        ans += (mint(2).pow(eq) - 1) * 2 * mint(2).pow(up);
        cout << ans << endl;
    } else {
        int eq = 0, up = 0;
        rep(i, m) {
            if(es[i].c - r[i] == x) eq++;
            if(es[i].c - r[i] > x) up++;
        }
        cout << (mint(2).pow(eq) - 1) * 2 * mint(2).pow(up) << endl;
    }
}

Measured memory_bytes: 384