#include #include #include #include #include #include #include using namespace std; struct Graph { static constexpr int64_t INF = (int64_t)1 << 60; struct Edge { int i, r; int64_t f; }; Graph(int n) : v(n), h(n), q(n), e(n) {} void add_edge(int i, int j, int64_t f) { int r0 = e[j].size(); int r1 = e[i].size(); e[i].push_back({ j, r0, max(+f, (int64_t)0) }); e[j].push_back({ i, r1, max(-f, (int64_t)0) }); } void bfs(int i0, int i1) { fill(v.begin(), v.end(), -1); v[i0] = 0; int j0 = 0, j1 = 0; q[j1++] = i0; while (j0 < j1) { int i = q[j0++]; for (Edge& o : e[i]) { if (v[o.i] >= 0 || o.f == 0) continue; v[o.i] = v[i] + 1; if (o.i == i1) return; q[j1++] = o.i; } } } int64_t dfs(int i, int i1, int64_t f0) { for (; h[i] < e[i].size(); h[i]++) { Edge& o = e[i][h[i]]; if (v[o.i] <= v[i] || o.f == 0) continue; int64_t f = min(f0, o.f); if (o.i != i1) f = dfs(o.i, i1, f); if (f == 0) continue; o.f -= f; e[o.i][o.r].f += f; return f; } return 0; } int64_t max_flow(int i0, int i1) { // i0 != i1 for (int64_t f = 0;;) { bfs(i0, i1); if (v[i1] < 0) return f; fill(h.begin(), h.end(), 0); while (1) { int64_t t = dfs(i0, i1, INF); if (t == 0) break; f += t; } } } vector v, h, q; vector> e; }; void coco(vector& v) { size_t n = v.size(); vector> t(n); for (int i = 0; i < n; i++) { t[i] = { v[i], i }; } sort(t.begin(), t.end()); int k = 0; for (int i = 0; i < n; i++) { if (i > 0 && t[i].first != t[i - 1].first) k++; v[t[i].second] = k; } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m, d; cin >> n >> m >> d; vector u(m), v(m), w(m); vector> p(n); for (int i = 0; i < m; i++) { int p0, p1; cin >> u[i] >> v[i] >> p0 >> p1 >> w[i]; u[i]--; v[i]--; p1 += d; p[u[i]].push_back(p0); p[v[i]].push_back(p1); } vector k(n + 1); for (int i = 0; i < n; i++) { if (p[i].empty()) continue; coco(p[i]); k[i + 1] = 1 + *max_element(p[i].begin(), p[i].end()); } for (int i = 0; i < n; i++) { k[i + 1] += k[i]; } Graph g(k[n]); for (int i = 0; i < n; i++) { for (int j = k[i]; j < k[i + 1] - 1; j++) { g.add_edge(j, j + 1, Graph::INF); } } vector l(n); for (int i = 0; i < m; i++) { g.add_edge(k[u[i]] + p[u[i]][l[u[i]]++], k[v[i]] + p[v[i]][l[v[i]]++], w[i]); } if (k[1] - k[0] == 0 || k[n] - k[n - 1] == 0) { cout << 0 << endl; quick_exit(0); } cout << g.max_flow(0, k[n] - 1) << endl; return 0; }