#include <bits/stdc++.h>
using namespace std;
vector<pair<int, long long> > edge[100010];
vector<pair<int, long long> > L[100010];
priority_queue<pair<long long, long long>, vector<pair<long long, long long> >,
               greater<pair<long long, long long> > >
    H;
long long E[100010 * 3], p[100010], first[100010];
long long t[100010], level[100010], stramos[100010][20];
long long dist[100010], dp[100010][20];
pair<long long, long long> rmq[100010][20];
int n, m, k, q, x, y, i, j, a, b, K;
long long cost, c;
struct muchie {
  int x, y;
  long long cost;
};
vector<muchie> mch;
inline int get_rad(int x) {
  while (t[x] > 0) x = t[x];
  return x;
}
inline long long cmp(muchie a, muchie b) { return a.cost < b.cost; }
void _union(int x, int y, long long cost) {
  int rx = get_rad(x), ry = get_rad(y);
  if (rx == ry) return;
  edge[x].push_back(make_pair(y, cost));
  edge[y].push_back(make_pair(x, cost));
  if (t[rx] < t[ry]) {
    t[rx] += t[ry];
    t[ry] = rx;
  } else {
    t[ry] += t[rx];
    t[rx] = ry;
  }
}
void dfs(int nod, int tata) {
  level[nod] = 1 + level[tata];
  for (int i = 1; i <= 17; ++i) {
    stramos[nod][i] = stramos[stramos[nod][i - 1]][i - 1];
    dp[nod][i] = max(dp[nod][i - 1], dp[stramos[nod][i - 1]][i - 1]);
  }
  for (int i = 0; i < edge[nod].size(); ++i) {
    int vecin = edge[nod][i].first;
    if (vecin != tata) {
      stramos[vecin][0] = nod;
      dp[vecin][0] = edge[nod][i].second;
      dfs(vecin, nod);
    }
  }
}
long long solve(int x, int y) {
  if (level[x] > level[y]) swap(x, y);
  long long sol = 0;
  for (int i = 17; i >= 0; i--) {
    int nod = stramos[y][i];
    if (level[y] - (1 << i) >= level[x]) {
      sol = max(sol, dp[y][i]);
      y = stramos[y][i];
    }
  }
  for (int i = 17; i >= 0; i--) {
    if (stramos[x][i] != stramos[y][i]) {
      sol = max(sol, max(dp[x][i], dp[y][i]));
      x = stramos[x][i], y = stramos[y][i];
    }
  }
  if (x != y) sol = max(sol, max(dp[x][0], dp[y][0]));
  return sol;
}
int main() {
  scanf("%d%d%d%d", &n, &m, &K, &q);
  for (i = 1; i <= m; ++i) {
    scanf("%d%d%d", &x, &y, &c);
    L[x].push_back(make_pair(y, c));
    L[y].push_back(make_pair(x, c));
  }
  for (i = K + 1; i <= n; ++i) dist[i] = 1LL << 60;
  for (i = 1; i <= K; ++i) {
    H.push(make_pair(0, i));
    dist[i] = 0;
  }
  while (!H.empty()) {
    int nod = H.top().second;
    long long cst = H.top().first;
    H.pop();
    if (cst != dist[nod]) continue;
    for (int i = 0; i < L[nod].size(); ++i) {
      int vecin = L[nod][i].first;
      long long cost = L[nod][i].second;
      if (dist[nod] + cost < dist[vecin]) {
        dist[vecin] = dist[nod] + cost;
        H.push(make_pair(dist[vecin], vecin));
      }
    }
  }
  for (i = 1; i <= n; ++i)
    for (j = 0; j < L[i].size(); ++j) {
      int vecin = L[i][j].first;
      if (vecin <= i) continue;
      mch.push_back({i, vecin, L[i][j].second + dist[i] + dist[vecin]});
    }
  sort(mch.begin(), mch.end(), cmp);
  for (i = 1; i <= n; ++i) t[i] = -1;
  for (int i = 0; i < mch.size(); ++i) {
    int x = mch[i].x, y = mch[i].y;
    long long cost = mch[i].cost;
    _union(x, y, cost);
  }
  dfs(1, 0);
  for (i = 1; i <= q; i++) {
    scanf("%d%d", &a, &b);
    printf("%d\n", solve(a, b));
  }
  return 0;
}
