//Bokan ga bokka--nn!!
//Daily Lunch Special Tanoshii !!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
#include <cassert>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 500000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i<x;i++)
int d[100005];
priority_queue<P,vector<P>,greater<P> >que;
vector<P>edge[100005];
int par[100005],ran[100005];
vector<P1>all;
int n,m,k,q;
void init()
{
	for(int i=0;i<100005;i++) { par[i]=i; ran[i]=0;}
}
int find(int x)
{	
	if(par[x]==x) return x;
	else return par[x]=find(par[x]);
	
}
void unite(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return;
	if(ran[x]<ran[y])
	{
		par[x]=y;
	}
	else
	{
		par[y]=x;
		if(ran[x]==ran[y]) ran[x]++;
	}
}
bool same(int x,int y)
{
	return find(x)==find(y);
}
vector<int>next[100005];
int parent[20][100005][2];
int depth[100005];
void dfs(int v,int p,int dd)
{
	parent[0][v][0]=p;
	if(parent[0][v][0]!=-1) parent[0][v][1]=min(d[p],d[v]);
	else parent[0][v][1]=d[v];
	depth[v]=dd;
	for(int i=0;i<next[v].size();i++)
	{
		if(next[v][i]!=p)
		{
			dfs(next[v][i],v,dd+1);
		}
	}
}
void init2()
{
	dfs(1,-1,0);
	for(int k=0;k+1<20;k++)
	{
		for(int v=1;v<=n;v++)
		{
			if(parent[k][v][0]<0) { parent[k+1][v][0]=-1; parent[k+1][v][1]=parent[k][v][1];}
			else{ 
				parent[k+1][v][0]=parent[k][parent[k][v][0]][0];
				parent[k+1][v][1]=min(parent[k][v][1],parent[k][parent[k][v][0]][1]);
			}
		}
	}
}
int lca(int u,int v)
{
	int val=INF;
	if(depth[u]>depth[v]) swap(u,v);
	for(int k=0;k<20;k++)
	{
		if((depth[v]-depth[u])>>k & 1)
		{
			val=min(val,parent[k][v][1]);
			v=parent[k][v][0];
		}
	}
	if(u==v) return val;
	for(int k=19;k>=0;k--)
	{
		if(parent[k][u][0]!=parent[k][v][0])
		{
			val=min(val,min(parent[k][v][1],parent[k][u][1]));
			u=parent[k][u][0];
			v=parent[k][v][0];
		}
	}
	return min(val,min(parent[0][v][1],parent[0][u][1]));
}
int main()
{

	scanf("%d %d %d %d",&n,&m,&k,&q);
	for(int i=1;i<=m;i++)
	{
		int a,b,l;
		scanf("%d %d %d",&a,&b,&l);
		edge[a].pb(mp(b,l));
		edge[b].pb(mp(a,l));
	}
	fill(d,d+100005,INF);
	for(int i=1;i<=k;i++)
	{
		int v; scanf("%d",&v);
		d[v]=0;
		que.push(mp(d[v],v));
	}
	while(!que.empty())
	{
		P p=que.top(); que.pop();
		if(p.first!=d[p.second]) continue;
		for(int i=0;i<edge[p.second].size();i++)
		{
			if(d[edge[p.second][i].first]>p.first+edge[p.second][i].second)
			{
				d[edge[p.second][i].first]=p.first+edge[p.second][i].second;
				que.push(mp(d[edge[p.second][i].first],edge[p.second][i].first));
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<edge[i].size();j++)
		{
			all.pb(mp(min(d[i],d[edge[i][j].first]),mp(i,edge[i][j].first)));
		}
	}
	sort(all.begin(),all.end(),greater<P1>());
	init();
	int s=0;
	for(int i=0;i<all.size();i++)
	{
		P1 p=all[i];
		int x=p.second.first;
		int y=p.second.second;
		if(same(x,y)) continue;
		unite(x,y);
		next[x].pb(y);
		next[y].pb(x);
		//root=x;
		//s++;
		//printf("%d\n",i);
	}
	//assert(s==n-1);
	//int f=0;
	//for(int i=0;i<131072*4;i++) segment[i][0]=segment[i][1]=INF;
	//fill(dist,dist+300005,INF);
	//dfs(1,-1,0,f);
	init2();
	/*for(int i=0;i<131072*2;i++)
	{
//if(dist[i]!=INF) printf("%d %d %d\n",i,dist[i],id[i]); 
		update(i,depth[i]);
	}*/
	//dfs2(1,-1,0);
	for(int i=0;i<q;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		printf("%d\n",lca(a,b));
	}
}

Measured memory_bytes: 37992