#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define rep2(i, s, n) for (int i = (int)(s); i < (int)(n); i++) #define repb(i, e) for (int i = (int)(e); i >= 0; i--) #define all(x) x.begin(), x.end() using namespace std; using ll = long long; using ull = unsigned long long; using vi = vector; using vll = vector; using vd = vector; using vvi = vector; using vvll = vector; using vvd = vector; using vs = vector; using vb = vector; using vvb = vector; using vc = vector; using vvc = vector; using pii = pair; using pll = pair; using pil = pair; using pli = pair; using vpii = vector; using vpll = vector; using vpil = vector; using vpli = vector; const double PI = acos(-1); const ll MOD = 1000000007; const ll MODL = 2147483647; const int INF = 1000000007; const ll INFL = 1LL<<60; template inline bool chmin(T &a, T b) {if (a > b) {a = b; return true;} return false;} template inline bool chmax(T &a, T b) {if (a < b) {a = b; return true;} return false;} // template T gcd(T a, T b) {if (a < b) swap(a, b); if (b == 0) return a; else return gcd(b, a%b);} template inline T ceil(T a, T b) {return (a+(b-1))/b;} template inline T floor(T a, T b) {return a/b;} template inline void add(T &a, T b, T m) {a = ((a % m + b % m)) % m;} template inline void sub(T &a, T b, T m) {a = ((a % m - b % m) + m) % m;} template inline void mul(T &a, T b, T m) {a = (((a % m + m) % m) * ((b % m) + m) % m) % m;} struct Edge { int to, rev; ll cap; }; class MaximumFlow { public: int size = 0; vb used; vector> G; MaximumFlow(int n) { init(n); } void init(int n) { size = n; used = vb(n); G = vector>(n); rep(i, n) G[i].clear(); } void add_edge(int a, int b, ll c) { int Current_Ga = G[a].size(); int Current_Gb = G[b].size(); G[a].push_back(Edge{b, Current_Gb, c}); G[b].push_back(Edge{a, Current_Ga, 0}); } ll dfs(int pos, int goal, ll F) { if (pos == goal) return F; used[pos] = true; rep(i, G[pos].size()) { if (G[pos][i].cap == 0) continue; if (used[G[pos][i].to]) continue; ll flow = dfs(G[pos][i].to, goal, min(F, G[pos][i].cap)); if (flow >= 1) { G[pos][i].cap -= flow; G[G[pos][i].to][G[pos][i].rev].cap += flow; return flow; } } return 0; } ll max_flow(int s, int t) { ll Total_Flow = 0; while (true) { rep(i, size) used[i] = false; ll F = dfs(s, t, 1e9); if (F == 0) break; Total_Flow += F; } return Total_Flow; } }; int main() { int n, m, u, v, id1, id2; ll d, p, q, w; cin >> n >> m >> d; vvi time(n); vector> edge; rep(i, m) { cin >> u >> v >> p >> q >> w; u--; v--; time[u].push_back(p); time[v].push_back(q+d); edge.emplace_back(u, v, p, q+d, w); } vi now_id(n+1, 0); rep(i, n+1) { if (i != n) sort(all(time[i])); if (i != 0) now_id[i] = now_id[i-1] + time[i-1].size(); } MaximumFlow MF(now_id[n]); rep(i, m) { auto [now, next, now_t, next_t, weight] = edge[i]; id1 = lower_bound(all(time[now]), now_t) - time[now].begin(); id2 = lower_bound(all(time[next]), next_t) - time[next].begin(); MF.add_edge(now_id[now]+id1, now_id[next]+id2, weight); } rep(i, n) { rep(j, time[i].size()) { if (j + 1 != (int)(time[i].size())) MF.add_edge(now_id[i]+j, now_id[i]+j+1, INFL); } } cout << MF.max_flow(0, now_id[n]-1) << endl; }