#include <bits/stdc++.h>
using namespace std;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
struct node {
  int u, v, w;
} e[1000005];
struct Union_Find_Set {
  int fa[1000005];
  void init(int x) {
    for (int i = 1; i <= x; i++) fa[i] = i;
  }
  int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
  void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    fa[x] = y;
  }
} S;
int n, m, k, q, v[1000005], w[1000005], head[1000005], nxt[1000005], cnt,
    dist[1000005], vis[1000005], f[100005][25], p[100005][25], dep[1000005];
void add(int a, int b, int c) {
  v[++cnt] = b;
  w[cnt] = c;
  nxt[cnt] = head[a];
  head[a] = cnt;
}
void dij() {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      q;
  memset(dist, 0x3f, sizeof(dist));
  dist[0] = 0;
  q.push(make_pair(0, 0));
  while (!q.empty()) {
    int c = q.top().second;
    q.pop();
    if (vis[c]) continue;
    vis[c] = 1;
    for (int i = head[c]; i != -1; i = nxt[i]) {
      if (dist[v[i]] > dist[c] + w[i]) {
        dist[v[i]] = dist[c] + w[i];
        q.push(make_pair(dist[v[i]], v[i]));
      }
    }
  }
}
int cmp(node a, node b) { return a.w < b.w; }
void KS() {
  sort(e + 1, e + 1 + m, cmp);
  S.init(n);
  for (int i = 1; i <= m; i++) {
    int x = e[i].u, y = e[i].v;
    if (S.find(x) == S.find(y)) continue;
    S.merge(x, y);
    add(x, y, e[i].w);
    add(y, x, e[i].w);
  }
}
void dfs(int x, int fa) {
  dep[x] = dep[fa] + 1;
  for (int i = 0; i <= 19; i++)
    f[x][i + 1] = f[f[x][i]][i], p[x][i + 1] = max(p[x][i], p[f[x][i]][i]);
  for (int i = head[x]; i != -1; i = nxt[i]) {
    if (v[i] == fa) continue;
    f[v[i]][0] = x;
    p[v[i]][0] = w[i];
    dfs(v[i], x);
  }
}
int LCA(int x, int y) {
  int ans = 0;
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = 20; i >= 0; i--) {
    if (dep[f[x][i]] >= dep[y]) ans = max(ans, p[x][i]), x = f[x][i];
  }
  if (x == y) return ans;
  for (int i = 20; i >= 0; i--) {
    if (f[x][i] != f[y][i]) {
      ans = max(ans, p[x][i]);
      ans = max(ans, p[y][i]);
      x = f[x][i];
      y = f[y][i];
    }
  }
  ans = max(ans, p[x][0]);
  ans = max(ans, p[y][0]);
  return ans;
}
signed main() {
  memset(head, -1, sizeof(head));
  n = read();
  m = read();
  k = read();
  q = read();
  for (int i = 1; i <= m; i++) {
    int x = read(), y = read(), z = read();
    e[i].u = x;
    e[i].v = y;
    e[i].w = z;
    add(x, y, z);
    add(y, x, z);
  }
  for (int i = 1; i <= k; i++) add(0, i, 0), add(i, 0, 0);
  dij();
  for (int i = 1; i <= m; i++) e[i].w += dist[e[i].u] + dist[e[i].v];
  memset(head, -1, sizeof(head));
  cnt = 0;
  KS();
  dfs(1, 0);
  for (int i = 1; i <= q; i++) {
    int x = read(), y = read();
    printf("%d\n", LCA(x, y));
  }
}
