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

using P = pair<int, int>;

class union_find {
public:
    union_find(int n)
        : par_(n, -1)
    {}
    void init(int n) {
        par_.assign(n, -1);
    }

    int root(int x) {
        return par_[x] < 0 ? x : par_[x] = root(par_[x]);
    }

    bool unite(int x, int y) {
        x = root(x); y = root(y);
        if(x == y) {
            return false;
        } else {
            if(par_[x] < par_[y]) {
                par_[x] += par_[y];
                par_[y] = x;
            } else {
                par_[y] += par_[x];
                par_[x] = y;
            }
            return true;
        }
    }

    bool same(int x, int y) {
        return root(x) == root(y);
    }

    int size(int x) {
        return -par_[root(x)];
    }

private:
    std::vector<int> par_;
};


struct edge {
    int from, to, cost;
    bool operator<(edge const& other) const {
        return cost > other.cost;
    }
};

using edges = vector<edge>;
using graph = vector<edges>;


class lca {
public:
    lca(vector<vector<int>>& g, int root)
        : V(g.size()),
          log_V(0),
          depth_(V, 0)
    {
        for(int v=V; v>0; v /= 2) {
            ++log_V;
        }
        parent.assign(log_V, std::vector<int>(V, 0));
        dfs(g, root, -1, 0);
        for(int k=0; k+1 < log_V; ++k) {
            for(int v=0; v<V; ++v) {
                if(parent[k][v] < 0) {
                    parent[k+1][v] = -1;
                } else {
                    parent[k+1][v] = parent[k][parent[k][v]];
                }
            }
        }
    }

    void dfs(vector<vector<int>> const& g, int v, int p, int d) {
        parent[0][v] = p;
        depth_[v] = d;
        for(int i=0; i<g[v].size(); ++i) {
            if(g[v][i] != p) {
                dfs(g, g[v][i], v, d+1);
            }
        }
    }

    int depth(int v) const {
        return depth_[v];
    }

    int query(int u, int v) {
        if(depth_[u] > depth_[v]) {
            std::swap(u, v);
        }
        for(int k=0; k<log_V; ++k) {
            if((depth_[v] - depth_[u]) >> k & 1) {
                v = parent[k][v];
            }
        }
        if(u == v) {
            return u;
        }
        for(int k=log_V - 1; k>=0; --k) {
            if(parent[k][u] != parent[k][v]) {
                u = parent[k][u];
                v = parent[k][v];
            }
        }
        return parent[0][u];
    }

private:
    int V, log_V;
    std::vector<vector<int>> parent;
    std::vector<int> depth_;
};


constexpr int INF = 1e9;

int main() {
    int N, M, K, Q;
    cin >> N >> M >> K >> Q;
    graph g(N);
    for(int i=0; i<M; ++i) {
        int a, b, l;
        cin >> a >> b >> l;
        a--; b--;
        g[a].push_back((edge){a, b, l});
        g[b].push_back((edge){b, a, l});
    }

    vector<int> d(2*N, INF);
    priority_queue<P, vector<P>, greater<P>> que;
    for(int i=0; i<K; ++i) {
        int f;
        cin >> f;
        f--;
        d[f] = 0;
        que.push(make_pair(0, f));
    }
    while(!que.empty()) {
        P p = que.top();
        que.pop();
        int v = p.second;
        if(d[v] < p.first) {
            continue;
        }
        for(auto& e : g[v]) {
            if(d[e.to] > d[v] + e.cost) {
                d[e.to] = d[v] + e.cost;
                que.push(make_pair(d[e.to], e.to));
            }
        }
    }

    edges es;
    for(int i=0; i<N; ++i) {
        for(auto& e : g[i]) {
            if(i < e.to) {
                es.push_back((edge){i, e.to, min(d[i], d[e.to])});
            }
        }
    }
    sort(es.begin(), es.end());

    union_find uf(N);
    vector<vector<int>> tree(2*N);
    int new_id = N;
    vector<int> id(N);
    for(int i=0; i<N; ++i) {
        id[i] = i;
    }
    for(auto& e : es) {
        int a = uf.root(e.from), b = uf.root(e.to);
        if(uf.unite(a, b)) {
            tree[new_id].push_back(id[a]);
            tree[new_id].push_back(id[b]);
            d[new_id] = min(d[id[a]], d[id[b]]);
            id[uf.root(a)] = new_id;
            new_id += 1;
        }
    }

    lca l(tree, new_id-1);
    for(int i=0; i<Q; ++i) {
        int s, t;
        cin >> s >> t;
        s--; t--;
        cout << d[l.query(s, t)] << endl;
    }
}


Measured memory_bytes: 42464