#https://yukicoder.me/problems/no/654 import sys sys.setrecursionlimit(10**7) from collections import deque class Edmond_karp: def __init__(self,V): self.v = V self.edges = [[] for _ in range(V)] #隣接リスト def addEdge(self,fr,to,cap): forward = [to,cap,len(self.edges[to])] #行き先、capasity,逆向きの辺のindex backward = [fr,0,len(self.edges[fr])] #逆向きの辺 self.edges[fr].append(forward) self.edges[to].append(backward) def bfs(self,s,t): #tはdestination,fは追加できる最大のフロー量 q = deque([(s,-1,float('inf'),-1)]) #vertex,parent,flow,rev_idx parent = [-1]*self.v revs = [-1]*self.v self.used[s] = 1 parent[s] = -1 revs[s] = -1 #sからでてる逆向きの辺は存在しないので-1でok aug_flow = 0 #sからtまでの最短距離を計算する while len(q) > 0: v,p,f,rev = q.popleft() if v == t: #終点に達したら aug_flow = f break for e in self.edges[v]: w,cap,rev_idx = e #revは反対の辺の情報 if cap and not self.used[w]: q.append((w,v,min(f,cap),rev_idx)) self.used[w] = 1 parent[w] = v revs[w] = rev_idx #wの逆向きの辺のindex # 最短経路のフロー数だけ遡る if aug_flow: #最大値が0じゃなかったら v,p,rev = t,parent[t],revs[t] while p != -1: rev_e = self.edges[v][rev] #tからのreversed edge e = self.edges[p][rev_e[2]] #vじゃだめ。index入れないと e[1] -= aug_flow rev_e[1] += aug_flow v,p,rev = p,parent[p],revs[p] return aug_flow def flow(self,s,t): flow = 0 f = INF = float('inf') v = self.v while f: #この操作回数はO(VE)らしい。 self.used = [0]*v #used初期化 f = self.bfs(s,t) #計算量はO(E) fordfulkersonと一緒 flow += f return flow N,M,d = map(int,input().split()) #(u,pi)→(v,qi)にcapacityがwiの辺を設定 #(u,pi)→(u,pi+1)には容量無限大の辺を設定(空港で待つことを意味する) #上の方法だと間に合わないから #辺を貼るのは街iに飛行機が到着する時刻だけでいい。 def convert(u,time): return u*maxtime + time_dict[time] INF = float('inf') #dを考慮する。Aに出発しBに到着する飛行機はAに出発し、B+dに到着するとみなすことができる。 events = [] time = set() for _ in range(M): u,v,p,q,w = map(int,input().split()) #このqは1日の終わりを超えることはない。 u -= 1 v -= 1 q += d #(u,p)→(v,q+d)へcapacityがwの辺 events.append((u,v,p,q,w)) time.add(p) time.add(q) time = sorted(list(time)) maxtime = len(time) time_dict = {t:i for i,t in enumerate(time)} ff = Edmond_karp(maxtime*N) wait = [[] for _ in range(N)] for u,v,p,q,w in events: ff.addEdge(convert(u,p),convert(v,q),w) wait[u].append(p) wait[v].append(q) for i in range(N): wait[i].sort() for j in range(len(wait[i])-1): t1 = wait[i][j] t2 = wait[i][j+1] ff.addEdge(convert(i,t1),convert(i,t2),INF) if wait[0] and wait[N-1]: print(ff.flow(convert(0,wait[0][0]),convert(N-1,wait[N-1][-1]))) else: print(0)