import std.stdio, std.array, std.string, std.conv, std.algorithm; import std.typecons, std.range, std.random, std.math, std.container; import std.numeric, std.bigint, core.bitop, std.bitmanip; alias Plane = Tuple!(int, "u", int, "v", int, "p", int, "q", int, "w"); immutable long INF = 1L << 59; void main() { auto s = readln.split.map!(to!int); auto N = s[0]; auto M = s[1]; auto D = s[2]; auto P = new Plane[](M); foreach (i; 0..M) { s = readln.split.map!(to!int); P[i] = Plane(s[0], s[1], s[2], s[3], s[4]); } int source = M; int sink = M + 1; auto dinic = new Dinic(M + 2); foreach (i; 0..M) { if (P[i].u == 1) { dinic.add_edge(source, i, P[i].w); } if (P[i].v == N) { dinic.add_edge(i, sink, P[i].w); } } foreach (i; 0..M) { foreach (j; 0..M) { if (i == j) continue; if (P[i].v == P[j].u && P[j].p - P[i].q >= D) { dinic.add_edge(i, j, min(P[i].w, P[j].w)); } } } dinic.run(source, sink).writeln; } class Dinic { alias Edge = Tuple!(int, "to", long, "cap", long, "rev"); int V; Edge[][] G; int[] itr, level; this(int V) { this.V = V; G = new Edge[][](V); } void add_edge(int from, int to, long cap) { G[from] ~= Edge(to, cap, G[to].length.to!long); G[to] ~= Edge(from, 0, G[from].length.to!long-1); } void bfs(int s) { level = new int[](V); level.fill(-1); DList!int q; level[s] = 0; q.insertBack(s); while (!q.empty) { int v = q.front(); q.removeFront(); foreach (e; G[v]){ if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[v] + 1; q.insertBack(e.to); } } } } long dfs(int v, int t, long f) { if (v == t) return f; for (int i = itr[v]; i < G[v].length.to!int; ++i) { //auto e = G[v][i]; if (G[v][i].cap > 0 && level[v] < level[G[v][i].to]) { long d = dfs(G[v][i].to, t, min(f, G[v][i].cap)); if (d > 0) { G[v][i].cap -= d; G[G[v][i].to][G[v][i].rev].cap += d; return d; } } } return 0; } long run(int s, int t) { long ret = 0, f; while (true) { bfs(s); if (level[t] < 0) break; itr = new int[](V); while ((f = dfs(s, t, INF)) > 0) ret += f; } return ret; } }