#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int n, k, head[MAXN], cnt, m, Q;
long long dis[MAXN];
struct Edge {
  int v;
  long long w;
  int nex;
} edge[MAXN * 6];
void add(int u, int v, long long w) {
  edge[cnt] = {v, w, head[u]};
  head[u] = cnt++;
}
int vis[MAXN];
priority_queue<pair<long long, int>, vector<pair<long long, int>>,
               greater<pair<long long, int>>>
    q;
void bfs() {
  for (int i = 1; i <= n; i++) dis[i] = 1e18;
  for (int i = 1; i <= k; i++) {
    dis[i] = 0;
    q.push({0, i});
  }
  while (q.size()) {
    int u = q.top().second;
    q.pop();
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = head[u]; ~i; i = edge[i].nex) {
      int v = edge[i].v;
      int w = edge[i].w;
      if (dis[v] > dis[u] + w) {
        dis[v] = dis[u] + w;
        q.push({dis[v], v});
      }
    }
  }
}
long long g[MAXN][30];
int f[MAXN][30], dep[MAXN];
void dfs(int u, int fa) {
  for (int i = head[u]; ~i; i = edge[i].nex) {
    int v = edge[i].v;
    int w = edge[i].w;
    if (v == fa) continue;
    f[v][0] = u;
    g[v][0] = w;
    dep[v] = dep[u] + 1;
    for (int j = 1; j <= 20; j++) {
      int anc = f[v][j - 1];
      f[v][j] = f[anc][j - 1];
      g[v][j] = max(g[v][j - 1], g[anc][j - 1]);
    }
    dfs(v, u);
  }
}
struct E {
  int u, v;
  long long w;
  bool operator<(const E &A) const {
    return w + dis[u] + dis[v] < A.w + dis[A.u] + dis[A.v];
  }
} e[MAXN];
int pre[MAXN];
int find(int u) { return u == pre[u] ? u : pre[u] = find(pre[u]); }
long long lca(int u, int v) {
  long long Max = 0;
  if (dep[u] < dep[v]) swap(u, v);
  for (int i = 20; i >= 0; i--)
    if (dep[f[u][i]] >= dep[v]) {
      Max = max(Max, g[u][i]);
      u = f[u][i];
    }
  if (u == v) return Max;
  for (int i = 20; i >= 0; i--)
    if (f[u][i] != f[v][i]) {
      Max = max(Max, max(g[u][i], g[v][i]));
      u = f[u][i];
      v = f[v][i];
    }
  return max(Max, max(g[u][0], g[v][0]));
}
int main() {
  memset(head, -1, sizeof head);
  cin >> n >> m >> k >> Q;
  for (int i = 1; i <= n; i++) pre[i] = i;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    add(u, v, w);
    add(v, u, w);
    e[i] = {u, v, w};
  }
  bfs();
  sort(e + 1, e + 1 + m);
  cnt = 0;
  memset(head, -1, sizeof head);
  for (int i = 1; i <= m; i++) {
    int u = e[i].u;
    int v = e[i].v;
    long long w = e[i].w + dis[u] + dis[v];
    if (find(u) != find(v)) {
      pre[find(u)] = find(v);
      add(u, v, w);
      add(v, u, w);
    }
  }
  dfs(1, 0);
  while (Q--) {
    int u, v;
    cin >> u >> v;
    cout << lca(u, v) << endl;
  }
  return 0;
}
