#include<iostream>
#include<climits>
#include<cassert>
#include<algorithm>
#include<cassert>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

const int inf = 1000000000;

class st{
public:
  int now,cost;
  bool operator<(const st & a)const{
    return cost > a.cost;
  }
};

struct Edge{
  int f,t,cost;
  bool operator<(const Edge & a)const{
    return cost > a.cost;
  }
};

const int N = 100000;
/*
  ç¥­ããè¡ããã¦ãããã¼ãã¾ã§ã®æç­è·é¢ãåãã¼ãã«ã¤ãã¦è¨ç®ããã
  ç¥­ããè¡ããã¦ãããã¼ããè¦ç¹ã¨ãã¦æç­çµè·¯ãæ±ããã°è¯ãã
  ElogE
*/
int cost[N];//ä¸çªè¿ãç¥­ãã¸ã®ã³ã¹ã
bool ism[N];//ç¥­ãï¼
vector<Edge> d_edge[N];
void dijkstra(int n){
  rep(i,n)cost[i] = inf;
  priority_queue<st> Q;
  rep(i,n){
    if (ism[i]){
      cost[i] = 0;
      Q.push((st){i,0});
    }
  }
  while(!Q.empty()){
    st now = Q.top();Q.pop();
    if (cost[now.now] != now.cost)continue;
    rep(i,(int)d_edge[now.now].size()){
      int next = d_edge[now.now][i].t;
      int nec  = d_edge[now.now][i].cost + cost[now.now];
      if (cost[next] > nec){
	cost[next] = nec;
	Q.push((st){next,nec});
      }
    }
  }
}
//ããã¾ã§dijkstra
//ããããMST
class DisjointSet{
public:
 vector<int> rank,p;
 DisjointSet(){}
 DisjointSet(int size){
   rank.resize(size,0);
   p.resize(size,0);
 }
 void make_set(int x){
   p[x]=x;
   rank[x]=0;
 }
 void merge(int x,int y){
   link(find_set(x),find_set(y));
 }
 void link(int x,int y){
   if (rank[x]>rank[y]){
     p[y]=x;
   }else {
     p[x]=y;
     if ( rank[x] ==rank[y])rank[y]+=1;
   }
 }
 int find_set(int x){
   if (x != p[x])p[x]=find_set(p[x]);
   return p[x];
 }
};

/*
  æ±ããæç­çµè·¯ããã¨ã«æå°å¨åæ¨ãæ§ç¯ããã
  ãã®æã¨ãã¸ã®éã¿ã¯ãè¾ºã«æ¥ç¶ãã¦ãï¼ã¤ã®ç¹ã®æç­è·é¢ã®ãã¡å°ããæ¹ã¨ããã
  ããããçç±ã¯ããã®ã¨ãã¸ãéã£ãã¨ãã«ãç¥­ãã®å ´æçµµã®æå°è·é¢ãï¼ã¤ã®ãã¡ã®å°ããæ¹ãã¨ãããã§ããã
  ï¼ãã£ã¨å°ããå ´æãéãæã¨ããã®ã¯ãããã©ã¾ãããã¦ãããï¼
 */
vector<Edge> m_edge;
vector<Edge> edge[N];
vector<int> s_edge[N*2];//æå°å¨åæ¨ã®æ§ç¯ä»®å®ãã°ã©ãã«ããã
int weight[N*2];//æå°å¨åæ¨ã®æ§ç¯éç¨ã§éã¿ãè¨é²ããã
void mst(int n){
  vector<int> idmemo(n);//
  int lastid = 0;//ä»ã¾ã§ä½¿ã£ãã¨ãã¸ã®æ¬æ°

  DisjointSet dj(n);
  rep(i,n){
    dj.make_set(i);
    idmemo[i] = i;
  }
  rep(i,(int)m_edge.size()){
    m_edge[i].cost = min(cost[m_edge[i].f],cost[m_edge[i].t]);
  }
  sort(m_edge.begin(),m_edge.end());

  rep(i,(int)m_edge.size()){
    int f = m_edge[i].f,t = m_edge[i].t,c=m_edge[i].cost;
    if (dj.find_set(f) != dj.find_set(t)){
      int idf = idmemo[dj.find_set(f)],idt=idmemo[dj.find_set(t)];
      int cur = n + lastid;
      s_edge[cur].push_back(idf);
      s_edge[cur].push_back(idt);
      weight[cur] = c;
      dj.merge(f,t);
      edge[min(f,t)].push_back((Edge){f,t,c});
      idmemo[dj.find_set(f)] = cur;
      lastid++;
    }
  }
}

