#include <bits/stdc++.h>   using namespace std;   template <class T>   istream& operator>>(istream& is, vector<T>& v) {     for (T& x : v) is >> x;     return is;   }   ostream& operator<<(ostream& os, const pair<int, int>& unit) {     return os <<  y =   << unit.first <<  x +   << unit.second;   }   template <class T>   ostream& operator<<(ostream& os, const vector<T>& v) {     if (!v.empty()) {       os << v.front();       for (int i = 1; i < v.size(); ++i) os <<     << v[i];     }     return os;   }   const int P = 1000000007;   int norm(int x) { return x >= P ? x - P : x; }   void add(int& x, int y) {     if ((x += y) >= P) x -= P;   }   pair<long long, long long> operator+(const pair<long long, long long>& lhs,                                        const pair<long long, long long>& rhs) {     return pair<long long, long long>(lhs.first + rhs.first,                                       lhs.second + rhs.second);   }   pair<long long, long long> operator-(const pair<long long, long long>& lhs) {     return pair<long long, long long>(-lhs.first, -lhs.second);   }   pair<long long, long long> operator-(const pair<long long, long long>& lhs,                                        const pair<long long, long long>& rhs) {     return lhs + (-rhs);   }   long long operator^(const pair<long long, long long>& lhs,                       const pair<long long, long long>& rhs) {     return lhs.first * rhs.first + lhs.second * rhs.second;   }   long long operator*(const pair<long long, long long>& lhs,                       const pair<long long, long long>& rhs) {     return lhs.first * rhs.second - lhs.second * rhs.first;   }   long long dfrac(long long x, long long y) {     if (x < 0) return (x - y + 1) / y;     return x / y;   }   int main() {     ios::sync_with_stdio(false);     cin.tie(nullptr);     int n, m, q;     cin >> n >> m >> q;     vector<int> u(m), v(m), w(m);     for (int i = 0; i < m; ++i) {       cin >> u[i] >> v[i] >> w[i];       --u[i];       --v[i];     }     vector<int> dp(n, numeric_limits<int>::min());     dp[0] = 0;     int ans = 0;     for (int i = 0; i < n; ++i) {       add(ans, *max_element(dp.begin(), dp.end()) % P);       vector<int> ndp(n, numeric_limits<int>::min());       for (int j = 0; j < m; ++j) {         ndp[u[j]] = max(ndp[u[j]], dp[v[j]] + w[j]);         ndp[v[j]] = max(ndp[v[j]], dp[u[j]] + w[j]);       }       swap(dp, ndp);     }     vector<pair<long long, long long> > pts;     for (int i = 0; i < m; ++i) {       int val = max(dp[u[i]], dp[v[i]]);       pts.emplace_back(w[i], val - w[i] * n);     }     sort(pts.begin(), pts.end());     vector<pair<long long, long long> > stk;     for (const auto& pt : pts) {       if (!stk.empty() && stk.back().first == pt.first) stk.pop_back();       while (stk.size() > 1 && ((stk[stk.size() - 1] - stk[stk.size() - 2]) *                                 (pt - stk[stk.size() - 1])) >= 0) {         stk.pop_back();       }       stk.push_back(pt);     }     auto contrib = [&](long long l, long long r,                        const pair<long long, long long>& lne) {       l = max(l, (long long)n);       r = min(r, (long long)q);       if (l <= r)         ans = (ans + (r - l + 1) * lne.second % P +                (l + r) * (r - l + 1LL) / 2 % P * lne.first) %               P;       if (ans < 0) ans += P;     };     long long cur = numeric_limits<long long>::min();     for (int i = 0; i + 1 < stk.size(); ++i) {       long long nxt = dfrac(stk[i].second - stk[i + 1].second,                             stk[i + 1].first - stk[i].first);       contrib(cur + 1, nxt, stk[i]);       cur = nxt;     }     contrib(cur + 1, numeric_limits<long long>::max(), stk.back());     cout << ans <<   n ;     return 0;   }