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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define oset tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update> 

#define ll long long

#ifdef sarthak
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
int begtime = clock();
#else
#define trace(...)
#endif

#ifndef sarthak
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("unroll-loops")
    // #pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif

#define foreach(it,ar) for (auto it = ar.begin(); it != ar.end(); it++)
#define fort(i,v) for(auto i:v)
#define fr(i,a,b) for (ll i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (ll i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (ll i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (ll i = n - 1; i >= 0; i--)
#define fill(ar,val) rep(i,sizeof(ar)/sizeof(ll)) ar[i]=val
#define fill2(ar,val) rep(i,sizeof(ar)/sizeof(ar[0])) rep(j,sizeof(ar[0])/sizeof(ll)) ar[i][j]=val
#define fill0(ar) memset(ar,0,sizeof(ar))
#define debug(x) cout<<#x<<": "<<x<<endl

#define ld long double
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define sd2(x,y) scanf("%d %d",&x,&y)
#define slld2(x,y) scanf("%lld %lld",&x,&y)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define pd2(x,y) printf("%d %d\n",x,y)
#define plld2(x,y) printf("%lld %lld\n",x,y)
#define all(ar) ar.begin(), ar.end()
#define endl '\n'
#define sz(x) (int)x.size()
#define len(x) (int)x.length()

typedef pair<ll, ll> ii;
typedef pair<ii, ll> iii;
typedef vector<ii> vii;
typedef vector<ll> vi;

#define INF 1000000000000000000
#define PI 3.14159265358979323846L

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rngb(chrono::steady_clock::now().time_since_epoch().count()); // can give negative values too

const ll N = 100000;
const ll Q = 300000;

struct dis_set
{
    ll parent;
    ll si;

    dis_set(){}

    dis_set(ll x)
    {
        parent = x;
        si = 1;
    }
};

ll d[N+1];
vector<ii> ed[N+1];
vector<iii> e;
dis_set s[N+1];
vector<ll> qq[N+1];
ll arr[2*Q+1];
ll ans[Q+1];

ll find(ll x)
{
    if(s[x].parent==x)
        return x;
    return s[x].parent = find(s[x].parent);
}

void unio(ll x, ll y, ll w)
{
    x = find(x);
    y = find(y);
    if(s[x].si>s[y].si)
        swap(x,y);
    for(auto v:qq[x])
    {
        ll v2 = v^1;
        // trace(v,v2,x,y);
        if(arr[v2]==y)
            ans[v/2] = w;
        arr[v] = y;
        qq[y].pb(v);
    }
    s[y].si += s[x].si;
    s[x].parent = y;
}

void solve()
{
    ll n,m,k,q;
    cin >> n >> m >> k >> q;

    rep(i,m)
    {
        ll u,v,w;
        cin >> u >> v >> w;
        ed[u].pb({v,w});
        ed[v].pb({u,w});
    }

    set<ii> st;
    fr(i,1,n)
    {
        d[i] = INF;
    }
    fr(i,1,k)
    {
        d[i] = 0;
    }
    fr(i,1,n)
    {
        st.insert({d[i],i});
    }
    while(!st.empty())
    {
        ii xx = *(st.begin());
        st.erase(st.begin());

        for(auto v:ed[xx.ss])
        {
            if(d[v.ff]>xx.ff+v.ss)
            {
                st.erase({d[v.ff],v.ff});
                d[v.ff] = xx.ff+v.ss;
                st.insert({d[v.ff],v.ff});
            }
        }
    }

    fr(i,1,n)
    {
        for(auto v:ed[i])
        {
            ll w2 = d[i] + d[v.ff] + v.ss;
            e.pb({{w2,i},v.ff});
            // trace(i,v.ff,w2);
        }
    }

    sort(all(e));

    rep(i,q)
    {
        ll u,v;
        cin >> u >> v;
        arr[2*i] = u;
        arr[2*i+1] = v;
        qq[u].pb(2*i);
        qq[v].pb(2*i+1);
    }

    fr(i,1,n)
    {
        s[i] = dis_set(i);
    }

    for(auto vv:e)
    {
        ll w = vv.ff.ff;
        ll u = vv.ff.ss;
        ll v = vv.ss;

        if(find(u)!=find(v))
        {
            // trace(u,v,w);
            unio(u,v,w);
        }
    }

    rep(i,q)
    {
        cout << ans[i] << endl;
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout << fixed;
    cout << setprecision(10);
    #ifdef sarthak
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    ll t = 1;
    // cin >> t;

    while(t--)
    {
        solve();
    }

    #ifdef sarthak
    cerr << "Time elapsed: " << (clock() - begtime)*1000/CLOCKS_PER_SEC << " ms\n\n";
    #endif
}
