#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 10;
const long long INF = 1e15;
struct edge {
  int x, y, w;
};
struct node {
  int x;
  long long d;
  bool operator<(const node &_) const { return d > _.d; }
};
int n, m, k, q;
edge e[3 * maxn];
int tot;
int last[maxn];
int pre[6 * maxn], other[6 * maxn], len[6 * maxn];
long long dis[maxn];
bool vis[maxn];
int father[maxn], rk[maxn], v[maxn], dep[maxn];
void add(int x, int y, int z) {
  tot++;
  pre[tot] = last[x];
  last[x] = tot;
  other[tot] = y;
  len[tot] = z;
}
void Dijkstra() {
  priority_queue<node> que;
  for (int i = 1; i <= k; i++) dis[i] = 0;
  for (int i = k + 1; i <= n; i++) dis[i] = INF;
  for (int i = 1; i <= n; i++) que.push((node){i, dis[i]});
  while (!que.empty()) {
    node cur = que.top();
    que.pop();
    if (vis[cur.x]) continue;
    vis[cur.x] = 1;
    for (int p = last[cur.x]; p; p = pre[p]) {
      int q = other[p];
      if (dis[q] > dis[cur.x] + len[p]) {
        dis[q] = dis[cur.x] + len[p];
        que.push((node){q, dis[q]});
      }
    }
  }
}
bool cmp(edge a, edge b) { return a.w < b.w; }
int getfather(int x) {
  while (father[x]) x = father[x];
  return x;
}
int main() {
  scanf("%d%d%d%d", &n, &m, &k, &q);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].w);
    add(e[i].x, e[i].y, e[i].w);
    add(e[i].y, e[i].x, e[i].w);
  }
  Dijkstra();
  for (int i = 1; i <= m; i++) e[i].w = dis[e[i].x] + dis[e[i].y] + e[i].w;
  sort(e + 1, e + m + 1, cmp);
  for (int i = 1; i <= n; i++) rk[i] = 1;
  for (int i = 1; i <= m; i++) {
    int fa = getfather(e[i].x);
    int fb = getfather(e[i].y);
    if (fa == fb) continue;
    if (rk[fa] > rk[fb]) swap(fa, fb);
    father[fa] = fb;
    rk[fb] = max(rk[fb], rk[fa] + 1);
    v[fa] = e[i].w;
  }
  for (int i = 1; i <= n; i++) {
    int d = 1, x = i;
    while (father[x]) x = father[x], d++;
    dep[i] = d;
  }
  for (int i = 1; i <= q; i++) {
    int x, y;
    int tmp = 0;
    scanf("%d%d", &x, &y);
    while (dep[x] > dep[y]) tmp = max(tmp, v[x]), x = father[x];
    while (dep[y] > dep[x]) tmp = max(tmp, v[y]), y = father[y];
    while (x != y) {
      tmp = max(tmp, v[x]);
      tmp = max(tmp, v[y]);
      x = father[x];
      y = father[y];
    }
    printf("%d\n", tmp);
  }
  return 0;
}
