#include <cstdio>
#include <cstring>
#include <iostream>
#include <bitset>
#include <algorithm>

using namespace std;

typedef long long LL;

const int maxN = 1e5 + 5;
const int maxM = 2e5 + 5;
const int mod = 1e9 + 7;

int n, m, T, ecnt;
int head[maxN], dep[maxN];
int to[maxM], nxt[maxM], wht[maxM];
int f[20][maxN], MAX[20][maxN];
LL X, mstsum;
bitset<maxM> ismst, vis;

struct Edge
{
    int u, v, w;

    Edge() { }

    Edge(int _u, int _v, int _w) : u(_u), v(_v), w(_w) { }
} edge[maxM];

bool operator<(const Edge& a, const Edge& b)
{ return a.w < b.w; }

template <typename _Tp>
inline bool Chkmax(_Tp& x, const _Tp& y)
{ return x < y ? x = y, true : false; }

namespace U
{
    int fa[maxN], size[maxN];

    int Find(int x)
    { return fa[x] == x ? x : fa[x] = Find(fa[x]); }

    inline bool Merge(int u, int v)
    {
        int fu = Find(u), fv = Find(v);
        if (fu == fv)
            return false;
        if (size[fu] > size[fv])
            swap(fu, fv);
        fa[fu] = fv, size[fv] += size[fu];
        return true;
    }

    void Init()
    {
        for (int i = 1; i <= n; ++i)
            fa[i] = i, size[i] = 1;
    }
}

int FPM(int bas, int ind)
{
    int res = 1;
    while (ind)
    {
        if (ind & 1)
            res = (LL)res * bas % mod;
        bas = (LL)bas * bas % mod;
        ind >>= 1;
    }
    return res;
}

void DFS(int u)
{
    for (int i = 1; 1 << i <= dep[u]; ++i)
        f[i][u] = f[i - 1][f[i - 1][u]],
        Chkmax(MAX[i][u] = MAX[i - 1][u], MAX[i - 1][f[i - 1][u]]);
    for (int i = head[u]; i; i = nxt[i])
    {
        int v = to[i];
        if (v == f[0][u])
            continue;
        f[0][v] = u, MAX[0][v] = wht[i];
        dep[v] = dep[u] + 1;
        DFS(v);
    }
}

int Query(int u, int v)
{
    int res = 0;
    if (dep[u] < dep[v])
        swap(u, v);
    for (int i = 19; ~i; --i)
        if (dep[f[i][u]] >= dep[v])
            Chkmax(res, MAX[i][u]), u = f[i][u];
    if (u == v)
        return res;
    for (int i = 19; ~i; --i)
        if (f[i][u] != f[i][v])
        {
            Chkmax(res, MAX[i][u]);
            u = f[i][u];
            Chkmax(res, MAX[i][v]);
            v = f[i][v];
        }
    return max(res, max(MAX[0][u], MAX[0][v]));
}

inline void Link(int u, int v, int w)
{
    ++ecnt;
    to[ecnt] = v, wht[ecnt] = w, nxt[ecnt] = head[u];
    head[u] = ecnt;
    ++ecnt;
    to[ecnt] = u, wht[ecnt] = w, nxt[ecnt] = head[v];
    head[v] = ecnt;
}

inline void Init()
{
    memset(head + 1, 0, n * sizeof(int));
    ecnt = 0, mstsum = 0;
    memset(f, 0, sizeof(f));
    memset(MAX, 0, sizeof(MAX));
    ismst.reset();
}

int Getans(LL lim)
{
    if (mstsum >= lim)
        return FPM(2, m) - 1;
    vis.reset();
    for (int i = 1; i <= m; ++i) if (!ismst[i])
    {
        int u = edge[i].u, v = edge[i].v;
        if (mstsum + edge[i].w - Query(u, v) < lim)
            vis.set(i);
    }
    return FPM(2, m - vis.count() - n + 2) - 1;
}

int main()
{
    ios::sync_with_stdio(false);
        cin >> n >> m >> X;
        for (int i = 1; i <= m; ++i)
        {
            Edge& o = edge[i];
            cin >> o.u >> o.v >> o.w;
        }
        sort(edge + 1, edge + m + 1);
        U::Init(), Init();
        for (int i = 1; i <= m; ++i)
        {
            Edge& o = edge[i];
            if (U::Merge(o.u, o.v))
            {
                ismst.set(i);
                Link(o.u, o.v, o.w);
                mstsum += o.w;
            }
        }
        dep[1] = 1, DFS(1);
        cout << ((Getans(X) - Getans(X + 1)) % mod + mod) % mod << endl;
    return 0;
}

Measured memory_bytes: 18816