#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>

using namespace std;

#define MAX_N (100000)
typedef pair<int,int> pint;
typedef pair<int,pint> ppi;
struct edge{
    int dst,weight;
};
vector<edge> road[MAX_N];
vector<ppi> r2;
vector<int> road2[MAX_N];
int d[MAX_N],n;
int inf=1000000000;

struct UnionFind{
    int par[MAX_N]; 
    void init(int n){
        for (int i=0;i<n;i++) par[i] = i;
    } 
    int find(int x){
        if (x==par[x]) return (x);
        return (par[x]=find(par[x]));
    }
    void unite(int x, int y){
        x=find(x);y=find(y);       
        if(x==y) return;
        par[x] = y;
    } 
    bool same(int x, int y){
        return (find(x) == find(y));
    } 
};

int par[20][MAX_N];
int depth[MAX_N];
int mn[20][MAX_N];
void dfs(int v,int p,int dep){
    par[0][v]=p;
    mn[0][v]=min(d[v],p>0?d[p]:inf);
    depth[v]=dep;
    for(int i=0;i<road2[v].size();++i){
        if(road2[v][i]!=p){
            dfs(road2[v][i],v,dep+1);
    }
  }
}
void lca_init(){
    dfs(0,-1,0);
    for(int k=0;k<19;++k){
        for(int i=0;i<n;++i){
            if(par[k][i]<0) par[k+1][i]=-1;
            else{
                par[k+1][i]=par[k][par[k][i]];
                mn[k+1][i]=min(mn[k][i],mn[k][par[k][i]]);
            }
        }
    }
}
int lca(int a,int b){
    int res=inf;
    if(depth[a]>depth[b]) swap(a,b);
    for(int k=0;k<20;++k){
        if((depth[b]-depth[a]) >> k & 1){
            res=min(res,mn[k][b]);
            b=par[k][b];
        }
    }
    if(a==b) return min(res,d[a]);
    for(int k=19;k>=0;--k){
        if(par[k][a] !=par[k][b]){
            res=min(res,min(mn[k][a],mn[k][b]));
            a=par[k][a];
            b=par[k][b];
        }
    }
    return min(res,min(mn[0][a],mn[0][b]));
}

int main(){
    priority_queue<pint,vector<pint>,greater<pint> > pq;
    int m,k,q;
    cin>>n>>m>>k>>q;
    int a,b,l;
    edge ed;
    for(int i=0;i<m;++i){
        cin>>a>>b>>l;
        ed.dst=b-1;ed.weight=l;road[a-1].push_back(ed);
        ed.dst=a-1;ed.weight=l;road[b-1].push_back(ed);
    }
    for(int i=0;i<n;++i) d[i]=inf;
    for(int i=0;i<k;++i){
        cin>>a;d[a-1]=0;
        pq.push(make_pair(0,a-1));
    }
    while(!pq.empty()){
        pint pi=pq.top();pq.pop();
        int t=pi.second;
        for(vector<edge>::iterator it=road[t].begin();it!=road[t].end();++it){
            if(d[it->dst]>d[t]+it->weight){
                d[it->dst]=d[t]+it->weight;
                pq.push(make_pair(d[it->dst],it->dst));
            }
        }
    }
    for(int i=0;i<n;++i){
        for(int j=0;j<road[i].size();++j){
            r2.push_back(make_pair(min(d[i],d[road[i][j].dst]),make_pair(i,road[i][j].dst)));
        }
    }
    sort(r2.begin(),r2.end(),greater<ppi>());
    UnionFind uf;
    uf.init(n);

    for(int i=0;i<r2.size();++i){
        ppi rr=r2[i];
        if(!uf.same(rr.second.first,rr.second.second)){
            uf.unite(rr.second.first,rr.second.second);
            road2[rr.second.first].push_back(rr.second.second);
            road2[rr.second.second].push_back(rr.second.first);
        }
    }
    lca_init();
    for(int i=0;i<q;i++){
    cin>>a>>b;
    cout<<lca(a-1,b-1)<<endl;
  }
    return 0;
}

Measured memory_bytes: 36516