#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define xx first
#define yy second
const int BS=500;
using namespace std;
using namespace __gnu_pbds;
#define be begin()
#define rb rbegin()
#define all(v) v.begin(),v.end() 
#define rep(i,start,lim) for(long long (i)=(start);i<(lim);i++)
#define nod int node,int l,int r
#define lson node*2,l,(l+r)/2
#define rson node*2+1,(l+r)/2+1,r
typedef long long ll;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> rbTree;
const ll inf= 1e9+10;
ll mod=  1e9+7;
const ll mxn= 3e5+20;
const int N=2.5*1e7+10;
const double pi=3.14159;
#define mp make_pair
#define mp3(a,b,c) mp(a,mp(b,c))
typedef pair<int,int> pii;
typedef pair<int,pair<int,int> > piii;
typedef pair<int,pair<int,pair<int,int>>> piiii;
typedef pair<ll, int> pli;
typedef pair<ll,ll> pll;
int dx[]={0,1,0,-1,1,-1,1,-1};
int dy[]={1,0,-1,0,-1,1,1,-1};
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll n,k,m,q,x,y,p;
vector<pii> g[mxn], qry[mxn];
ll d[mxn], par[mxn], ans[mxn];
vector<tuple<ll,int,int>> e;
set<int> dsu[mxn];
int find(int x){ return x==par[x]?x:par[x]=find(par[x]); }
void dij(){
    priority_queue<pli> pq;
    for(int i=1;i<=n;i++){
        if(i<=k) pq.push(mp(0,i));
        else d[i]=inf;
    }
    while(!pq.empty()){
        auto top=pq.top();
        pq.pop();
        int u=top.yy;
        for(auto [v,w]: g[u]){
            if(d[v]>w+d[u]) d[v]=w+d[u], pq.push(mp(-d[v],v));
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin>>n>>m>>k>>q;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        g[u].eb(v,w), g[v].eb(u,w);
    }
    dij();
    for(int v=1;v<=n;v++){
        for(auto [u,w]: g[v]){
            if(u<v)
            e.pb(make_tuple(d[u]+d[v]+w,u,v));
        }
    }
    for(int i=0;i<q;i++){
        int u,v;
        cin>>u>>v;
        qry[u].eb(v,i), qry[v].eb(u,i);
    }
    for(int i=1;i<=n;i++) par[i]=i, dsu[i].insert(i);
    sort(all(e));
    for(auto [wt,u,v]: e){
        //cout<<wt<<'\n';
        int x=find(u), y=find(v);
        if(x==y) continue;
        if(dsu[x].size()<dsu[y].size()) swap(x,y);
        par[y]=x; // make bigger the parent
        for(auto u: dsu[y]){
            for(auto [other,id]: qry[u]){
                if(dsu[x].count(other)) ans[id]=wt;
            }
        }
        for(auto u: dsu[y]) dsu[x].insert(u);
    }
    for(int i=0;i<q;i++) cout<<ans[i]<<'\n';
}