#include <iostream>
#include <cstring>
#include <queue>
//1.读准题意,是问第一个到第二个之间的距离
//2.注意范围,稍微大大一点的数尽量用long long
//3.采用广度搜索,可以实现找到最短路径
//4.该题的关键在于引入kcount来表示已占用的点数和step来记录路径,实现在广度搜索的过程中,淘汰不合适的方案,达到相应搜索的目的
using namespace std;
const int MAXN = 200;
struct {
long long x, y;
} coord[MAXN+5];
struct status {
long long x, y;
int step, kcount;
};
bool visited[MAXN+5];
int bfs(int n, int m, int k, int begin, int end, long long r)
{
int max;
// 变量初始化
memset(visited, false, sizeof(visited));
// 设置根结点
status start, front, v;
start.x = coord[begin].x;
start.y = coord[begin].y;
start.step = 0;
start.kcount = 0;
queue<status> q;
q.push(start);
// 设置根结点为已经访问过
visited[begin] = true;
while(!q.empty()) {
front = q.front();
q.pop();
// 到达终点则结束
if(front.x == coord[end].x && front.y == coord[end].y)
return front.step - 1;
// 搜索可以连接的路由器
if(front.kcount == k)
max = n;
else
max = n + m;
for(int i=0; i<max; i++) {
// 访问过的坐标则跳过
if(visited[i])
continue;
// 判定下一个路由器的坐标是否在半径r之内, 不在半径之内则跳过,在半径之内则继续搜索
if((front.x - coord[i].x) * (front.x - coord[i].x) + (front.y - coord[i].y) * (front.y - coord[i].y) > r * r)
continue;
else {
// 第i个路由器设为已经访问过
visited[i] = true;
// 计算步数,并且将第i个路由器加入队列
v.x = coord[i].x;
v.y = coord[i].y;
v.step = front.step + 1;
if(i >= n)
v.kcount = front.kcount + 1;
else
v.kcount = front.kcount;
q.push(v);
}
}
}
return 0;
}
int main()
{
int n, m, k;
long long r;
// 输入数据
cin >> n >> m >> k >> r;
for(int i=0; i<n+m; i++) // n个路由器的位置+可以增设的m个路由器的位置
cin >> coord[i].x >> coord[i].y;
// 输出结果
cout << bfs(n, m, k, 0, 1, r) << endl;
return 0;
}