#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;
// 04:15:05


struct Edge { 
  int src,dst,w; 
  bool operator < ( const Edge& edge ) const {
    if( w != edge.w ) return w > edge.w;
    if( src != edge.src ) return src < edge.src;
    return dst < edge.dst;
  }
};

struct Data {
  int cur,w;
  bool operator < ( const Data& data ) const {
    if( w != data.w ) return w > data.w;
    return cur < data.cur;
  }
};

const int IINF = INT_MAX;
const int MAX_V = 100010;
int V,E,K,Q;
vector<Edge> G[MAX_V];
bool isFestival[MAX_V];
int score[MAX_V];

void dijkstraForScoring(){
  priority_queue<Data> Q;
  rep(i,V) {
    if( isFestival[i] ) {
      score[i] = 0;
      Q.push((Data){i,0});
    } else {
      score[i] = IINF;
    }
  }
  while( !Q.empty() ){
    Data data = Q.top(); Q.pop();
    rep(i,(int)G[data.cur].size()){
      Edge &e = G[data.cur][i];
      if( score[e.dst] > data.w + e.w ) {
        score[e.dst] = data.w + e.w;
        Q.push((Data){e.dst,score[e.dst]});
      }
    }
  }
}

int par[MAX_V];

int find(int x){
  if( x == par[x] ) return x;
  return par[x] = find(par[x]);
}

void unit(int x,int y){
  x = find(x), y = find(y);
  if( x != y ) par[x] = y;
}

struct HLEdge { int to,w,index; };
vector<HLEdge> HLG[MAX_V];
vector<int> costs,toNode;

void reconstructG(){
  rep(i,V) par[i] = i;
  vector<Edge> edges;
  rep(i,V) rep(j,(int)G[i].size()) edges.push_back((Edge){G[i][j].src,G[i][j].dst,min(score[G[i][j].src],score[G[i][j].dst])});
  sort(edges.begin(),edges.end());
  
  vector<Edge> spanning_tree;
  rep(i,(int)edges.size()){
    int src = edges[i].src, dst = edges[i].dst;
    if( find(src) != find(dst) ) {
      unit(src,dst);
      spanning_tree.push_back(edges[i]);
    }
  }
  rep(i,V) G[i].clear();
  assert( (int)spanning_tree.size() == V-1 );
  rep(i,(int)spanning_tree.size()) {
    Edge &e = spanning_tree[i];
    HLG[e.src].push_back((HLEdge){e.dst,e.w,i});
    HLG[e.dst].push_back((HLEdge){e.src,e.w,i});
    //costs.push_back(e.w);
  }
}

void prepare(){
  dijkstraForScoring();
  reconstructG();
}

// HLD -- begin

typedef pair<int,int> ii;

class LCA_RMQ {
private:
  int limit,N;
  vector<ii> dat;
public:
  void init(int n_){
    N = n_;
    dat.clear();
    limit = 1;
    while(limit<n_) limit *= 2;
    dat.resize(2*limit);
    rep(i,2*limit-1) dat[i] = ii(IINF,IINF);
  }
  ii _build(int cur,int L,int R,const vector<ii> &buf) {
    if( !( 0 <= cur && cur < 2 * limit) ) return ii(IINF,IINF);
    if( L == R-1 ) {
      if( L >= N ) return ii(IINF,IINF);
      dat[cur] = buf[L];
    } else {
      ii vl = _build(cur*2+1,L,(L+R)/2,buf);
      ii vr = _build(cur*2+2,(L+R)/2,R,buf);
      dat[cur] = min(vl,vr);
    }
    return dat[cur];
  }
  void build(const vector<ii> &buf){ _build(0,0,limit,buf); }

  void update(int k,ii a){
    k += limit-1;
    dat[k] = a;
    while(k > 0){
      k = (k-1)/2;
      dat[k] = (dat[k*2+1].first>dat[k*2+2].first?dat[k*2+2]:dat[k*2+1]);
    }
  }
  ii _query(int a,int b,int k,int l,int r){
    if(r<=a || b<=l)return ii(IINF,-1);
    else if(a<=l && r<=b)return dat[k];
    ii vl = _query(a,b,k*2+1,l,(l+r)/2);
    ii vr = _query(a,b,k*2+2,(l+r)/2,r);
    return min(vl,vr);
  }
  ii query(int a,int b){ return _query(a,b,0,0,limit); }
};

int root;
vector<int> id,vs,depth;

void LCA_dfs(int v,int p,int d,int &k){
  id[v] = k;
  vs[k] = v;
  depth[k++] = d;
  for(int i=0;i<(int)HLG[v].size();i++){
    if(HLG[v][i].to != p){
      LCA_dfs(HLG[v][i].to,v,d+1,k);
      vs[k] = v;
      depth[k++] = d;
    }
  }
}

void LCA_init(int V,LCA_RMQ &rmq){
  root = 0;
  vs.clear();
  vs.resize(V*2,0);
  depth.clear();
  depth.resize(V*2,0);
  id.clear();
  id.resize(V);
  int k = 0;
  LCA_dfs(root,-1,0,k);
  rmq.init(k+1);  
  vector<ii> tmp;
  rep(i,k) tmp.push_back(ii(depth[i],vs[i]));
  rmq.build(tmp);
}

int lca(int u,int v,LCA_RMQ &rmq){ return rmq.query(min(id[u],id[v]),max(id[u],id[v])+1).second; }

class RMQ{
private:
  int limit,N;
  vector<int> dat;
public:
  void init(int n_){
    N = n_;
    limit = 1;
    while(limit<n_)limit*=2;
    dat.clear();
    dat.resize(2*limit,IINF);
  }
  
