#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, M = 3e5 + 5;
int mp[N], to[M * 2], v[M * 2], nex[M * 2], cnt;
int mp2[N], to2[M << 1], v2[M << 1], nex2[M << 1], cnt2;
long long maxx[20][N], dis[N];
int num[N];
bool vis[N];
int fa[N];
int ff[20][N], dep[N];
struct node {
  int x, v, fr;
  friend bool operator<(node a, node b) { return a.v > b.v; };
};
priority_queue<node> qu;
int n, m, q, k;
void add(int x, int y, int w) {
  cnt++;
  to[cnt] = y;
  v[cnt] = w;
  nex[cnt] = mp[x];
  mp[x] = cnt;
}
void add2(int x, int y, int w) {
  cnt2++;
  to2[cnt2] = y;
  v2[cnt2] = w;
  nex2[cnt2] = mp2[x];
  mp2[x] = cnt2;
}
int gtf(int x) {
  if (x != fa[x]) fa[x] = gtf(fa[x]);
  return fa[x];
}
bool uni(int x, int y) {
  int anx = gtf(x), any = gtf(y);
  if (anx == any) return 0;
  fa[anx] = any;
  return 1;
}
void dij() {
  int i, j;
  node p, d;
  for (i = 1; i <= k; i++) {
    p.x = i;
    p.v = 0;
    p.fr = i;
    qu.push(p);
  }
  while (!qu.empty()) {
    p = qu.top();
    qu.pop();
    if (vis[p.x]) {
      if (uni(p.fr, num[p.x])) {
        add2(p.fr, num[p.x], p.v + dis[p.x]);
        add2(num[p.x], p.fr, p.v + dis[p.x]);
      }
      continue;
    }
    vis[p.x] = 1;
    num[p.x] = p.fr;
    dis[p.x] = p.v;
    for (i = mp[p.x]; i; i = nex[i]) {
      d.x = to[i];
      d.fr = p.fr;
      d.v = p.v + v[i];
      qu.push(d);
    }
  }
}
void dfs(int x, int f) {
  ff[0][x] = f;
  dep[x] = dep[f] + 1;
  for (int i = 1; i <= 19; i++) {
    ff[i][x] = ff[i - 1][ff[i - 1][x]];
    maxx[i][x] = max(maxx[i - 1][x], maxx[i - 1][ff[i - 1][x]]);
  }
  for (int i = mp2[x]; i; i = nex2[i]) {
    if (to2[i] == f) continue;
    maxx[0][to2[i]] = v2[i];
    dfs(to2[i], x);
  }
}
long long lca(int u, int v) {
  int i;
  long long mx = 0;
  if (dep[u] < dep[v]) swap(u, v);
  for (i = 19; i >= 0; i--)
    if (dep[ff[i][u]] >= dep[v]) {
      mx = max(mx, maxx[i][u]);
      u = ff[i][u];
    }
  if (u == v) return mx;
  for (i = 19; i >= 0; i--)
    if (ff[i][u] != ff[i][v]) {
      mx = max(mx, max(maxx[i][u], maxx[i][v]));
      u = ff[i][u];
      v = ff[i][v];
    }
  mx = max(mx, max(maxx[0][u], maxx[0][v]));
  return mx;
}
int main() {
  scanf("%d%d%d%d", &n, &m, &k, &q);
  int i, j;
  for (i = 1; i <= n; i++) fa[i] = i;
  cnt = 0;
  for (i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    add(u, v, w);
    add(v, u, w);
  }
  dij();
  memset(maxx, 0, sizeof(maxx));
  dfs(1, 0);
  for (i = 1; i <= q; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    printf("%I64d\n", lca(u, v));
  }
  return 0;
}
