#include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define ll long long #define mkp make_pair using namespace std; const int MaxN = 255 * 255, MaxM = MaxN * 255, inf = 1000000000; int N, M, x[MaxN], y[MaxN], W, Hash[255][255], To[255][255][255], indx[MaxN], indy[MaxN]; bool endp[MaxN]; struct Disk { int r, c; bool operator < (const Disk &a) const { if (r != a.r) return r < a.r; return c > a.c; } } d[MaxN], disk[MaxN]; ll sqr(ll x) { return x * x; } ll GetDist(int i, int j) { return sqr(x[i] - x[j]) + sqr(y[i] - y[j]); } struct Node { int d, x; bool operator < (const Node &a) const { return d > a.d; } Node() {} Node(int d, int x) :d(d), x(x) {} }; bool done[MaxN]; int dist[MaxN]; priority_queue <Node> Q; int Dijkstra() { while (!Q.empty()) { int u = Q.top().x, i = indx[u], k = indy[u]; // printf("%d %d\n", u, dist[u]); Q.pop(); if (done[u]) continue; done[u] = 1; if (endp[u]) return dist[u]; if (indy[u] != M) { int v = u + 1; if (dist[v] > dist[u] + disk[indy[v]].c - disk[indy[u]].c) { dist[v] = dist[u] + disk[indy[v]].c - disk[indy[u]].c; Q.push(Node(dist[v], v)); } } for (int j = 1; j <= N; j++) if ((j != indx[u]) && (To[i][j][k] <= M)) { int v = Hash[j][To[i][j][k]]; if (dist[v] > dist[u] + disk[To[i][j][k]].c) { dist[v] = dist[u] + disk[To[i][j][k]].c; Q.push(Node(dist[v], v)); } } } return inf; } void Main() { int dtot; scanf("%d%d%d", &N, &dtot, &W); for (int i = 1; i <= N; i++) scanf("%d%d", x + i, y + i); for (int i = 1; i <= dtot; i++) { scanf("%d%d", &d[i].r, &d[i].c); } sort(d + 1, d + dtot + 1); M = 0; for (int i = 1; i <= dtot; i++) { while(M && (disk[M].c > d[i].c)) M--; disk[++M] = d[i]; } int total = 0; for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) { Hash[i][j] = ++total; indx[total] = i; indy[total] = j; } Q = priority_queue <Node>(); memset(done, 0, sizeof(done)); memset(dist, 63, sizeof(dist)); memset(endp, 0, sizeof(endp)); for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) { if (disk[j].r >= y[i]) { dist[Hash[i][j]] = disk[j].c; Q.push(Node(dist[Hash[i][j]], Hash[i][j])); } if (disk[j].r >= W - y[i]) endp[Hash[i][j]] = 1; } for (int j = 1; j <= N; j++) if (j != i) { ll dist = GetDist(i, j); int ind = M + 1; for (int k = 1; k <= M; k++) { while ((ind > 1) && ((ll)(disk[k].r + disk[ind - 1].r) * (disk[k].r + disk[ind - 1].r) >= dist)) ind--; To[i][j][k] = ind; } } } int ret = Dijkstra(); if (ret < inf) printf("%d\n", ret); else printf("impossible\n"); } int main() { int T; freopen("river.in","r",stdin); freopen("river.out","w",stdout); scanf("%d", &T); while (T--) { Main(); } return 0; }