#ifndef _GLIBCXX_NO_ASSERT #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include #include #include #endif // C++ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif using namespace std; #define rep(i, n) for(ll i = 0; i < n; i++) #define revrep(i, n) for(ll i = n-1; i >= 0; i--) typedef long long ll; typedef pair Pint; typedef pair P; typedef vector vec; typedef vector mat; //typedef pair> P; //typedef tuple T; ll INFL = 100000000000;//10^18 = 2^60 int INF = 1000000000;//10^9 ll MOD = 1000000007; //vector dy = {0,0,1,-1}; //vector dx = {1,-1,0,0}; #define MAX_V 200010 struct edge {ll to, cap, rev;}; vector > G(MAX_V); bool used[MAX_V]; void add_edge(ll from, ll to, ll cap){ edge F; edge T; F.to = to; F.cap = cap; F.rev = G[to].size(); G[from].push_back(F); T.to = from; T.cap = 0; T.rev = G[from].size() - 1; G[to].push_back(T); } ll dfs(ll v, ll t, ll f){ if(v == t) return f; used[v] = true; for(ll i = 0; i < G[v].size(); i++){ edge &e = G[v][i]; if(!used[e.to] && e.cap > 0){ ll 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; } ll max_flow(ll s, ll t){ ll flow = 0; while(1){ memset(used, 0, sizeof(used)); ll f = dfs(s, t, INF); if(f == 0) return flow; flow += f; } } ll N, M, d; vector u(1010), v(1010), p(1010), q(1010), w(1010); ll compress(vector &p, vector &q){ vector xs; xs.push_back(0LL); xs.push_back(1000000000); rep(i, M){ xs.push_back(p[i]); xs.push_back(q[i]); } sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end()); rep(i, M){ p[i] = lower_bound(xs.begin(), xs.end(), p[i]) - xs.begin(); q[i] = lower_bound(xs.begin(), xs.end(), q[i]) - xs.begin(); } return xs.size(); } int main(void){ cin >> N >> M >> d; rep(i, M){ cin >> u[i] >> v[i] >> p[i] >> q[i] >> w[i]; u[i]--, v[i]--; q[i] += d; } ll T = compress(p, q); rep(i, M){ add_edge(p[i] + T * u[i], q[i] + T * v[i], w[i]); } ll s = 10000; add_edge(s, 0, INFL); rep(i, N){ vector xs; xs.push_back(0); xs.push_back(T-1); rep(j, M){ if(u[j] == i){ xs.push_back(p[j]); } if(v[j] == i){ xs.push_back(q[j]); } } sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end()); rep(j, xs.size()-1){ add_edge(xs[j] + T * i, xs[j+1] + T * i, INFL); } } cout << max_flow(s, T * N - 1) << endl; }