#include #include using ll = long long; using ull = unsigned long long; #define rep(i, n) for(int i = 0; i < (int)(n); i++) #define REP(i, m, n) for(int i = (int)(m); i < (int)(n); i++) using namespace std; using namespace atcoder; using mint = modint998244353; const int inf = 1000000007; const ll longinf = 1ll << 60; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin >> n >> m; ll c; cin >> c; vector l(m), r(m), w(m), p(m); rep(i, m) { cin >> l[i] >> r[i] >> w[i] >> p[i]; --l[i]; --r[i]; } vector ord(m); rep(i, m) ord[i] = i; sort(ord.begin(), ord.end(), [&](int x, int y) { return w[x] < w[y]; }); dsu uf(n); vector>> g(n); vector used(m); ll cost = 0; for(auto i : ord) { if(uf.same(l[i], r[i])) { continue; } used[i] = 1; uf.merge(l[i], r[i]); g[l[i]].push_back({r[i], w[i]}); g[r[i]].push_back({l[i], w[i]}); cost += w[i]; } if(cost > c) { cout << -1 << endl; return 0; } vector parent(n), rank(n); auto dfs = [&](auto &&self, int x, int p) -> void { parent[x] = p; for(auto to : g[x]) { if(to.first == p) continue; rank[to.first] = rank[x] + 1; self(self, to.first, x); } }; dfs(dfs, 0, -1); vector nxt(n, vector>(20)); rep(i, n) { nxt[i][0] = {-1, -1}; for(auto to : g[i]) { if(to.first == parent[i]) { nxt[i][0] = to; } } } rep(b, 19) { rep(i, n) { if(nxt[i][b].first == -1) { nxt[i][b + 1] = nxt[i][b]; } else { auto nnxt = nxt[nxt[i][b].first][b]; nxt[i][b + 1] = {nnxt.first, max(nnxt.second, nxt[i][b].second)}; } } } auto query = [&](int l, int r) -> int { int ma = 0; if(rank[l] < rank[r]) swap(l, r); for(int b = 19; b >= 0; --b) { if(rank[l] - (1 << b) < rank[r]) continue; ma = max(ma, nxt[l][b].second); l = nxt[l][b].first; } if(l == r) { return ma; } for(int b = 19; b >= 0; --b) { if(nxt[l][b].first == nxt[r][b].first) continue; ma = max(ma, nxt[l][b].second); ma = max(ma, nxt[r][b].second); l = nxt[l][b].first; r = nxt[r][b].first; } return max({ma, nxt[l][0].second, nxt[r][0].second}); }; int ans = 0; rep(i, m) { if(used[i]) { ans = max(ans, p[i]); continue; } int ret = query(l[i], r[i]); if(cost - ret + w[i] <= c) { ans = max(ans, p[i]); } } cout << ans << endl; return 0; }