#include <bits/stdc++.h>
using namespace std;
template <typename Tp>
inline void outarr(Tp _begin, Tp _end, const char* _delim = " ") {
  for (Tp current = _begin; current != _end; ++current) {
    std::cout << *current << _delim;
  }
  std::cout << '\n';
}
using ll = long long;
using pii = std::pair<int, int>;
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = static_cast<const int>(1e9 + 7);
constexpr ll LLINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int MAXN = 2005;
struct Edge {
  int From;
  int To;
  int W;
  Edge(int a, int b, int w) : From(a), To(b), W(w) {}
};
struct Line {
  pair<int, ll> Y;
  ll X;
  Line(pair<int, ll> y, ll x) : Y(move(y)), X(x) {}
};
vector<Edge> edges;
ll val[MAXN][MAXN];
int maxe[MAXN];
int Add(int x, int y) {
  x += y;
  return x < MOD ? x : x - MOD;
}
int Mul(int x, int y) { return int(1LL * x * y % MOD); }
void FBS(int v, int maxd) {
  memset(val, -1, sizeof(val));
  val[0][v] = 0;
  for (int i = 1; i <= maxd; ++i) {
    for (auto [from, to, w] : edges) {
      if (val[i - 1][from] != -1) {
        val[i][to] = max(val[i][to], val[i - 1][from] + w);
      }
    }
  }
}
ll Intersect(const pair<int, ll>& lhs, const pair<int, ll>& rhs) {
  if (lhs.first == rhs.first) {
    return -LLINF;
  }
  return (((rhs.second - lhs.second) - 1LL + (lhs.first - rhs.first)) /
          (lhs.first - rhs.first));
}
int Calc(int l, int r, const pair<int, ll>& y) {
  const ll n = r - l + 1;
  return Add(Mul(int((n * l + (n - 1) * n / 2) % MOD), y.first),
             int(y.second * n % MOD));
}
int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int n, m, q;
  cin >> n >> m >> q;
  for (int i = 0; i < (m); ++i) {
    int a, b, w;
    cin >> a >> b >> w;
    --a;
    --b;
    edges.emplace_back(a, b, w);
    edges.emplace_back(b, a, w);
    maxe[a] = max(maxe[a], w);
    maxe[b] = max(maxe[b], w);
  }
  FBS(0, m);
  int ans = 0;
  for (int i = 0; i < (m); ++i) {
    ans = Add(ans, int(*max_element(val[i + 1], val[i + 1] + n) % MOD));
  }
  vector<pair<int, ll>> lines(n);
  for (int i = 0; i < (n); ++i) {
    lines[i] = {maxe[i], val[m][i]};
  }
  sort((lines).begin(), (lines).end());
  vector<Line> stk;
  stk.emplace_back(make_pair(0, 0LL), -LLINF);
  for (int i = 0; i < (n); ++i) {
    while (Intersect(lines[i], stk.back().Y) <= stk.back().X) {
      stk.pop_back();
    }
    stk.emplace_back(lines[i], Intersect(lines[i], stk.back().Y));
  }
  stk.emplace_back(make_pair(0, 0LL), LLINF);
  int cur = 1;
  for (int i = 1; i < static_cast<int>((stk).size()); ++i) {
    if (stk[i - 1].X > q - m) {
      break;
    }
    if (stk[i].X <= cur) {
      continue;
    }
    ans = Add(ans, Calc(cur, min((int)stk[i].X - 1, q - m), stk[i - 1].Y));
    cur = (int)stk[i].X;
  }
  cout << ans << "\n";
  return 0;
}
