#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(__typeof((X).begin()) it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)x.size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<int,int> pi;
typedef stringstream sst;
typedef vector<int> vi;

struct edge{
	int from,to,cost;
	edge(int from,int to,int cost):from(from),to(to),cost(cost){}
};

bool comp(const edge e1,const edge e2){return e1.cost>e2.cost;}

int N,M,K,Q;
vector<edge> G[100010];
int d[100010];
vector<edge> E;

int root=0,par[21][100010],dep[100010];
int mi[21][100010];

void dij(int n,int from){
	fill(d,d+n,INF);
	priority_queue<pi,vector<pi>,greater<pi> > Q;
	d[from]=0;
	Q.push(pi(0,from));
	while(sz(Q)){
		pi p=Q.top();Q.pop();
		if(p.fir>d[p.sec])continue;
		int v=p.sec;
		rep(i,sz(G[v])){
			if(d[G[v][i].to] > d[v] + G[v][i].cost){
				d[G[v][i].to] = d[v] + G[v][i].cost;
				Q.push(pi(d[G[v][i].to],G[v][i].to));
			}
		}
	}
}

int par_uf[100010],RANK[100010];

void init_uf(int n){for(int i=0;i<n;i++){par_uf[i]=i;RANK[i]=0;}}
int find(int x){if(par_uf[x]==x)return x;else return find(par_uf[x]);}
void unite(int x,int y){x=find(x);y=find(y);if(x==y)return;if(RANK[x]<RANK[y])par_uf[x]=y;else{par_uf[y]=x;if(RANK[x]==RANK[y])RANK[x]++;}}
bool same(int x,int y){return find(x)==find(y);}

void dfs(int v,int p,int depth){
	par[0][v]=p;
	mi[0][v]=min(d[v],p==-1?(int)INF:d[p]);
	dep[v]=depth;
	rep(i,sz(G[v])){
		if(G[v][i].to!=p)dfs(G[v][i].to,v,depth+1);
	}
}

void init(int n){
	dfs(root,-1,0);
	rep(k,19)rep(v,n){
		if(par[k][v]<0){
			par[k+1][v]=-1;
			mi[k+1][v]=mi[k][v];
		}else{
			par[k+1][v]=par[k][par[k][v]];
			mi[k+1][v]=min(mi[k][v],mi[k][par[k][v]]);
		}
	}
}

int lca(int u,int v){
	if(dep[u]>dep[v])swap(u,v);
	int minU=d[u],minV=d[v];
	rep(k,20)if((dep[v]-dep[u]) >> k & 1){
		minV=min(minV,mi[k][v]);
		v=par[k][v];
	}
	if(u==v)return min(minU,minV);//u;
	for(int k=19;k>=0;k--){
		if(par[k][u]!=par[k][v]){
			minU=min(minU,mi[k][u]);
			minV=min(minV,mi[k][v]);
			u=par[k][u];
			v=par[k][v];
		}
	}
	return min(min(minU,minV),d[par[0][u]]);//par[0][u];
}

int main(){
	cin.tie(0);
	ios_base::sync_with_stdio(0);
	cin>>N>>M>>K>>Q;
	int A,B,L;
	rep(i,M){
		cin>>A>>B>>L;
		A--;B--;
		edge e1=edge(A,B,L),e2=edge(B,A,L);
		G[A].pb(e1);
		G[B].pb(e2);
		E.pb(e1);
	}
	int F;
	rep(i,K){
		cin>>F;
		F--;
		G[N].pb(edge(N,F,0));
	}
	dij(N+1,N);
	
	rep(i,N)G[i].clear();
	rep(i,M){
		E[i].cost=min(d[E[i].from],d[E[i].to]);
	}
	sort(E.begin(),E.end(),comp);
	init_uf(N);
	rep(i,M){
		if(!same(E[i].from,E[i].to)){
			unite(E[i].from,E[i].to);
			G[E[i].from].pb(E[i]);
			G[E[i].to].pb(edge(E[i].to,E[i].from,E[i].cost));
		}
	}
	
	init(N);
	int S,T;
	rep(i,Q){
		cin>>S>>T;
		S--;T--;
		cout<<lca(S,T)<<endl;
	}
}

Measured memory_bytes: 33108