import java.io.*; import java.util.*; public class MaartenWrongDijkstra { public static void main(String[] args) { Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in))); new MaartenWrongDijkstra().run(sc); sc.close(); } public void run(Scanner sc) { int n = sc.nextInt(); int m = sc.nextInt(); int t = sc.nextInt(); Map> edges = new HashMap<>(); for (int i = 0; i < m; i++) { int a = sc.nextInt(), b = sc.nextInt(), d = sc.nextInt(), v = sc.nextInt(); edges.putIfAbsent(a, new ArrayList<>()); edges.get(a).add(new Edge(a, b, d, v)); edges.putIfAbsent(b, new ArrayList<>()); edges.get(b).add(new Edge(b, a, d, v)); } if (dijkstra(edges, n, 0) <= t) { System.out.println(0); return; } double low = 0, high = 1e15; while (low * (1. + 1e-15) < high) { double mid = (low + high) / 2; if (dijkstra(edges, n, mid) <= t) high = mid; else low = mid; } System.out.println(high); } private double dijkstra(Map> edges, int n, double overSpeed) { double[] distances = new double[n + 1]; boolean[] done = new boolean[n + 1]; PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(i -> distances[i])); pq.add(1); while (!pq.isEmpty()) { Integer current = pq.poll(); if (current == n) return distances[n]; if (done[current]) continue; done[current] = true; for (Edge e : edges.get(current)) { double newDistance = distances[current] + e.dist / (e.speed + overSpeed); if (distances[e.to] == 0 || newDistance < distances[e.to]) { distances[e.to] = newDistance; pq.add(e.to); } } } return Double.NaN; // Should never happen } static class Edge { public final int from; public final int to; public final double dist; public final double speed; Edge(int from, int to, int dist, int speed) { this.from = from; this.to = to; this.dist = dist; this.speed = speed; } } }