import std; void main () { int N, M, P; long Y; readln.read(N, M, P, Y); auto graph = new Tuple!(int, int)[][](N); foreach (i; 0 .. M) { int A, B, C; readln.read(A, B, C); A--, B--; graph[A] ~= tuple(B, C); graph[B] ~= tuple(A, C); } auto D = new int[](P); auto E = new int[](P); foreach (i; 0 .. P) { readln.read(D[i], E[i]); D[i]--; } // dijkstra auto pq = BinaryHeap!(Tuple!(int, long)[], "b[1] < a[1]")([]); auto cost = new long[](N); cost[] = long.max; cost[0] = 0; pq.insert(tuple(0, 0L)); while (!pq.empty()) { auto pos = pq.front(); pq.removeFront(); int u = pos[0]; long c = pos[1]; if (cost[u] < c) continue; foreach (to; graph[u]) { int v = to[0]; long nc = c + to[1]; if (nc < cost[v]) { cost[v] = nc; pq.insert(tuple(v, nc)); } } } long ans = 0; foreach (i; 0 .. P) { long rem = max(0L, Y - cost[D[i]]); if (rem <= 0) continue; ans = max(ans, rem / E[i]); } writeln(ans); } void read (T...) (string S, ref T args) { import std.conv : to; import std.array : split; auto buf = S.split; foreach (i, ref arg; args) { arg = buf[i].to!(typeof(arg)); } }