// Arup Guha
// 6/4/2013
// Solution to 2005 World Finals Problem B: GSM Network
import java.util.*;

public class gsm {

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

		// Get input data.
		int numTowers = stdin.nextInt();
		int numCities = stdin.nextInt();
		int numRoads = stdin.nextInt();
		int numQ = stdin.nextInt();
		int loop = 1;

		while (numTowers != 0) {

			// Read in cell towers.
			pt[] towers = new pt[numTowers];
			for (int i=0; i<numTowers; i++) {
				double x = stdin.nextDouble();
				double y = stdin.nextDouble();
				towers[i] = new pt(x,y);
			}

			// Create all perpendicular bisectors of pairs of towers.
			line[] allBisectors = new line[numTowers*(numTowers-1)/2];
			int cur = 0;
			for (int i=0; i<numTowers; i++) {
				for (int j=i+1; j<numTowers; j++) {
					allBisectors[cur] = new line(pt.bisector(towers[i],towers[j]), new pt(towers[j].y-towers[i].y, towers[i].x-towers[j].x));
					cur++;
				}
			}

			// Read in the cities.
			pt[] cities = new pt[numCities];
			for (int i=0; i<numCities; i++) {
				double x = stdin.nextDouble();
				double y = stdin.nextDouble();
				cities[i] = new pt(x,y);
			}

			// Read in adjacency matrix.
			int[][] adj = new int[numCities][numCities];
			for (int i=0; i<numCities; i++) {
				Arrays.fill(adj[i], 1000000000);
				adj[i][i] = 0;
			}

			// Get switching graph.
			for (int i=0; i<numRoads; i++) {
				int a = stdin.nextInt()-1;
				int b = stdin.nextInt()-1;
				adj[a][b] = numSwitches(cities[a], cities[b], towers, allBisectors);
				adj[b][a] = adj[a][b];
			}

			// Run Floyd's on it.
			for (int k=0; k<numCities; k++)
				for (int i=0; i<numCities; i++)
					for (int j=0; j<numCities; j++)
						adj[i][j] = Math.min(adj[i][j], adj[i][k]+adj[k][j]);

			// Answer Queries
			System.out.println("Case "+loop+":");
			for (int i=0; i<numQ; i++) {
				int start = stdin.nextInt() - 1;
				int end = stdin.nextInt() - 1;
				if (adj[start][end] < 1000000000)
					System.out.println(adj[start][end]);
				else
					System.out.println("Impossible");
			}

			// Get next case.
			numTowers = stdin.nextInt();
			numCities = stdin.nextInt();
			numRoads = stdin.nextInt();
			numQ = stdin.nextInt();
			loop++;
		}

	}

	// Returns the number of swtiches from start to end.
	public static int numSwitches(pt start, pt end, pt[] towers, line[] allBisectors) {

		int n = towers.length;
		lineseg mySeg = new lineseg(start, end);

		// Store all parameters of intersection with this segment (start->end).
		// A number in this list represents the fraction of the way from start to end the
		// intersection occurs.
		ArrayList<Double> critPts = new ArrayList<Double>();
		critPts.add(0.0);
		critPts.add(1.0);
		for (int i=0; i<allBisectors.length; i++) {

			Double cross = mySeg.intersect(allBisectors[i]);
			if (cross != null)
				critPts.add(cross);
		}

		// Sort these.
		Collections.sort(critPts);

		int numSwitches = 0, prevPt = -1;

		// Go through critical intervals, testing the midpoints of each. 
		// iff there is a switch in consecutive midpoint does there exist an actual switch.
		for (int i=0; i<critPts.size()-1; i++) {
			pt test = mySeg.evalAt((critPts.get(i)+critPts.get(i+1))/2);
			int curPt = test.closest(towers);
			if (i>0 && prevPt != curPt) numSwitches++;
			prevPt = curPt;
		}

		// Return the answer.
		return numSwitches;
	}
}

class pt {

	public double x;
	public double y;

	public pt(double myx, double myy) {
		x = myx;
		y = myy;
	}

	public double dist(pt other) {
		return Math.sqrt(Math.pow(x-other.x,2) + Math.pow(y-other.y,2));
	}

	// Returns the index of the closest point to this point from options.
	public int closest(pt[] options) {

		double minD = dist(options[0]);
		int ans = 0;

		for (int i=1; i<options.length; i++) {
			double tempD = dist(options[i]);
			if (tempD < minD) {
				minD = tempD;
				ans = i;
			}
		}
		return ans;
	}

	// Returns the bisector point of a and b.
	public static pt bisector(pt a, pt b) {
		return new pt((a.x+b.x)/2, (a.y+b.y)/2);
	}
}

class line {

	public pt start;
	public pt dir;

	public line(pt init, pt direction) {
		start = init;
		dir = direction;
	}

}

class lineseg {

	public pt start;
	public pt end;
	public double dx;
	public double dy;

	public lineseg(pt a, pt b) {
		start = a;
		end = b;
		dx = end.x - start.x;
		dy = end.y - start.y;
	}

	// Returns the parameter of intersection (0 to 1) if there is one, null otherwise.
	public Double intersect(line myLine) {

		double den = det(dx, -myLine.dir.x, dy, -myLine.dir.y);

		// Will never be useful.
		if (den == 0) return null;

		// Solves for parameter on segment.
		double num = det(myLine.start.x-start.x, -myLine.dir.x, myLine.start.y-start.y, -myLine.dir.y);
		double lambda = num/den;

		// Intersection not on segment.
		if (lambda < 0 || lambda > 1) return null;

		return lambda;
	}

	public static double det(double a, double b, double c, double d) {
		return a*d - b*c;
	}

	public pt evalAt(double lambda) {
		return new pt(start.x+lambda*dx, start.y+lambda*dy);
	}
}