#include using namespace std; #define REP(i,a,n) for(int i=(a); i<(int)(n); i++) #define rep(i,n) REP(i,0,n) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it) #define ALLOF(c) (c).begin(), (c).end() typedef long long ll; typedef unsigned long long ull; const ll INF = (ll)(1e19); class Dinic { ll MAX_V; struct edge{ ll to, cap, rev, icap, flow; }; vector< vector > G; vector level; //sからの距離 vector iter; //どこまで調べたか void max_flow_bfs(ll s){ fill(level.begin(), level.end(), -1); queue que; level[s] = 0; que.push(s); while(!que.empty()){ ll v = que.front(); que.pop(); for(ll i=0; i0 && level[e.to]<0){ level[e.to] = level[v] + 1; que.push(e.to); } } } } ll max_flow_dfs(ll v, ll t, ll f){ if(v==t) return f; for(ll &i=iter[v]; i0 && level[v]0){ e.cap -= d; G[e.to][e.rev].cap += d; e.flow += d; return d; } } } return 0; } public: Dinic(ll N):MAX_V(N),G(N),level(N),iter(N){ } void add_edge(ll from, ll to, ll cap){ G[from].push_back((edge){to, cap, (ll)G[to].size(), cap, 0}); G[to].push_back((edge){from, 0, (ll)G[from].size()-1, 0, 0}); } ll get_flow(ll from, ll to){ //untried rep(i,G[from].size()){ if(G[from][i].to == to){ return G[from][i].flow; } } return -1; } ll max_flow(ll s, ll t){ ll flow = 0; while(true){ max_flow_bfs(s); if(level[t]<0) return flow; fill(iter.begin(), iter.end(), 0); ll f; while((f = max_flow_dfs(s, t, INF))>0){ flow += f; } } } }; int N, M; ll d; vector> air; int main(){ cin >> N >> M >> d; rep(i,M){ ll u, v, p, q, w; cin >> u >> v >> p >> q >> w; air.push_back({u,v,p,q,w}); } { map,ll> check; rep(i,air.size()){ vector tmp = {air[i][0], air[i][1], air[i][2], air[i][3]}; check[tmp] += air[i][4]; } air.clear(); FOR(it,check){ vector tmp = it->first; tmp.push_back(it->second); air.push_back(tmp); } } vector> G(N+1); rep(i,air.size()){ G[air[i][0]].insert(air[i][2]); G[air[i][1]].insert(air[i][3]); } map,int> memo; int id = 0; rep(i,G.size()){ FOR(it,G[i]){ memo[{(ll)i,(*it), 0}] = id++; memo[{(ll)i,(*it), 1}] = id++; } } Dinic dinic(id+2); rep(i,G.size()){ FOR(it1,G[i]){ FOR(it2,G[i]){ int prev = *it1; int next = *it2; if(next-prev>=d){ dinic.add_edge(memo[{(ll)i,prev,1}], memo[{(ll)i,next,0}], INF); } } } } rep(i,air.size()){ dinic.add_edge(memo[{air[i][0],air[i][2],0}], memo[{air[i][1],air[i][3],1}], air[i][4]); } rep(i,G.size()){ FOR(it,G[i]){ if(i==1) dinic.add_edge(id, memo[{(ll)i,*it,0}], INF); if(i==1) dinic.add_edge(id, memo[{(ll)i,*it,1}], INF); if(i==N) dinic.add_edge(memo[{(ll)i,*it,0}], id+1, INF); if(i==N) dinic.add_edge(memo[{(ll)i,*it,1}], id+1, INF); } } cout << dinic.max_flow(id, id+1) << endl; return 0; }