#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define rep(i, n) for(int i = 1; (i) <= (n); ++i)
#define forn(i, l, r) for(int i = (l); i <= (r); ++i)
#define ford(i, r, l) for(int i = (r); i >= (l); --i)
#define FOR(i, n) for(int i = 0; i < (n); ++i)
#define FORD(i, n) for(int i = ((n) - 1); i >= 0; --i)
#define fi first
#define se second
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define endl "\n"
#define task "walk"
#define sz(a) int(a.size())
#define C(x, y) make_pair(x, y)
#define all(a) (a).begin(), (a).end()
#define bit(i, mask) (mask >> i & 1)

template<typename T> bool maximize(T &res, const T &val) { if (res < val){ res = val; return true; }; return false; }
template<typename T> bool minimize(T &res, const T &val) { if (res > val){ res = val; return true; }; return false; }

inline int readInt()       {char c;while(c=getchar(),c!='-'&&(c<'0'||c>'9'));bool sign=(c=='-');if(sign)c=getchar();int n=c-'0';while(c=getchar(),c>='0'&&c<='9')n=10*n+c-'0';return(!sign)?n:-n;}
inline ll readLong()       {char c;while(c=getchar(),c!='-'&&(c<'0'||c>'9'));bool sign=(c=='-');if(sign)c=getchar();ll  n=c-'0';while(c=getchar(),c>='0'&&c<='9')n=10*n+c-'0';return(!sign)?n:-n;}
inline string readString() {char c;while(c=getchar(),c==' '||c=='\n'||c=='\t');string s({c});while(c=getchar(),c!=EOF&&c!=' '&&c!='\n'&&c!='\t')s+=c;return s;}

const int N = 1e5 + 3;
const int M = 5e5;
const int LOG = 16;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 33;
const int S = 375;

int n, m, k, q;

int D[N], b[N];
vector<pii> g[N];
int par[N], sz[N];

int root(int u) {return u == par[u] ? u : par[u] = root(par[u]);}
bool union_set(int u, int v)
{
    if((u = root(u)) == (v = root(v))) return 0;
    if(sz[u] < sz[v]) swap(u, v);
    par[v] = u;
    sz[u] += sz[v];

    return 1;
}
void Dijkstra()
{
    priority_queue<pii, vector<pii>, greater<pii>> q;
    rep(i, n)
    {
        if(b[i]) D[i] = 0, q.push({0, i});
        else D[i] = INF;
    }
    while(sz(q))
    {
        pii tmp = q.top();
        q.pop();
        int dist = tmp.fi, u = tmp.se;
        if(D[u] != dist) continue;

        for(auto &[v, w] : g[u])
            if(minimize(D[v], D[u] + w))
            q.push({D[v], v});
    }
}

int tin[N], tout[N], timedfs = 0;
int up[N][LOG + 1], min_edge[N][LOG + 1];

void dfs(int u, int p = 1, int w = INF)
{
    tin[u] = ++timedfs;
    up[u][0] = p;
    min_edge[u][0] = w;
    forn(i, 1, LOG)
    {
        up[u][i] = up[up[u][i - 1]][i - 1];
        min_edge[u][i] = min(min_edge[u][i - 1], min_edge[up[u][i - 1]][i - 1]);
    }

    for(auto &[v, wei] : g[u])
    if(v != p)
    {
        dfs(v, u, wei);
    }
    tout[u] = ++timedfs;
}

bool is_anc(int u, int v)
{
    return tin[u] <= tin[v] && tout[v] <= tout[u];
}

int get(int u, int v)
{
    int res = INF;
    if(is_anc(u, v)) swap(u, v);

    ford(i, LOG, 0) if(!is_anc(up[u][i], v))
        res = min(res, min_edge[u][i]), u = up[u][i];
    if(!is_anc(u, v))
        res = min(res, min_edge[u][0]), u = up[u][0];

    ford(i, LOG, 0) if(!is_anc(up[v][i], u))
        res = min(res, min_edge[v][i]), v = up[v][i];
    if(!is_anc(v, u))
        res = min(res, min_edge[v][0]);
    return res;
}

array<int, 3> e[M];

void solve()
{
    cin >> n >> m >> k >> q;
    rep(i, m)
    {
        int u, v, w;
        cin >> u >> v >> w;
        g[u].pb({v, w});
        g[v].pb({u, w});
        e[i] = {w, u, v};
    }
    rep(i, k)
    {
        int x;
        cin >> x;
        b[x] = 1;
    }

    Dijkstra();
    rep(i, n) g[i].clear();

    rep(i, m)
        e[i][0] = min(D[e[i][1]], D[e[i][2]]);
    sort(e + 1, e + 1 + m);
    rep(i, n) par[i] = i, sz[i] = 1;
    ford(i, m, 1) if(union_set(e[i][1], e[i][2]))
    {
        g[e[i][1]].pb({e[i][2], e[i][0]});
        g[e[i][2]].pb({e[i][1], e[i][0]});
    }
    dfs(1);
    rep(i, q)
    {
        int u, v;
        cin >> u >> v;
        cout << get(u, v) << endl;
    }
}

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int TC = 1;

    if(fopen(task".inp", "r"))
    {
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }

//    if(fopen("note.inp", "r"))
//    {
//        freopen("note.inp", "r", stdin);
//        freopen("note.out", "w", stdout);
//    }

    while(TC--)
    {
        solve();
        cout << endl;
    }

    return 0;
}
