#include <bits/stdc++.h>
using namespace std;
priority_queue<pair<long long, long long>, vector<pair<long long, long long> >,
               greater<pair<long long, long long> > >
    q;
stringstream ssin;
const long long LINF = 0x7fffffffffffffffll;
const long long N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
long long n, m, k, qq, idx, t = log2(N);
long long e[M], ne[M], w[M], h[N], p[N];
long long dis[N], belong[N], d[N][20];
long long depth[N], fa[N][20];
bool vis[N];
inline long long read() {
  char c = getchar();
  long long x = 0, f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}
void add(long long a, long long b, long long c) {
  e[idx] = b;
  w[idx] = c;
  ne[idx] = h[a];
  h[a] = idx++;
}
long long find(long long x) {
  if (p[x] != x)
    return p[x] = find(p[x]);
  else
    return p[x];
}
struct node {
  long long a, b, c;
  bool operator<(const node &x) const { return c < x.c; }
} E[M], E2[M];
void dij() {
  for (int i = 0; i <= n; ++i) dis[i] = 1e17;
  for (int i = 1; i <= k; ++i) dis[i] = 0;
  while (!q.empty()) {
    pair<long long, long long> t = q.top();
    q.pop();
    int u = t.second;
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = h[u]; ~i; i = ne[i]) {
      int v = e[i], z = w[i];
      if (dis[u] + z < dis[v]) {
        dis[v] = dis[u] + z;
        q.push({dis[v], v});
        belong[v] = belong[u];
      }
    }
  }
}
void bfs(long long rt) {
  memset(depth, 0x3f, sizeof depth);
  ;
  depth[0] = 0;
  depth[rt] = 1;
  queue<int> Q;
  Q.push(rt);
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (int i = h[x]; ~i; i = ne[i]) {
      int y = e[i], z = w[i];
      if (depth[y] > depth[x] + 1) {
        depth[y] = depth[x] + 1;
        Q.push(y);
        fa[y][0] = x;
        d[y][0] = z;
        for (int k = 1; k <= t; ++k) {
          fa[y][k] = fa[fa[y][k - 1]][k - 1];
          d[y][k] = max(d[y][k - 1], d[fa[y][k - 1]][k - 1]);
        }
      }
    }
  }
}
long long lca(long long a, long long b) {
  long long res = 0;
  if (depth[a] < depth[b]) swap(a, b);
  for (int k = t; k >= 0; --k) {
    if (depth[fa[a][k]] >= depth[b]) {
      res = max(res, d[a][k]);
      a = fa[a][k];
    }
  }
  if (a == b) return res;
  for (int k = t; k >= 0; --k) {
    if (fa[a][k] != fa[b][k]) {
      res = max(res, d[a][k]);
      res = max(res, d[b][k]);
      a = fa[a][k];
      b = fa[b][k];
    }
  }
  return max(res, max(d[a][0], d[b][0]));
}
int main() {
  n = read();
  m = read();
  k = read();
  qq = read();
  memset(h, -1, sizeof h);
  ;
  for (int i = 1; i <= k; ++i) {
    belong[i] = i;
    q.push({0, i});
  }
  for (int i = 1; i <= m; ++i) {
    int a, b, c;
    a = read();
    b = read();
    c = read();
    E[i] = {a, b, c};
    add(a, b, c);
    add(b, a, c);
  }
  dij();
  int cnt = 0;
  for (int i = 1; i <= m; ++i) {
    long long a = E[i].a, b = E[i].b, c = E[i].c;
    if (belong[a] == belong[b]) continue;
    E2[++cnt] = {belong[a], belong[b], dis[a] + dis[b] + c};
    add(belong[a], belong[b], dis[a] + dis[b] + c);
    add(belong[b], belong[a], dis[a] + dis[b] + c);
  }
  sort(E2 + 1, E2 + 1 + cnt);
  for (int i = 1; i <= n; ++i) p[i] = i;
  memset(h, -1, sizeof h);
  ;
  idx = 0;
  for (int i = 1; i <= cnt; ++i) {
    long long a = E2[i].a, b = E2[i].b, c = E2[i].c;
    if (find(a) == find(b)) continue;
    int pa = find(a), pb = find(b);
    p[pa] = pb;
    add(a, b, c);
    add(b, a, c);
  }
  bfs(1);
  while (qq--) {
    int a, b;
    a = read();
    b = read();
    cout << lca(a, b) << '\n';
  }
}
