#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>pr;
typedef pair<int,pr>ppr;
#define fi first
#define se second
struct Edge{
    int to,cost;
    Edge(int to,int cost):to(to),cost(cost){}
    Edge(){}
};
struct UnionFind{
    int N,par[100000],rank[100000];
    UnionFind(int _N){
        N=_N;
        for(int i=0;i<N;i++){
            par[i]=i;
            rank[i]=0;
        }
    }
    int find(int x){
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);y=find(y);
        if(x==y)return;
        if(rank[x]<rank[y])par[x]=y;
        else{
            par[y]=x;
            rank[x]+=rank[x]==rank[y];
        }
    }
    bool same(int x,int y){
        return find(x)==find(y);
    }
};
const int INF=1e9;
int N,M,K,Q;
ppr es[200000];
int F[100000];
vector<Edge>G[100000];
int dist[100000];
int depth[100000];
pr dbl[20][100001];
void Dijkstra(){
    fill_n(dist,N,INF);
    priority_queue<pr,vector<pr>,greater<pr> >Q;
    for(int i=0;i<K;i++){
        Q.push(pr(0,F[i]));
        dist[F[i]]=0;
    }
    while(!Q.empty()){
        pr p=Q.top();Q.pop();
        if(dist[p.se]<p.fi)continue;
        for(int i=0;i<G[p.se].size();i++){
            Edge &e=G[p.se][i];
            if(dist[e.to]<p.fi+e.cost)continue;
            dist[e.to]=p.fi+e.cost;
            Q.push(pr(p.fi+e.cost,e.to));
        }
    }
}
void Kruskal(){
    for(int i=0;i<M;i++){
        ppr &e=es[i];
        e.fi=min(dist[e.se.fi],dist[e.se.se]);
    }
    sort(es,es+M,greater<ppr>());
    UnionFind uf(N);
    vector<ppr>V;
    for(int i=0;i<M;i++){
        ppr &e=es[i];
        if(uf.same(e.se.fi,e.se.se))continue;
        V.push_back(es[i]);
        uf.unite(e.se.fi,e.se.se);
    }
    for(int i=0;i<N-1;i++){
        es[i]=V[i];
    }
}

void dfs(int pos=0,int par=-1,int d=0){
    dbl[0][pos+1]=pr(par+1,min(dist[pos],(par!=-1?dist[par]:(1<<30))));
    depth[pos]=d;
    for(int i=0;i<G[pos].size();i++){
        int to=G[pos][i].to;
        if(to==par)continue;
        dfs(to,pos,d+1);
    }
}
int LCA(int a,int b){
    int cost=min(dist[a],dist[b]);
    if(depth[a]<depth[b])swap(a,b);
    int dif=(depth[a]-depth[b]);
    for(int i=0;i<20;i++){
        if((dif>>i)&1){
            cost=min(cost,dbl[i][a+1].se);
            a=dbl[i][a+1].fi-1;
        }
    }
    if(a==b)return cost;

    for(int i=19;i>=0;i--){
        if(dbl[i][a+1].fi==dbl[i][b+1].fi)continue;
        cost=min(cost,dbl[i][a+1].se);
        cost=min(cost,dbl[i][b+1].se);
        a=dbl[i][a+1].fi-1;
        b=dbl[i][b+1].fi-1;
    }
    return min(cost,dbl[0][a+1].se);
}
int main(){
    scanf("%d%d%d%d",&N,&M,&K,&Q);
    for(int i=0;i<M;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        a--;b--;
        es[i].se=pr(a,b);
        G[a].push_back(Edge(b,c));
        G[b].push_back(Edge(a,c));
    }
    for(int i=0;i<K;i++){
        scanf("%d",&F[i]);
        F[i]--;
    }

    Dijkstra();
    Kruskal();

    for(int i=0;i<N;i++)G[i].clear();
    for(int i=0;i<N-1;i++){
        ppr &p=es[i];
        G[p.se.fi].push_back(Edge(p.se.se,0));
        G[p.se.se].push_back(Edge(p.se.fi,0));
    }

    dfs();

    for(int i=0;i<19;i++){
        for(int j=0;j<N;j++){
            int ds=min(dbl[i][j+1].se,dbl[i][dbl[i][j+1].fi].se);
            int to=dbl[i][dbl[i][j+1].fi].fi;
            dbl[i+1][j+1]=pr(to,ds);
        }
    }


    while(Q--){
        int a,b;
        scanf("%d%d",&a,&b);
        a--;b--;
        printf("%d\n",LCA(a,b));
    }
    return 0;
}

Measured memory_bytes: 31648