#include <bits/stdc++.h>
using namespace std;
template<typename T>
class fixed_point : T {
  public:
    explicit constexpr fixed_point (
        T&& t
      ) noexcept
      : T(forward<T>(t))
      {
      }
    template<typename... Args>
    constexpr decltype(auto)
    operator()(
        Args&&... args
      ) const
      {
        return T::operator()(*this, forward<Args>(args)...);
      }
};
template<typename T>
static inline constexpr decltype(auto) fix (T&& t) noexcept {
  return fixed_point<T>{forward<T>(t)};
}
namespace mint {
  int md = 1e9 + 7;
  inline void add (int &a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    a += b; if (a >= md) a -= md;
  }
  inline void sub (int &a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    a -= b; if (a < 0) a += md;
  }
  inline int sum (int a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    add(a, b); return a;
  }
  inline int dif (int a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    sub(a, b); return a;
  }
  template<class... A>
  inline int prod (A... args) {
    long long ret = 1;
    for (int a :	initializer_list<int>{args...}) {
      assert(0 <= a && a < md);
      ret *= a;
      ret %= md;
    }
    return (int)(ret % md);
  }
  inline void mul (int &a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    a = prod(a, b);
  }
  inline int inv (int a) {
    assert(0 <= a && a < md);
    a %= md;
    if(a < 0) a += md;
    int b = md, u = 0, v = 1;
    while (a) {
      int t = b / a;
      b -= a * t; swap(a, b);
      u -= v * t; swap(u, v);
    }
    assert(b == 1);
    if(u < 0) u += md;
    return u;
  }
  inline int quot (int a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    return prod(a, inv(b));
  }
  inline void div (int& a, int b) {
    assert(0 <= a && a < md && 0 <= b && b < md);
    a = quot(a, b);
  }
  inline int pow (int a, long long b) {
    assert(0 <= a && a < md);
    int res = 1;
    for (; b; b >>= 1) {
      if (b & 1) mul(res, a);
      mul(a, a);
    }
    return res;
  }
  namespace factorials {
    int sz;
    vector<int> fact, finv;
    void init (int n) {
      sz = n;
      fact.resize(n); finv.resize(n);
      fact[0] = 1;
      for (int i = 1; i < n; i++) fact[i] = prod(fact[i - 1], i);
      finv[n - 1] = inv(fact[n - 1]);
      for (int i = n - 2; i >= 0; i--) finv[i] = prod(finv[i + 1], i + 1);
    }
  }
  inline int fct (int i) {
    using namespace factorials;
    assert(0 <= i && i < sz);
    return fact[i];
  }
  inline int fnv (int i) {
    using namespace factorials;
    assert(0 <= i && i < sz);
    return finv[i];
  }
  inline int binom (int n, int k) {
    using namespace factorials;
    assert(0 <= n && n < sz);
    if (0 < k || n < k) return 0;
    return prod(fact[n], finv[k], finv[n - k]);
  }
}
class disjoint_set {
  int n;
  vector<int> prt;
  public:
    disjoint_set (int n)
      : n(n), prt(n, -1)
      {
      }
      inline bool is_root (int x) const {
        return prt[x] < 0;
      }
      inline int size (int x) {
        return -prt[find(x)];
      }
      inline bool equiv (int x, int y) {
        return find(x) == find(y);
      }
      int find (int x) {
        return (is_root(x) ? x : (prt[x] = find(prt[x])));
      }
      inline bool unite (int x, int y) {
        x = find(x); y = find(y);
        if (x == y) return false;
        if (size(x) < size(y)) swap(x, y);
        prt[x] += prt[y];
        prt[y] = x;
        return true;
      }
};
int main() {
  cin.tie(0); cin.sync_with_stdio(false);
  int n, m; long long X;
  cin >> n >> m >> X;
  vector<tuple<long long, int, int>> edg;
  for (int i = 0; i < m; i++) {
    int u, v; long long w;
    cin >> u >> v >> w;
    u--; v--;
    edg.emplace_back(w, u, v);
  }
  sort(edg.begin(), edg.end());
  long long W = 0;
  vector<vector<pair<int, long long>>> grh(n);
  disjoint_set djs(n);
  for (auto& e : edg) {
    int u, v; long long w; tie(w, u, v) = e;
    if (djs.unite(u, v)) {
      W += w;
      grh[u].emplace_back(v, w);
      grh[v].emplace_back(u, w);
    }
  }
  if (X < W) {
    cout << 0 << endl;
    return 0;
  }
  int a = 0, b = 0, c = 0;
  for (auto& e : edg) {
    int u, v; long long w; tie(w, u, v) = e;
    auto d = w - fix ([&]
      (
        auto dfs, int crr, int prt, long long ret
      )
      -> long long
      {
        if (crr == v) return ret;
        for (auto const& e : grh[crr]) {
          int nxt; long long w; tie(nxt, w) = e;
          if (nxt == prt) continue;
          auto d = dfs(nxt, crr, max(ret, w));
          if (d != -1) return d;
        }
        return -1;
      })(u, u, 0);
    assert(d >= 0);
    if (d < X - W) a++;
    else if (d == X - W) b++;
    else c++;
  }
  assert(a + b + c == m);
  int ret = -1;
  if (X == W) {
    assert(a == 0);
    ret = mint::prod(
      mint::dif(mint::pow(2, b), 2),
      mint::pow(2, c)
    );
  } else {
    ret = mint::prod(
      2,
      mint::dif(mint::pow(2, b), 1),
      mint::pow(2, c)
    );
  }
  cout << ret << endl;
  return 0;
}

Measured memory_bytes: 384