#include <bits/stdc++.h>
using namespace std;
template <typename T>
void uin(T &a, T b) {
  if (b < a) a = b;
}
template <typename T>
void uax(T &a, T b) {
  if (b > a) a = b;
}
const long long MOD = 1e9 + 7;
const long long INF = 1e13 + 228;
long long mod(long long x) {
  x %= MOD;
  if (x < 0) x += MOD;
  return x;
}
struct Edge {
  long long a, b, c;
  Edge() {}
  Edge(long long _a, long long _b, long long _c) {
    a = _a;
    b = _b;
    c = _c;
  }
};
struct Line {
  long long k, b;
  Line() {}
  Line(long long _k, long long _b) {
    k = _k;
    b = _b;
  }
  long long get(long long x) { return k * x + b; }
  long long sum(long long l, long long r) {
    long long summa = mod((r - l + 1) * b);
    long long add = mod(k * mod((r - l + 1) * (r + l) / 2));
    summa = mod(summa + add);
    return summa;
  }
};
bool operator<(Line fir, Line sec) { return fir.k < sec.k; }
long double intersect(Line fir, Line sec) {
  if (fir.k == sec.k) return -228;
  return (sec.b - fir.b) / (fir.k - sec.k);
}
vector<Line> st;
long long sz = 0;
void AddLine(Line l) {
  while (sz > 1 &&
         intersect(st[sz - 1], l) < intersect(st[sz - 2], st[sz - 1])) {
    st.pop_back();
    --sz;
  }
  st.emplace_back(l);
  ++sz;
}
long long Get(long long x) {
  long long mx = 0;
  for (auto l : st) {
    uax(mx, l.get(x));
  }
  return mx;
}
const long long N = 2013;
vector<pair<long long, long long> > g[N];
long long mx_out[N];
long long d[N], dd[N];
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  long long n, m, q;
  cin >> n >> m >> q;
  vector<Edge> edges;
  for (long long i = 0; i < m; ++i) {
    long long u, v, w;
    cin >> u >> v >> w;
    g[u].emplace_back(v, w);
    g[v].emplace_back(u, w);
    edges.emplace_back(u, v, w);
  }
  for (long long v = 1; v <= n; ++v) {
    for (pair<long long, long long> p : g[v]) {
      uax(mx_out[v], p.second);
    }
  }
  for (long long i = 1; i <= n; ++i) {
    d[i] = -INF;
  }
  d[1] = 0;
  long long ans = 0;
  vector<Line> lines;
  for (long long k = 0; k <= n; ++k) {
    long long mx = 0;
    for (long long i = 1; i <= n; ++i) {
      uax(mx, d[i]);
    }
    if (k <= q) {
      ans = mod(ans + mx);
    }
    {
      for (long long v = 1; v <= n; ++v) {
        if (d[v] >= 0) {
          lines.emplace_back(Line(mx_out[v], d[v] - k * mx_out[v]));
        }
      }
    }
    for (long long i = 1; i <= n; ++i) {
      dd[i] = d[i];
    }
    for (auto e : edges) {
      long long a = e.a, b = e.b, c = e.c;
      if (d[a] + c > dd[b]) {
        dd[b] = d[a] + c;
      }
      if (d[b] + c > dd[a]) {
        dd[a] = d[b] + c;
      }
    }
    for (long long i = 1; i <= n; ++i) {
      d[i] = dd[i];
    }
  }
  sort(lines.begin(), lines.end());
  {
    long long ss = (long long)lines.size();
    long long i = 0;
    while (i < ss) {
      long long j = i;
      long long K = lines[j].k;
      long long B = lines[j].b;
      while (j + 1 < ss && lines[j + 1].k == K) {
        ++j;
        uax(B, lines[j].b);
      }
      AddLine(Line(K, B));
      i = j + 1;
    }
  }
  vector<long long> pts;
  for (long long i = 0; i < (long long)st.size() - 1; ++i) {
    pts.emplace_back((long long)intersect(st[i], st[i + 1]));
  }
  long long last = n;
  for (long long i = 0; i < (long long)pts.size(); ++i) {
    long long x = pts[i];
    if (n + 1 <= x) {
      ans = mod(ans + st[i].sum(last + 1, min(x, q)));
      last = min(x, q);
    }
  }
  if (last < q) {
    ans = mod(ans + st.back().sum(last + 1, q));
  }
  cout << ans << '\n';
  return 0;
}