const int SEGT_SIZE = (1<<19);//number of element
const int M = 2*N;//required memory 
const int MAX_VALUE=INT_MAX;//maximum possible value;
int segt[M];//init with MAX_VALUE
int inp[SEGT_SIZE];
 
void update(int value,int pos,int n){
  int index=n-1+pos;
  segt[index]=value;//[pos,pos]
  while(index>0){
    index=(index-1)/2;
    segt[index]=min(segt[index*2+1],segt[index*2+2]);
  }
}
 
//children of now
//left now*2+1
//right now*2+2
//find[ql,qr] from [l,r] (definition of l and r is different from ant books)
int query(int l,int r,int now,int ql,int qr){
  if (l == ql && r == qr){
    return segt[now];
  }
  int midr=(l+r)/2,midl=midr+1;//right
  //child (l-midr) and (midl-r)
  int ret=MAX_VALUE;
  if (ql <= midr)ret=min(ret,query(l,midr,now*2+1,ql,min(qr,midr)));
  if (midl <= qr)ret=min(ret,query(midl,r,now*2+2,max(midl,ql),qr));
  return ret;
}
//end of library
 
void init(int n){
  rep(i,n)segt[i]=MAX_VALUE;
}

/*
  MSTã®æ§ç¯ä»®å®ãã°ã©ãã«ãããã®ã«ã¤ãã¦ãåã®ã°ã©ãã¨ãã¸ããã¼ãåãããã®ã«çªå·ãæ¯ãåããã
  ããªããäºåæ¨ã«ãªã£ã¦ãã¦ãä¸ã¤ç®ã®ã¨ãã¸ããã©ã£ã¦ããã¨ãã«ä¿æãã¦ããidããã®ãã¼ãã®idã«ããã
*/

int tid[N];
void buildSegtree(int now,int &id,const int segtN){
  if (s_edge[now].size() == 0){
    tid[now] = id;
    return;
  }
  rep(i,s_edge[now].size()){
    int next = s_edge[now][i];
    buildSegtree(next,id,segtN);
    if (i == 0){//ã»ã°ã¡ã³ãããªã¼ãã¢ãããã¼ãããã
      update(weight[now],id,segtN);
      id++;
    }
  }
} 

void solve(int n,int q){
  /*
    MSTã®æ§ç¯éç¨ãäºåæ¨ã«ãããã®ãä½¿ã£ã¦ãLCAã§ããããã«ããã
  */
  int segtN=1;
  for(segtN = 1;segtN < n;segtN*=2);
  init(segtN);
  //build
  int id = 0;
  buildSegtree(n+n-2,id,segtN);
  //solve
  rep(i,q){
    int f,t;
    cin>>f>>t;
    f--;t--;
    if (tid[f] > tid[t])swap(f,t);
    int ans = query(0,segtN-1,0,tid[f],tid[t]-1);
    cout << ans << endl;
  }
}

/**/
main(){
  int n,m,k,q;
  while(cin>>n>>m>>k>>q && n){
    //åæå for dijkstra
    rep(i,n){
      d_edge[i].clear();
      ism[i] = false;
    }
    //åæå for MST
    m_edge.clear();
    rep(i,n){
      edge[i].clear();
    }

    //åæå for ã»ã°ã¡ã³ãããªã¼
    rep(i,2*n){
      s_edge[i].clear();
      weight[i] = -1;
    }

    rep(i,m){
      int f,t,c;
      cin>>f>>t>>c;
      f--;t--;
      d_edge[f].push_back((Edge){f,t,c});
      d_edge[t].push_back((Edge){t,f,c});

      m_edge.push_back((Edge){f,t,c});
    }
    rep(i,k){//ç¥­ããè¡ããã¦ããå ´æ
      int tmp;
      cin>>tmp;
      ism[tmp-1] = true;
    }
    
    dijkstra(n);
    //rep(i,n){cout << i+1 <<" " << cost[i] << endl;}
    //ããã¾ã§ã§ãåãã¼ãã«ã¤ãã¦ãç¥­ããè¡ã£ã¦ãè¡ã¾ã§ã®æç­è·é¢ãè¨ç®ããã

    //ããããMST
    mst(n);


    //ããã§è§£ã
    solve(n,q);
  }
  return false;
}

Measured memory_bytes: 22000