// Arup Guha
// 12/23/2025
// Solution to 2025 SER D1 Problem L: Tree Racing

import java.util.*;
import java.io.*;

public class treeracing {

	public static int n;
	public static ArrayList<Integer>[] g;
	public static int[] dist;
	public static int root;
	public static racer[] racers;
	public static int k;
	public static boolean[] special;
	
	public static void main(String[] args) throws Exception {
	
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		n = Integer.parseInt(tok.nextToken());
		int m = Integer.parseInt(tok.nextToken());
		k = Integer.parseInt(tok.nextToken());
		
		// Make graph.
		g = new ArrayList[n];
		for (int i=0; i<n; i++)
			g[i] = new ArrayList<Integer>();
		for (int i=0; i<n-1; i++) {
			tok = new StringTokenizer(stdin.readLine());
			int u = Integer.parseInt(tok.nextToken()) - 1;
			int v = Integer.parseInt(tok.nextToken()) - 1;
			g[u].add(v);
			g[v].add(u);
		}
		
		// Store racers.
		racers = new racer[m];
		for (int i=0; i<m; i++) {
			tok = new StringTokenizer(stdin.readLine());
			int u = Integer.parseInt(tok.nextToken()) - 1;
			int t = Integer.parseInt(tok.nextToken());
			racers[i] = new racer(i, u, t);
		}
		
		// Get root, mark special nodes.
		root = Integer.parseInt(stdin.readLine()) - 1;
		int numS = Integer.parseInt(stdin.readLine());
		special = new boolean[n];
		for (int i=0; i<numS; i++)
			special[Integer.parseInt(stdin.readLine())-1] = true;
		
		// Do BFS and get a bunch of info.
		info[] dArray = rootTree();
		
		// Sorting special nodes by depth.
		ArrayList<Integer>[] depthSpecial = new ArrayList[n];
		for (int i=0; i<n; i++) depthSpecial[i] = new ArrayList<Integer>();
		for (int i=0; i<n; i++)
			if (special[i])
				depthSpecial[dArray[i].d].add(i);
			
		PriorityQueue<racer>[] pq = new PriorityQueue[n];
		for (int i=0; i<n; i++) pq[i] = new PriorityQueue<racer>();
		
		// Stores answers for each racer.
		long[] times = new long[m];
		Arrays.fill(times, -1);
		
		// Process each racer.
		for (int i=0; i<m; i++) {
			
			int id = racers[i].u;
			
			// Link to root.
			if (!special[id] && dArray[id].prevSpecial == -1) {
				times[i] = racers[i].unit*dArray[id].d;
			}
			
			// Special on the way to root.
			else {
				
				// You start at a special node.
				if (special[id]) {
					pq[id].add(racers[i]);
				}
				
				// Here we have to calculate the distance to nearest special node.
				else {
					racers[i].totald = racers[i].unit*dArray[id].dToSpecial;
					pq[dArray[id].prevSpecial].offer(racers[i]);
				}
			}
		}
		
		// Process special nodes in order from deepest upto root.
		for (int i=n-1; i>0; i--) {
			for (Integer x: depthSpecial[i]) {
				
				// Just to be safe.
				if (pq[x].size() == 0) continue;
				
				ArrayList<racer> tmp = new ArrayList<racer>();
				
				// x is the node.
				for (int z=0; z<k && pq[x].size()>0; z++) 
					tmp.add(pq[x].poll());
				
				// We will advance to another priority queue.
				if (dArray[x].prevSpecial != -1) {
					
					// Find our next queue.
					int newLoc = dArray[x].prevSpecial;
					
					// Update times.
					int addD = dArray[x].dToSpecial;
					for (racer mine: tmp)
						mine.totald += ((long)addD)*mine.unit;
					
					// Add to queue.
					for (racer mine: tmp) 
						pq[newLoc].offer(mine);
				}
				
				// Process final ending times.
				else {
					for (racer me: tmp) {
						int addD = dArray[x].d;
						me.totald += ((long)addD)*me.unit;
						times[me.ID] = me.totald;
					}						
				}
			}
		} // end i loop.
		
		// times should be good.
		StringBuffer sb = new StringBuffer();
		for (int i=0; i<m; i++)
			sb.append(times[i]+"\n");
		System.out.print(sb);
	}
	
	public static info[] rootTree() {
		
		info[] res = new info[n];
		Arrays.fill(res, null);
		
		// Root isn't special and has no previous special.
		res[root] = new info(0, -1, -1);
		
		ArrayDeque<Integer> q = new ArrayDeque<Integer>();
		q.offer(root);
		
		// Run BFS.
		while (q.size() > 0) {
			
			int cur = q.poll();
			
			for (Integer next: g[cur]) {
				
				// Already been enqueued.
				if (res[next] != null) continue;
				
				// Set defaults.
				int myd = res[cur].d + 1;
				int mydToSpec = -1, pSpec = -1;
				
				// Here is how children of special nodes work.
				if (special[cur]) {
					mydToSpec = 1;
					pSpec = cur;
				}
				
				// Here is if a special node is somewhere above.
				else if (res[cur].dToSpecial != -1) {
					mydToSpec = res[cur].dToSpecial+1;
					pSpec = res[cur].prevSpecial;
				}
				
				// Store info then add to queue.
				res[next] = new info(myd, mydToSpec, pSpec);
				q.offer(next);
			}
		}
		
		return res;
	}
}

class racer implements Comparable<racer> {

	public int ID;
	public int u;
	public long unit;
	public long totald;
	
	public racer(int myID, int myu, long t) {
		ID = myID;
		u = myu;
		unit = t;
		totald = 0; // will be set later.
	}
	
	public int compareTo(racer other) {
		if (this.totald != other.totald)
			return Long.compare(this.totald, other.totald);
		return Long.compare(this.unit, other.unit);
	}
	
	public String toString() {
		return "RACER "+ID+": "+u+" "+unit+" "+totald;
	}
}	

class info {
	
	public int d;
	public int dToSpecial;
	public int prevSpecial;
	
	public info(int myd, int mydToSpecial, int myPrevSpecial) {
		d = myd;
		dToSpecial = mydToSpecial;
		prevSpecial = myPrevSpecial;
	}
	
	public String toString() {
		return d+", "+dToSpecial+", "+prevSpecial;
	}
}