#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <string>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
#include <cassert> 
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(),(x).end())
#define all(x) (x).begin(),(x).end()
#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define repn(i,a,n) for(int (i)=(a);(i)<(int)(n);(i)++)
#define EQ(a,b) (abs((a)-(b))<eps)

struct edge{int from,to,cost;};
int N,M,K,Q;
vector<edge> g[100100];
vector<edge> all;
int d[100100];
bool f[100100];
void dijkstra(){
    priority_queue<P,vector<P>,greater<P> > q;
    for(int i=0;i<N;i++){
        d[i]=INF;
        if(f[i]){
            d[i]=0;
            q.push(mp(0,i));
        }
    }
    while(!q.empty()){
        P a=q.top();
        q.pop();
        int v=a.sec;
        if(d[v]<a.fi)continue;
        for(int i=0;i<g[v].size();i++){
            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(mp(d[g[v][i].to],g[v][i].to));
            }
        }
    }
    return;
}
bool comp(const edge& x,const edge& y){
    return x.cost > y.cost;
}

// Link Cut Tree
// ??¨???Heavy-Light decomposition?????????path???splay??¨(??????????????¨)??§??????
// ???splay??¨????????????????????????????????????????????????
// root??\??????spaceships,road_development??§verify???

// LinkCutTree?????¬??\???(?????????????????????)????????¨?????±???????????§???????????????????????¨?????±?????????
// link???cut??????????????¨?????±???evert??????????????¨???

// path?????????????§?????????????????????????A??????B??????path???????????????????????????????????????
// A???evert??????B???expose???????????¨??§A??¨B?????????splay??¨????????????????§?????????????
// (?????????,B???expose????????£???splay??¨????????¨?????£?????????)
// ?????£?????????splay??¨???????????????Segtree????§????????????????????????????????????°(?????¶????????????),
// ?????????path?????????????????¨????????????????????????

// ???????????¨???:
// ????????§???path???????????????????°????????±???????

struct Node{
	Node *pp,*lp,*rp;
	int id;             // ???????????? ??????????????????????????????????????¨???	
	int size;           // ??????????±???????splay??¨????????????????????\??????????????°
	bool rev;           // ?????¢????????°
	
	typedef int val_t;  // ??????long long????????´???????????¨???
	
	struct Data{
		val_t val,mini;
	}data;
	
	
	Node(int id):pp(NULL),lp(NULL),rp(NULL),id(id),size(1){}
	
	Node(int id,val_t v):pp(NULL),lp(NULL),rp(NULL),id(id){
		data.val = v;
		data.mini = v;
	}
	void update(){ //????????????size,data?????´??°??????
		if(this==NULL)return;
		size = 1;
		data.mini = data.val;
		if(lp!=NULL){
			data.mini = min(lp->data.mini,data.mini);
			size += lp->size;
		}
		if(rp!=NULL){
			data.mini = min(rp->data.mini,data.mini);
			size += rp->size;
		}
		return;
	}
	void toggle(){
		assert(this!=NULL);
		swap(lp,rp);
		rev ^= true;
	}
	void push(){
		// ?????¶????????¨rev????????°????????¬????????????
		// ????????????rev????????????????????¶?????????????????¨???????????????
		bool lch = (lp!=NULL),rch = (rp!=NULL);
		if(rev){
			if(lch){
				lp->toggle();
			}
			if(rch){
				rp->toggle();
			}
			rev = false;
		}
	}
	void push_all(){ 
		// splay??????????°????????????§push?????????
		// stack overflow??????????????§??????????????§???????????´??????
		// ??????splay????????¨???????????¨???
		if(!is_root())pp->push_all();
		push();
	}
	bool is_root(){ // splay??¨?????????
		return !pp||(pp->lp!=this&&pp->rp!=this);
	}
	void rotr(){ // splay??¨???????????¢
		Node *q=pp,*r=q->pp;
		if((q->lp=rp))rp->pp=q;
		rp=q;q->pp=this;
		q->update();
		update();
		if((pp=r)){
			if(r->lp==q)r->lp=this;
			if(r->rp==q)r->rp=this;
		}
		r->update();
	}
	void rotl(){ // splay??¨ ????????¢
		Node *q=pp,*r=q->pp;
		if((q->rp=lp))lp->pp=q;
		lp=q;q->pp=this;
		q->update();
		update();
		if((pp=r)){
			if(r->lp==q)r->lp=this;
			if(r->rp==q)r->rp=this;
		}
		r->update();
	}
	/*void splay(){ // splay????????? ??????????±???????splay??¨??????????????£?????????
		push_all();
		while(!is_root()){
			Node *q=pp;
			if(q->is_root()){
				if(q->lp==this)rotr();
				else rotl();
			}else{
				Node *r=q->pp;
				if(r->lp==q){
					if(q->lp==this){q->rotr();rotr();}
					else {rotl();rotr();}
				}else{
					if(q->rp==this){q->rotl();rotl();}
					else {rotr();rotl();}
				}
			}
		}
	}*/
	void splay(){ // stack overflow ???????????¨????????£??????????????????????????????
		push();
		while(!is_root()){
			Node *q=pp;
			if(q->is_root()){
				q->push();push();
				if(q->lp==this)rotr();
				else rotl();
			}else{
				Node *r=q->pp;
				r->push();q->push();push();
				if(r->lp==q){
					if(q->lp==this){q->rotr();rotr();}
					else {rotl();rotr();}
				}else{
					if(q->rp==this){q->rotl();rotl();}
					else {rotr();rotl();}
				}
			}
		}
	}
	void expose(){ // ???????????¨???????????????splay??¨????±????????§?????????¢??????
		// ?????????????????¨?????\???splay??¨????±????????????¨????????????
		// ????????????expose??????path????§£????????????????????????????????????path????????§????????±?????????
		// ??????????§?(lca,evert????\?)
		Node *rp=NULL;
		for(Node *p=this;p;p=p->pp){
			p->splay();
			p->rp=rp;
			p->update();
			rp=p;
		}
		splay();  // ?????????????????£????????£??¨?????¨????????????(cut??¨???link??????)
	}
	
