![]()
![]()
![]()
![]()
![]()
![]()
#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;
}