#include <bits/stdc++.h>

using namespace std;

#define int long long
//#pragma warning(disable : 4996)
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#pragma optimizer ("Ofast")

int inf = 1000000000000000000l;
vector<int> d, ans;
vector<vector<int> > dsu;
vector<map<int, int>> t;

struct cmp{
    bool operator() (const int &a, const int &b){
        // returns true if a should go before b
        if (d[a] > d[b]) return true;
        return false;
    }
};

bool comp(vector<int> &o1,vector<int> &o2) {
        if (o1[0] >= o2[0]) return false;
        return true;
}

int gt(int u) {
    int k = u;
    while (u != dsu[u][0]) u = dsu[u][0];
    while (k != dsu[k][0]) {
        int p = dsu[k][0];
        dsu[k][0] = u;
        k = p;
    }
    return u;
}

void mer(int u, int v, int w) {
    u = gt(u);
    v = gt(v);
    if (u != v) {
        if (dsu[u][1] > dsu[v][1]) {
            dsu[v][0] = u;
            while (!t[v].empty()) {
                int k = t[v].begin() -> first;
                if (t[v][k]==1&&t[u][k]==1) {
                    t[u].erase(k);
                    ans[k] = w;
                }else t[u][k] = 1;
                t[v].erase(k);
            }
        } else {
            dsu[u][0] = v;
            while (!t[u].empty()) {
                int k = t[u].begin()->first;
                if (t[u][k]==1&&t[v][k]==1) {
                    t[v].erase(k);
                    ans[k] = w;
                }else t[v][k]=1;
                t[u].erase(k);
            }
            if (dsu[u][1] == dsu[v][1]) dsu[v][1]++;
        }
    }
}

main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //freopen("H.in", "r", stdin);
    //freopen("H.out", "w", stdout);
    int n, m, k, q;
    cin >> n >> m >> k >> q;
    vector<vector<int> > edge(n),w(n);
    for (int i = 0; i < m; i++) {
        int a, b, weight;
        cin >> a >> b >> weight;
        a--;
        b--;
        edge[a].push_back(b);
        edge[b].push_back(a);
        w[a].push_back(weight);
        w[b].push_back(weight);
    }
    d.resize(n);
    for (int i = k; i < n; i++) {
        d[i] = inf;
    }
    priority_queue<pair<int,int>> pq;
    for (int i = 0; i < k; ++i) {
        pq.push({d[i],i});
    }
    while (!pq.empty()) {
        int a = pq.top().second;
        int ld = pq.top().first;
        pq.pop();
        if(ld!=d[a])continue;
        for (int i = 0; i < edge[a].size(); ++i) {
            int b = edge[a][i];
            long ok = w[a][i];
            long r = d[a] + ok;
            if (r < d[b]) {
                d[b] = r;
                pq.push({d[b],b});
            }
        }
    }
    //for(int i = 0;i < n;++i)cout << i << " d[i]: " << d[i] << "\n";
    vector<vector<int> > mas(m, vector<int>(3,0));
    int c = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < w[i].size(); ++j) {
            if (i < edge[i][j]) {
                int p = w[i][j];
                p += d[i] + d[edge[i][j]];
                mas[c][0] = p;
                mas[c][1] = i;
                mas[c][2] = edge[i][j];
                c++;
            }
        }
    }
    sort(mas.begin(),mas.end(),comp);
    //for(int i = 0;i < m;++i){
    //    cout << mas[i][1] << " " << mas[i][2] << " " << mas[i][0] << "\n";
    //}
    dsu.resize(n);
    for(int i = 0;i < n;++i)dsu[i].resize(2);
    for (int i = 0; i < n; i++) {
        dsu[i][0] = i;
        dsu[i][1] = 1;
    }
    t.resize(n);
    ans.resize(q);
    for (int i = 0; i < q; i++) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        t[u][i] = 1;
        t[v][i] = 1;
    }
    for (int i = 0; i < m; i++) {
        int u = mas[i][1];
        int v = mas[i][2];
        mer(u, v, mas[i][0]);
    }
    for (int i = 0; i < q; i++) {
        cout << (ans[i]) << "\n";
    }
    return 0;
}
