#include <algorithm>
#include <cstdio>
#include <cstring>

const int MaxN = 1000, MaxM = 2000;
const int Mod = 1000000007;

inline int add(int x, int y) { return (x += y) >= Mod ? x - Mod : x; }
inline int sub(int x, int y) { return (x -= y) < 0 ? x + Mod : x; }
inline int mul(int x, int y) { return 1LL * x * y % Mod; }
inline int pw(int x, int y) { int z = 1; for (; y; y >>= 1, x = mul(x, x)) if (y & 1) z = mul(z, x); return z; }
inline int inv(int x) { return pw(x, Mod - 2); }
inline int sep(int x, int y) { return mul(x, inv(y)); }
inline void inc(int &x, int y = 1) { (x += y) >= Mod ? x -= Mod : 0; }
inline void dec(int &x, int y = 1) { (x -= y) < 0 ? x += Mod : 0; }

template <typename Int>
inline void tense(Int &x, Int y) { if (y > x) x = y; }
template <typename Int>
inline void relax(Int &x, Int y) { if (y < x) x = y; }

struct edge_t {
  int u, v, w;
  edge_t(int _u = 0, int _v = 0, int _w = 0) { u = _u, v = _v, w = _w; }
  inline friend bool operator<(const edge_t &a, const edge_t &b) { return a.w < b.w; }
};

template <size_t Node_Size, size_t Edge_Size>
struct graph_t {
  int cnte;
  int head[Node_Size], to[Edge_Size], next[Edge_Size], weight[Edge_Size];
  graph_t() { cnte = 0; }

  inline void addEdge(int u, int v, int w) {
    cnte++; to[cnte] = v; weight[cnte] = w;
    next[cnte] = head[u]; head[u] = cnte;
  }
};

template <size_t Node_Size>
class dsu {
private:
  int par[Node_Size];
  int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }

public:
  inline void init() { memset(par, -1, sizeof par); }
  inline bool same(int x, int y) { return find(x) == find(y); }

  inline void merge(int x, int y) {
    int p = find(x), q = find(y);
    if (p == q) return;
    par[p] += par[q];
    par[q] = p;
  }
};

template <size_t Node_Size>
class tree {
private:
  int rt;
  int fa[Node_Size], dep[Node_Size], val[Node_Size];
  long long dis[Node_Size];
  graph_t<Node_Size, Node_Size * 2> gr;

  void dfs(int u) {
    for (int i = gr.head[u]; i; i = gr.next[i]) {
      int v = gr.to[i], w = gr.weight[i];
      if (v == fa[u]) continue;
      fa[v] = u;
      dep[v] = dep[u] + 1;
      dis[v] = dis[u] + w;
      val[v] = w;
      dfs(v);
    }
  }

public:
  inline void addEdge(int u, int v, int w) {
    gr.addEdge(u, v, w);
    gr.addEdge(v, u, w);
  }

  void build(int _rt = 1) {
    rt = _rt;
    dfs(rt);
  }

  inline int getLca(int u, int v) {
    while (dep[u] != dep[v]) {
      if (dep[u] < dep[v]) v = fa[v];
      else u = fa[u];
    }
    while (u != v) {
      u = fa[u];
      v = fa[v];
    }
    return u;
  }

  inline long long getDist(int u, int v) {
    int lca = getLca(u, v);
    return dis[u] + dis[v] - 2 * dis[lca];
  }

  inline int getMax(int u, int v) {
    int res = 0;
    while (dep[u] != dep[v]) {
      if (dep[u] < dep[v]) std::swap(u, v);
      tense(res, val[u]);
      u = fa[u];
    }
    while (u != v) {
      tense(res, val[u]);
      tense(res, val[v]);
      u = fa[u], v = fa[v];
    }
    return res;
  }
};

int N, M;
long long X, S;
edge_t E[MaxM + 5];
tree<MaxN + 5> Tr;

void init() {
  scanf("%d %d", &N, &M);
  scanf("%lld", &X);
  for (int i = 1; i <= M; ++i)
    scanf("%d %d %d", &E[i].u, &E[i].v, &E[i].w);
}

bool kruskal() {
  static dsu<MaxN + 5> d;
  d.init();
  std::sort(E + 1, E + 1 + M);
  int edge_cnt = 0;
  for (int i = 1; i <= M; ++i) {
    int u = E[i].u, v = E[i].v, w = E[i].w;
    if (d.same(u, v) == false) {
      S += w;
      edge_cnt++;
      d.merge(u, v);
      Tr.addEdge(u, v, w);
    }
  }
  return edge_cnt == N - 1;
}

inline int specialCase() {
  int cnt = 0;
  for (int i = 1; i <= M; ++i) {
    int u = E[i].u, v = E[i].v, w = E[i].w;
    int z = Tr.getMax(u, v);
    if (w == z) cnt++;
  }
  return mul(sub(pw(2, cnt), 2), pw(2, M - cnt));
}

inline int calc(long long x) {
  int cnt = 0;
  for (int i = 1; i <= M; ++i) {
    int u = E[i].u, v = E[i].v, w = E[i].w;
    int z = Tr.getMax(u, v);
    if (S - z + w >= x) cnt++;
  }
  return pw(2, cnt + 1);
}

void solve() {
  if (kruskal() == false) {
    puts("0");
    return;
  }
  Tr.build();
  if (S == X) printf("%d\n", specialCase());
  else printf("%d\n", sub(calc(X), calc(X + 1)));
}

int main() {
  init();
  solve();
  return 0;
}

Measured memory_bytes: 1764