	// ????????¨?????±?????????link,cut????????¨?????±???evert??????????????¨???
	
	void cut(){ // ???????????¨???????????????????????????cut
		expose();
		Node *p=lp;
		if(p!=NULL){
			lp=NULL;
			p->pp=NULL;
		}
	}
	void link(Node *p){ // ???????????¨????????????p???????????????(p???????????????)
		expose();       // ??¢???????????¨????±????????????????????£????link????????¨?????????????????¨??????
		p->expose();
		pp=p;
		p->rp=this;
	}
	void evert(){
		//expose??§?????????????????¨?????\???splay??¨????±????????????¨???????????????????????§OK
		expose();
		toggle();
	}
	Node* root(){ // ???????????¨?????????????????????node???????±?????????¨??????
		expose();
		Node* u = this;
		while(u->lp)u=u->lp;
		u->splay();
		return u;
	}
	Node* lca(Node *p){
		p->expose();
		expose();
		Node *ret=p;
		while(p->pp != NULL){
			//expose??§?????????????????¨?????\???splay??¨????±????????????¨???????????????????????§OK
			if(p->is_root())ret=p->pp;
			p=p->pp;
		}
		return (this==p)?ret:NULL;
	}
	val_t get(){ // ????????§???path??????????????????????°????
		expose();
		return data.mini;
	}
};
Node* nv[100005];
void input(){
    cin >> N >> M >> K >> Q;
    for(int i=0;i<M;i++){
        edge e;
        scanf("%d %d %d",&e.from,&e.to,&e.cost);
        e.from--;e.to--;
        all.pb(e);
        g[e.from].pb(e);
        swap(e.from,e.to);
        g[e.from].pb(e);
    }
    memset(f,false,sizeof(f));
    for(int i=0;i<K;i++){
        int fes;
        cin >> fes;
        fes--;
        f[fes]=true;
    }
    dijkstra();
    for(int i=0;i<all.size();i++){
        all[i].cost=min(d[all[i].from],d[all[i].to]);
    }
    sort(all.begin(),all.end(),comp);
    for(int i=0;i<N;i++)nv[i]=new Node(i,d[i]);
    for(int i=0;i<all.size();i++){
        int a=all[i].from,b=all[i].to;
        if((nv[a]->lca(nv[b]))==NULL){
        	nv[a]->evert();
        	nv[a]->link(nv[b]);
        }
    }
    for(int i=0;i<Q;i++){
        int s,t;
        cin >> s >> t;
        s--;t--;
        nv[s]->evert();
        printf("%d\n",nv[t]->get());
    }
    return;
} 

int main(){
	input();
	return 0;
}

Measured memory_bytes: 21056