// Arup Guha
// 7/12/2015
// Solution to 2013 USACO Silver Problem B: Vacation Planning

import java.util.*;
import java.io.*;

public class vacation {

	public static int[][] m;

	public static void main(String[] args) throws Exception {

		BufferedReader stdin = new BufferedReader(new FileReader("vacation.in"));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		int n = Integer.parseInt(tok.nextToken());
		int edges = Integer.parseInt(tok.nextToken());
		int hubs = Integer.parseInt(tok.nextToken());
		int queries = Integer.parseInt(tok.nextToken());
		m = new int[n][n];

		// Set up adjacency matrix.
		for (int i=0; i<n; i++) {
			Arrays.fill(m[i], 1000000000);
			m[i][i] = 0;
		}

		// Read in matrix.
		for (int i=0; i<edges; i++) {
			tok = new StringTokenizer(stdin.readLine());
			int u = Integer.parseInt(tok.nextToken())-1;
			int v = Integer.parseInt(tok.nextToken())-1;
			int d = Integer.parseInt(tok.nextToken());
			m[u][v] = d;
		}

		// Run Floyd's.
		for (int k=0; k<n; k++)
			for (int i=0; i<n; i++)
				for (int j=0; j<n; j++)
					m[i][j] = Math.min(m[i][j], m[i][k]+m[k][j]);

		int res = 0;
		long sum = 0;

		// Process queries.
		for (int i=0; i<queries; i++) {
			tok = new StringTokenizer(stdin.readLine());
			int start = Integer.parseInt(tok.nextToken()) - 1;
			int end = Integer.parseInt(tok.nextToken()) - 1;

			// Look for any intermediate hub.
			int path = 1000000000;
			for (int mid=0; mid<hubs; mid++)
				path = Math.min(path, m[start][mid]+m[mid][end]);

			// There was a valid path, so update.
			if (path < 1000000000) {
				res++;
				sum = sum + path;
			}

		}

		// Here is our result.
		PrintWriter out = new PrintWriter(new FileWriter("vacation.out"));
		out.println(res);
		out.println(sum);
		out.close();
		stdin.close();
	}
}
