#include <bits/stdc++.h>
using namespace std;
const long long oo = 1e18 + 7, mod = 1e9 + 7;
const long long N = 2005;
long long n, m, q, mx_dist[N][N], tol;
vector<pair<long long, long long> > Adj[N];
struct line {
  long long a, b;
  line(long long _a, long long _b) : a(_a), b(_b) {}
};
long double inter(line x, line y) {
  return (long double)(x.b - y.b) / (long double)(y.a - x.a);
}
long long evaluate(line x, long long l, long long r) {
  if (l > r) return 0;
  long long tmp1 = ((r - l + 1) * x.b) % mod;
  long long tmp2 = (((((r - l + 1) * (r + l)) / 2) % mod) * x.a) % mod;
  return (tmp1 + tmp2) % mod;
}
struct convex_hull {
  deque<line> dq;
  void ins(line tmp) {
    while (dq.size() >= 1 && dq[dq.size() - 1].a == tmp.a &&
           dq[dq.size() - 1].b < tmp.b)
      dq.pop_back();
    if (!dq.size())
      dq.push_back(tmp);
    else if (dq[dq.size() - 1].a < tmp.a) {
      while (dq.size() >= 2 && inter(dq[dq.size() - 1], dq[dq.size() - 2]) >
                                   inter(tmp, dq[dq.size() - 1])) {
        dq.pop_back();
      }
      dq.push_back(tmp);
    }
  }
  long long process() {
    long long ans = 0, lst = 0;
    for (long long i = 0; i < dq.size(); i++) {
      long long l;
      if (i)
        l = max(n + 1, (long long)ceil(inter(dq[i - 1], dq[i])));
      else
        l = n + 1;
      long long r;
      if (i != dq.size() - 1)
        r = min(q, (long long)floor(inter(dq[i], dq[i + 1])));
      else
        r = q;
      l = max(l, lst + 1);
      ans += evaluate(dq[i], l, r);
      ans %= mod;
      lst = r;
    }
    return ans;
  }
} cv;
void input() {
  cin >> n >> m >> q;
  for (long long i = 1; i <= m; i++) {
    long long x, y, w;
    cin >> x >> y >> w;
    Adj[x].push_back({y, w});
    Adj[y].push_back({x, w});
  }
}
void process() {
  for (long long i = 0; i <= n; i++) {
    for (long long j = 1; j <= n; j++) mx_dist[i][j] = -oo;
  }
  mx_dist[0][1] = 0;
  for (long long i = 1; i <= n; i++) {
    long long mx = -1;
    for (long long j = 1; j <= n; j++) {
      for (long long k = 0; k < Adj[j].size(); k++)
        mx_dist[i][j] = max(mx_dist[i][j],
                            mx_dist[i - 1][Adj[j][k].first] + Adj[j][k].second);
      mx = max(mx, mx_dist[i][j]);
    }
    if (i <= q) tol += mx;
    tol %= mod;
  }
  vector<pair<long long, long long> > vc;
  for (long long i = 0; i <= n; i++) {
    for (long long j = 1; j <= n; j++) {
      long long mx_edge = 0;
      for (long long k = 0; k < Adj[j].size(); k++)
        mx_edge = max(mx_edge, Adj[j][k].second);
      vc.push_back({mx_edge, mx_dist[i][j] - mx_edge * i});
    }
  }
  sort(vc.begin(), vc.end());
  for (auto it : vc) {
    if (it.second < -2000000000) continue;
    line tmp(it.first, it.second);
    cv.ins(tmp);
  }
}
void output() { cout << (cv.process() + tol) % mod; }
signed main() {
  ios_base::sync_with_stdio(0);
  input();
  process();
  output();
}
