#define _USE_MATH_DEFINES #include "bits/stdc++.h" using namespace std; #define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i)) #define rep(i,j) FOR(i,0,j) #define each(x,y) for(auto &(x):(y)) #define mp make_pair #define MT make_tuple #define all(x) (x).begin(),(x).end() #define debug(x) cout<<#x<<": "<<(x)< >(b,vector(c,d)) #define vvv(a,b,c,d,e) vector > >(b,vv(a,c,d,e)) using ll = long long; using pii = pair; using vi = vector; using vll = vector; /* ディニック法による最大フロー O(|V|^2|E|) だけど、たいていはかなり高速 */ template struct Dinic { struct E { int to, rev; Capacity cap; }; vector> G; vector used; vector level, iter; static const Capacity INFW = numeric_limits::max(); Dinic() {} Dinic(int n) : G(n), used(n) { } void addEdge(int from, int to, Capacity cap) { G[from].push_back(E{ to, (int)G[to].size(), cap }); G[to].push_back(E{ from, (int)G[from].size() - 1 , 0}); } void bfs(int src, int sink) { vector que(G.size()); int ql = 0, qr = 0; que[qr++] = src; level.assign(G.size(), -1); level[src] = 0; while (ql < qr && level[sink] == -1) { int u = que[ql++]; for (auto &e : G[u]) { if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[u] + 1; que[qr++] = e.to; } } } } Capacity dfs(int v, int t, Capacity f) { if (v == t) return f; for (int &i = iter[v]; i < G[v].size(); i++) { E &e = G[v][i]; if (e.cap > 0 && level[v] < level[e.to]) { Capacity d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } Capacity calcMaxFlow(int s, int t) { Capacity flow = 0; while (1) { bfs(s, t); if (level[t] < 0)return flow; Capacity f; iter.assign(G.size(), 0); while ((f = dfs(s, t, INFW)) > 0) { flow += f; } } return flow; } }; int N, M, D, U[1001], V[1001], P[1001], Q[1001], W[1001], limit; vi times[1001], vertices[1001]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(20); cin >> N >> M >> D; limit = (int)1e9 + D; rep(i, M) { cin >> U[i] >> V[i] >> P[i] >> Q[i] >> W[i]; --U[i]; --V[i]; times[U[i]].push_back(P[i]); times[V[i]].push_back(Q[i] + D); } times[0].push_back(0); times[N - 1].push_back(limit); rep(i, N) { sort(all(times[i])); times[i].erase(unique(all(times[i])), times[i].end()); } int K = 0; rep(i, N)rep(j, sz(times[i]))vertices[i].push_back(K++); Dinic dinic(K); rep(i, N) { rep(j, sz(vertices[i]) - 1) { dinic.addEdge(vertices[i][j], vertices[i][j + 1], dinic.INFW); } } auto f = [&](int x, int y) { return vertices[x][lower_bound(all(times[x]), y) - times[x].begin()]; }; rep(i, M) { int u = f(U[i], P[i]); int v = f(V[i], Q[i] + D); dinic.addEdge(u, v, W[i]); } cout << dinic.calcMaxFlow(0, K - 1) << endl; }