#include<bits/stdc++.h>//万能头文件
using namespace std;//开启标准名字空间
struct Node {
int x,y,Time;//x为横坐标,y为纵坐标,Time为被感染时间
} s[250010];//设置结构体数组维护队列
int head,tail;//分别为头指针、尾指针
int n,m,a,b,vis[505][505],c[250010],d[250010],e,f,i,j,k;//vis的意义同分析,c数组和d数组为感染源坐标,e、f为领主坐标
int P[510][510];//每个坐标被感染时间
void bfs() {//开始bfs
tail=0;
head=0;//初始化指针
for(i=1; i<=a; i++) {//先把已知条件加入队列,并初始化时间
s[++tail].x=c[i];//相当于tail++,s[tail].x=c[i]
s[tail].y=d[i];
s[tail].Time=0;
P[c[i]][d[i]]=0;
}
while(head<tail) {//如果队列中还有元素
head++;//头指针加1
int h=s[head].x,r=s[head].y,tmp=s[head].Time;//取出队首元素
if(h+1<=n && vis[h+1][r]==0) {//往右扩展,若合法加入队列
s[++tail].x=h+1;//更新x坐标
s[tail].y=r;//更新y坐标
P[h+1][r]=s[tail].Time=tmp+1;//更新时间
vis[h+1][r]=1;//记录为已被感染
}
//以下每步操作意义同上
if(h-1>=1 && vis[h-1][r]==0) {//往左扩展,若合法加入队列
s[++tail].x=h-1;
s[tail].y=r;
P[h-1][r]=s[tail].Time=tmp+1;
vis[h-1][r]=1;
}
if(r+1<=m && vis[h][r+1]==0) {//往上扩展,若合法加入队列
s[++tail].x=h;
s[tail].y=r+1;
P[h][r+1]=s[tail].Time=tmp+1;
vis[h][r+1]=1;
}
if(r-1>=1 && vis[h][r-1]==0) {//往下扩展,若合法加入队列
s[++tail].x=h;
s[tail].y=r-1;
P[h][r-1]=s[tail].Time=tmp+1;
vis[h][r-1]=1;
}
}
}
int main() {
scanf("%d%d%d%d",&n,&m,&a,&b);//输入矩阵大小、感染源个数和领主个数
for(i=1; i<=a; i++) {
scanf("%d%d",&c[i],&d[i]);//输入感染源坐标
vis[c[i]][d[i]]=1;//记录为已被感染
}
bfs();//遍历每个坐标被感染的时间
for(i=1; i<=b; i++) {
scanf("%d%d",&e,&f);//输入领主坐标
printf("%d\n",P[e][f]);//直接输出被感染时间
}
return 0;//结束
}