  int _build(int cur,int L,int R,const vector<int> &buf){
    if( !( 0 <= cur && cur < 2*limit ) ) return IINF;
    if( L == R-1 ) {
      if( L >= N ) return IINF;
      dat[cur] = buf[L];
    } else {
      int vl = _build(cur*2+1,L,(L+R)/2,buf);
      int vr = _build(cur*2+2,(L+R)/2,R,buf);
      dat[cur] = min(vl,vr);
    }
    return dat[cur];
  }

  void build(const vector<int> &buf){ _build(0,0,limit,buf); };

  void update(int k,int a){
    k += limit-1;
    dat[k] = a;
    while(k > 0){
      k = (k-1)/2;
      dat[k] = min(dat[k*2+1],dat[k*2+2]);
    }
  }
 
  int _query(int a,int b,int k,int l,int r){
    if(r<=a || b<=l)return IINF;
    else if(a<=l && r<=b)return dat[k];
    int vl = _query(a,b,k*2+1,l,(l+r)/2);
    int vr = _query(a,b,k*2+2,(l+r)/2,r);
    return min(vl,vr);
  }

  int query(int a,int b){ return _query(a,b,0,0,limit); }
};

int chainNumber;
vector<int> subsize;
vector<int> chainID;
vector<int> headID;
vector<int> baseArray;
vector<int> posInBase;
vector<int> parent;

void HLD_dfs(int cur,int prev){
  parent[cur] = prev;
  rep(i,(int)HLG[cur].size()){
    int to = HLG[cur][i].to;
    if( to == prev ) continue;
    HLD_dfs(to,cur);
    subsize[cur] += subsize[to];
  }
}

void HLD(int cur,int prev,int &ptr){
  
  if( headID[chainNumber] == -1 ) headID[chainNumber] = cur;
  chainID[cur] = chainNumber;
  baseArray[ptr] = costs[cur];
  posInBase[cur] = ptr++;
  
  int maxi = -1;
  rep(i,(int)HLG[cur].size()) {
    int to = HLG[cur][i].to;
    if( to == prev ) continue;
    if( maxi == -1 || subsize[to] > subsize[maxi] ) maxi = to;
  }

  if( maxi != -1 ) HLD(maxi,cur,ptr);
  
  rep(i,(int)HLG[cur].size()){
    int to = HLG[cur][i].to;
    if( to == prev || to == maxi ) continue;
    ++chainNumber;
    HLD(to,cur,ptr);
  }

}

void HLD_init(){
  chainNumber = 0;

  subsize.clear();
  chainID.clear();
  headID.clear();
  baseArray.clear();
  posInBase.clear();
  parent.clear();

  subsize.resize(V,1);
  chainID.resize(V,-1);
  headID.resize(V,-1);
  baseArray.resize(V,IINF);
  posInBase.resize(V,-1);
  parent.resize(V,-1);

  HLD_dfs(0,-1);
  int ptr = 0;
  HLD(0,-1,ptr);

}

int _Query(int s,int t,RMQ &rmq){
  if( s == t ) return IINF;
  int chain_s, chain_t = chainID[t], mini = IINF;
  while( 1 ){
    chain_s = chainID[s];
    if( chain_s == chain_t ) {
      int ps = posInBase[s], pt = posInBase[t];
      if( s == t ) return mini;
      if( ps < pt ) mini = min(mini,rmq.query(ps,pt));
      else          mini = min(mini,rmq.query(pt+1,ps+1));
      return mini;
    } else {
      int head = headID[chain_s];
      int ps = posInBase[s], ph = posInBase[head];
      mini = min(mini,rmq.query(min(ps,ph),max(ps,ph)+1));
      s = parent[head];
    }
  }
  return mini;
}

int Query(int s,int t,RMQ &rmq,LCA_RMQ &lca_rmq){
  int ancestor = lca(s,t,lca_rmq);
  return min(_Query(s,ancestor,rmq),_Query(t,ancestor,rmq));
}
void Change(int position,int value,RMQ &rmq){ // ???????????????????????????????????????????????????????????´??????????????´????????? posInBase[position]??¨????????°?????????????????????
  position = posInBase[toNode[position]];
  rmq.update(position,value);
}

void MEG_dfs(int cur,int prev){
  rep(i,(int)HLG[cur].size()){
    int to = HLG[cur][i].to;
    if( prev == to ) continue;
    costs[to] = HLG[cur][i].w;
    toNode[HLG[cur][i].index] = to;
    MEG_dfs(to,cur);
  }
}

// HLD -- end

int main(){
  scanf("%d %d %d %d",&V,&E,&K,&Q);
  {
    int s,t,w;
    rep(i,E){
      scanf(" %d %d %d",&s,&t,&w);
      --s, --t;
      G[s].push_back((Edge){s,t,w});
      G[t].push_back((Edge){t,s,w});
    }
  }
  {
    int s;
    rep(i,K) {
      scanf(" %d",&s);
      --s;
      isFestival[s] = true;
    }
  }

  toNode.clear();
  toNode.resize(V,-1);
  costs.clear();
  costs.resize(V,IINF);
  prepare();
  MEG_dfs(0,-1);
  HLD_init();
  RMQ rmq;
  rmq.init(V);
  rmq.build(baseArray);
  LCA_RMQ lca_rmq;
  LCA_init(V,lca_rmq);

  {
    int s,t;
    rep(_,Q){
      scanf(" %d %d",&s,&t);
      --s, --t;
      printf("%d\n",Query(s,t,rmq,lca_rmq));
    }
  }
  return 0;
}

Measured memory_bytes: 32484