#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const int maxm = 3e5 + 5;
int U[maxm], V[maxm], W[maxm];
int par[maxn];
vector<int> adj[maxn], comp[maxn];
vector<pair<int, int>> Query[maxn];
priority_queue<pair<long long, int>, vector<pair<long long, int>>,
               greater<pair<long long, int>>>
    pq;
int N, M, Q, K;
long long D[maxn];
int res[maxn];
signed main(void) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> N >> M >> K >> Q;
  for (int i = 1; i <= M; ++i) {
    cin >> U[i] >> V[i] >> W[i];
    adj[U[i]].push_back(i);
    adj[V[i]].push_back(i);
  }
  for (int i = 1; i <= Q; ++i) {
    int u, v;
    cin >> u >> v;
    Query[u].push_back(make_pair(v, i));
    Query[v].push_back(make_pair(u, i));
  }
  for (int i = 1; i <= N; ++i) {
    if (i <= K)
      pq.push(make_pair(0, i));
    else
      D[i] = 1e17;
  }
  while (pq.size()) {
    auto now = pq.top();
    pq.pop();
    if (now.first != D[now.second]) continue;
    for (int id : adj[now.second]) {
      int u = now.second;
      int v = U[id] + V[id] - u;
      int w = W[id];
      if (D[v] > D[u] + w) {
        D[v] = D[u] + w;
        pq.push(make_pair(D[v], v));
      }
    }
  }
  vector<pair<long long, int>> edge;
  for (int i = 1; i <= M; ++i) {
    edge.push_back(make_pair(W[i] + D[U[i]] + D[V[i]], i));
  }
  sort(edge.begin(), edge.end());
  for (int i = 1; i <= N; ++i) {
    comp[i].push_back(i);
    par[i] = i;
  }
  for (auto all : edge) {
    int u = U[all.second], v = V[all.second];
    u = par[u];
    v = par[v];
    if (u == v) continue;
    if ((int)comp[u].size() < (int)comp[v].size()) swap(u, v);
    for (int it : comp[v]) {
      for (auto x : Query[it]) {
        if (par[x.first] == u) {
          res[x.second] = all.first;
        }
      }
    }
    for (int it : comp[v]) {
      par[it] = u;
      comp[u].push_back(it);
    }
  }
  for (int i = 1; i <= Q; ++i) cout << res[i] << '\n';
}
