import bisect import heapq import itertools import math import os import re import string import sys from collections import Counter, deque, defaultdict from copy import deepcopy from decimal import Decimal from fractions import gcd from functools import lru_cache, reduce from operator import itemgetter import numpy as np if os.getenv("LOCAL"): sys.stdin = open("_in.txt", "r") sys.setrecursionlimit(2147483647) INF = float("inf") IINF = 10 ** 18 MOD = 10 ** 9 + 7 N, M, D = list(map(int, sys.stdin.readline().split())) UVPQW = [list(map(int, sys.stdin.readline().split())) for _ in range(M)] class Dinic: def __init__(self, graph=None, residual=None): """ :param list of (list of (int, int)) graph: (to, cap) の隣接リスト :param list of (list of (list of (int|list))) residual: (to, cap, rev) の残余グラフ """ assert (graph and not residual) or (not graph and residual) if graph: self.graph = self.residual_graph(graph) else: self.graph = residual @staticmethod def residual_graph(graph): """ 残余グラフ構築 :param list of (list of (int, int)) graph: (to, cap) の隣接リスト :rtype: list of (list of (list of (int|list))) :return: (to, cap, rev) の残余グラフ """ ret = defaultdict(list) for v in graph.keys(): for u, cap in graph[v]: rev = [v, 0] edge = [u, cap, rev] rev.append(edge) ret[v].append(edge) ret[u].append(rev) return ret def _dist(self, s): """ :param int s: :rtype: list of int :return: s からの距離。残余グラフ上で到達できない場合は -1 """ ret = defaultdict(lambda: -1) ret[s] = 0 que = deque([(s, 0)]) while que: v, d = que.popleft() for u, cap, _ in self.graph[v]: if ret[u] < 0 < cap: ret[u] = d + 1 que.append((u, d + 1)) return ret def _dfs(self, s, t, dist, iter, flow=float('inf')): """ :param int s: :param int t: :param list of int dist: :param list of int iter: :param int flow: """ if s == t: return flow while iter[s] < len(self.graph[s]): edge = self.graph[s][iter[s]] to, cap, rev = edge if dist[s] < dist[to] and cap > 0: f = self._dfs(to, t, dist, iter, min(flow, cap)) if f > 0: edge[1] -= f rev[1] += f return f iter[s] += 1 return 0 def maximum_flow(self, from_v, to_v): """ :param int from_v: :param int to_v: :return: from_v から to_v への最大流 """ ret = 0 while True: dist = self._dist(from_v) if dist[to_v] < 0: break iter = defaultdict(int) while True: flow = self._dfs(from_v, to_v, dist, iter) if flow == 0: break ret += flow return ret counts = [0] * (N + 1) counts[1] = IINF # 時刻をグラフにする nodes = defaultdict(set) graph = defaultdict(list) for u, v, p, q, w in UVPQW: nodes[u].add(p) nodes[v].add(q + D) graph[(u, p)].append(((v, q + D), w)) nodes[1].add(0) nodes[N].add(IINF) for v, ps in nodes.items(): ps = list(ps) ps.sort() for p, q in zip(ps[:-1], ps[1:]): graph[(v, p)].append(((v, q), IINF)) print(Dinic(graph).maximum_flow((1, 0), (N, IINF)))