#include #include #include #include #include #include #include using namespace std; typedef long long lint; typedef vectorvi; typedef pairpii; #define rep(i,n)for(int i=0;i<(int)(n);++i) struct edge{ int to; lint cap; int rev; }; const int N=3001; const lint INF=1e16; // 蟻本p.195から vectorG[N]; int level[N]; int iter[N]; void add_edge(int from,int to,lint cap){ G[from].push_back((edge){to,cap,G[to].size()}); G[to].push_back((edge){from,0,G[from].size()-1}); } void bfs(int s){ memset(level,-1,sizeof(level)); queueque; level[s]=0; que.push(s); while(!que.empty()){ int v=que.front();que.pop(); for(int i=0;i<(int)G[v].size();++i){ edge&e=G[v][i]; if(e.cap>0&&level[e.to]<0){ level[e.to]=level[v]+1; que.push(e.to); } } } } lint dfs(int v,int t,lint f){ if(v==t)return f; for(int &i=iter[v];i<(int)G[v].size();++i){ edge&e=G[v][i]; if(e.cap>0&&level[v]0){ e.cap-=d; G[e.to][e.rev].cap+=d; return d; } } } return 0; } lint max_flow(int s,int t){ lint flow=0; for(;;){ bfs(s); if(level[t]<0)return flow; memset(iter,0,sizeof(iter)); lint f; while((f=dfs(s,t,INF))>0){ flow+=f; } } } typedef pair pipii; map memo; int get(int v,pii t){ pipii ind(v,t); if(memo.count(ind))return memo[ind]; int s=memo.size(); memo[ind]=s; return s; } const int A=1000; vector leave[A]; vector arrive[A]; int u[A],v[A],p[A],q[A],w[A]; int main(){ int n,m,d; cin>>n>>m>>d; vectortest; rep(i,m){ cin>>u[i]>>v[i]>>p[i]>>q[i]>>w[i]; u[i]--,v[i]--; leave[u[i]].push_back(pii(p[i],i)); arrive[v[i]].push_back(pii(q[i],i)); test.push_back(pii(p[i],-(i+1))); test.push_back(pii(q[i],i+1)); } sort(test.begin(),test.end()); rep(i,test.size()){ int idx=test[i].second; int j=abs(idx)-1; if(idx>0){ get(u[j],pii(p[j],j)); }else{ get(v[j],pii(q[j],j)); } } assert((int)memo.size()<=N-2); rep(i,n){ sort(leave[i].begin(),leave[i].end()); sort(arrive[i].begin(),arrive[i].end()); } rep(i,n){ rep(j,leave[i].size()-1){ int a=get(i,leave[i][j]); int b=get(i,leave[i][j+1]); add_edge(a,b,INF); } rep(j,arrive[i].size()){ int a=get(n+i,arrive[i][j]); lint time=arrive[i][j].first; lint dst=time+d; if(dst>1e9)continue; int idx=lower_bound(leave[i].begin(),leave[i].end(),pii((int)dst,-1))-leave[i].begin(); if(idx<(int)leave[i].size()){ int b=get(i,leave[i][idx]); add_edge(a,b,INF); } } } rep(i,m){ int a=get(u[i],pii(p[i],i)); int b=get(n+v[i],pii(q[i],i)); add_edge(a,b,w[i]); } int src=N-2; int sink=N-1; rep(i,arrive[n-1].size()){ int a=get(n+n-1,arrive[n-1][i]); add_edge(a,sink,INF); } rep(i,leave[0].size()){ int a=get(0,leave[0][i]); add_edge(src,a,INF); } lint flow=max_flow(src,sink); cout<