#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef pair P; #define rep(i, n) for (int i=0; i<(n); i++) #define all(c) (c).begin(), (c).end() #define uniq(c) c.erase(unique(all(c)), (c).end()) #define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin()) #define _1 first #define _2 second #define pb push_back #define INF 1145141919 #define MOD 1000000007 #define MAX_V 2010 struct Dinic { struct Edge { int to, cap, rev; }; vector G[MAX_V]; int level[MAX_V], iter[MAX_V]; void add_edge(int from, int to, int cap) { G[from].pb((Edge) { to, cap, (int)G[to].size() }); G[to].pb((Edge) { from, 0, (int)G[from].size()-1 }); } void bfs(int s) { rep(i, MAX_V) level[i] = INF; queue q; level[s] = 0; q.push(s); while (!q.empty()) { int x = q.front(); q.pop(); for (Edge e : G[x]) if (e.cap > 0 && level[e.to] == INF) { level[e.to] = level[x]+1; q.push(e.to); } } } int dfs(int x, int goal, int f) { if (x == goal) return f; for (int &i=iter[x]; i 0 && level[x] < level[e.to]) { int w = dfs(e.to, goal, min(f, e.cap)); if (w > 0) { e.cap -= w; G[e.to][e.rev].cap += w; return w; } } } return 0; } int max_flow(int s, int t) { int flow = 0; while (true) { bfs(s); if (level[t] == INF) return flow; rep(i, MAX_V) iter[i] = 0; while (true) { int f = dfs(s, t, INF); if (f == 0) break; flow += f; } } } }; int N, M, D; int base[1000]; vector W[1000]; Dinic dinic; int V; signed main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N >> M >> D; vector > edges; rep(i, M) { int u, v, p, q, w; cin >> u >> v >> p >> q >> w; u--, v--; q += D; W[u].pb(p); W[v].pb(q); edges.pb(make_tuple(u, v, p, q, w)); } if (W[N-1].empty() || W[0].empty()) { cout << 0 << "\n"; return 0; } rep(x, N) { sort(all(W[x])), uniq(W[x]); base[x] = V; rep(i, (int)W[x].size()-1) { dinic.add_edge(base[x]+i, base[x]+i+1, INF); } V += W[x].size(); } int s = V++, t = V++; dinic.add_edge(s, base[0], INF); dinic.add_edge(base[N-1]+(int)W[N-1].size()-1, t, INF); for (auto pp : edges) { int u, v, p, q, w; tie(u, v, p, q, w) = pp; dinic.add_edge(base[u]+index(W[u], p), base[v]+index(W[v], q), w); } cout << dinic.max_flow(s, t) << "\n"; return 0; }