#include <bits/stdc++.h>
using namespace std;
const long long N = 4e5 + 5;
const long long M = 6e5 + 5;
const long long mod = 1e9 + 7;
long long n, m, k, Q;
long long c;
long long num = 0, Num = 0;
long long h[N], H[N];
struct edge {
  long long u, v, w, next;
} e[M << 2], E[M], E2[M << 2];
struct node {
  long long bh, val;
  bool operator<(const node &b) const { return val > b.val; }
};
inline bool cmp(edge x, edge y) { return x.w < y.w; }
inline void add(long long u, long long v, long long w) {
  e[++num] = (edge){u, v, w, h[u]}, h[u] = num;
}
inline void Add(long long u, long long v, long long w) {
  E2[++Num] = (edge){u, v, w, H[u]}, H[u] = Num;
}
bool v[N];
long long dis[N], fa[N], f[N][22], dep[N], maxm[N][22];
bool vis[N];
priority_queue<node> q;
inline long long read() {
  long long x = 0, f = 1;
  long long ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
inline long long getf(long long x) {
  if (x != fa[x]) fa[x] = getf(fa[x]);
  return fa[x];
}
void kruskal() {
  for (long long i = 1; i <= n; i++) fa[i] = i;
  for (long long i = 1; i <= m; i++) {
    long long u = getf(E[i].u), v = getf(E[i].v);
    if (u != v) {
      fa[v] = u;
      Add(E[i].u, E[i].v, E[i].w);
      Add(E[i].v, E[i].u, E[i].w);
      c++;
      if (c == n - 1) return;
    }
  }
}
void dij() {
  memset(dis, 0x3f, sizeof dis);
  dis[0] = 0;
  q.push((node){0, 0});
  while (!q.empty()) {
    node u = q.top();
    q.pop();
    if (vis[u.bh]) continue;
    vis[u.bh] = 1;
    for (long long i = h[u.bh]; i; i = e[i].next) {
      long long v = e[i].v;
      if (dis[v] > dis[u.bh] + e[i].w) {
        dis[v] = dis[u.bh] + e[i].w;
        if (!vis[v]) q.push((node){v, dis[v]});
      }
    }
  }
}
void dfs(long long u, long long fa) {
  f[u][0] = fa;
  for (long long i = H[u]; i; i = E2[i].next) {
    long long v = E2[i].v;
    if (v == fa) continue;
    dep[v] = dep[u] + 1;
    maxm[v][0] = E2[i].w;
    dfs(v, u);
  }
}
void init() {
  for (long long i = 1; i <= 20; i++)
    for (long long j = 1; j <= n; j++) {
      f[j][i] = f[f[j][i - 1]][i - 1];
      maxm[j][i] = max(maxm[j][i - 1], maxm[f[j][i - 1]][i - 1]);
    }
}
long long get_max(long long x, long long y) {
  long long ans = 0;
  if (dep[x] < dep[y]) swap(x, y);
  for (long long i = 20; i >= 0; --i) {
    if (dep[f[x][i]] < dep[y]) continue;
    ans = max(ans, maxm[x][i]);
    x = f[x][i];
  }
  if (x == y) return ans;
  for (long long i = 20; i >= 0; i--) {
    if (f[x][i] == f[y][i]) continue;
    ans = max(ans, max(maxm[x][i], maxm[y][i]));
    x = f[x][i];
    y = f[y][i];
  }
  ans = max(ans, max(maxm[x][0], maxm[y][0]));
  return ans;
}
signed main() {
  cin >> n >> m >> k >> Q;
  for (long long i = 1; i <= m; i++) {
    long long u = read(), v = read(), w = read();
    add(u, v, w), add(v, u, w);
    E[i].u = u;
    E[i].v = v;
    E[i].w = w;
  }
  for (long long i = 1; i <= k; i++) add(0, i, 0), add(i, 0, 0);
  dij();
  for (long long i = 1; i <= m; i++) {
    E[i].w += dis[E[i].u] + dis[E[i].v];
  }
  sort(E + 1, E + m + 1, cmp);
  kruskal();
  dep[1] = 1;
  dfs(1, -1);
  init();
  for (long long i = 1, u, v; i <= Q; i++) {
    u = read(), v = read();
    printf("%lld", get_max(v, u));
  }
  return 0;
}
