#include <bits/stdc++.h>
using namespace std;
const long long maxn = 5e5 + 222;
struct node {
  long long s, id, dis;
  node() {}
  node(long long ss, long long i, long long d) {
    s = ss;
    id = i;
    dis = d;
  }
  bool operator<(const node& n) const { return dis > n.dis; }
};
vector<long long> TR[maxn];
vector<long long> W[maxn];
long long fa[maxn];
long long FA(long long x) {
  if (fa[x] == x) return x;
  fa[x] = FA(fa[x]);
  return fa[x];
}
inline void merge(long long a, long long b, long long dis) {
  long long A = FA(a), B = FA(b);
  if (A == B) return;
  fa[A] = B;
  TR[a].push_back(b);
  TR[b].push_back(a);
  W[a].push_back(dis);
  W[b].push_back(dis);
}
vector<long long> G[maxn];
vector<long long> LEN[maxn];
long long n, m, k, q;
pair<long long, long long> savemin[maxn];
void dj() {
  priority_queue<node> q;
  for (long long i = 1; i <= k; i++) {
    q.push(node(i, i, 0));
  }
  while (!q.empty()) {
    node nownode = q.top();
    q.pop();
    long long nowid = nownode.id;
    if (savemin[nowid].first) {
      merge(savemin[nowid].first, nownode.s,
            nownode.dis + savemin[nowid].second);
    }
    if (nownode.dis >= savemin[nowid].second) continue;
    savemin[nowid].second = nownode.dis;
    savemin[nowid].first = nownode.s;
    for (long long i = 0; i < G[nowid].size(); i++) {
      long long d = G[nowid][i];
      long long le = LEN[nowid][i];
      q.push(node(nownode.s, d, nownode.dis + le));
    }
  }
}
long long dep[maxn];
long long ffa[maxn][33];
long long faw[maxn][33];
void dfs(long long s, long long f, long long le) {
  ffa[s][0] = f;
  faw[s][0] = le;
  dep[s] = dep[f] + 1;
  for (long long i = 1; i < 30; i++) {
    ffa[s][i] = ffa[ffa[s][i - 1]][i - 1];
    faw[s][i] = max(faw[s][i - 1], faw[ffa[s][i - 1]][i - 1]);
  }
  for (long long i = 0; i < TR[s].size(); i++) {
    long long d = TR[s][i];
    if (d == f) continue;
    dfs(d, s, W[s][i]);
  }
}
inline long long cal(long long a, long long b) {
  if (dep[a] > dep[b]) swap(a, b);
  long long res = 0;
  for (long long i = 29; i >= 0; i--) {
    if (dep[ffa[b][i]] >= dep[a]) {
      res = max(res, faw[b][i]);
      b = ffa[b][i];
    }
  }
  if (a == b) return res;
  for (long long i = 29; i >= 0; i--) {
    if (ffa[a][i] != ffa[b][i]) {
      res = max(res, faw[a][i]);
      res = max(res, faw[b][i]);
      a = ffa[a][i];
      b = ffa[b][i];
    }
  }
  res = max(res, faw[a][0]);
  res = max(res, faw[b][0]);
  return res;
}
void solve() {
  scanf("%lld %lld %lld %lld", &n, &m, &k, &q);
  for (long long i = 1; i <= m; i++) {
    long long a, b, c;
    scanf("%lld %lld %lld", &a, &b, &c);
    G[a].push_back(b);
    G[b].push_back(a);
    LEN[a].push_back(c);
    LEN[b].push_back(c);
  }
  for (long long i = 1; i <= n; i++) {
    fa[i] = i;
    savemin[i].second = LLONG_MAX / 10;
  }
  dj();
  dfs(1, 0, 0);
  while (q--) {
    long long a, b;
    scanf("%lld %lld", &a, &b);
    long long temp = cal(a, b);
    printf("%lld\n", temp);
  }
}
signed main() { solve(); }
