#include <bits/stdc++.h>
using namespace std;
int n, m, k, q, par[100005];
vector<pair<int, long long>> v[100005], adj[100005];
vector<long long> dis(100005, 1e16);
int par_dsu[100005];
int get(int u) {
  if (u == par_dsu[u]) return u;
  return par_dsu[u] = get(par_dsu[u]);
}
long long rmq[100005][17];
int up[100005][17], lvl[100005], siz[100005], tin[100005], tout[100005];
void dfspre(int u, int dad = 1, int depth = 0, long long wt = 0) {
  static int clk = 0;
  tin[u] = clk++;
  up[u][0] = dad;
  rmq[u][0] = wt;
  lvl[u] = depth;
  for (int i = 1; i < 17; ++i) {
    up[u][i] = up[up[u][i - 1]][i - 1];
    rmq[u][i] = max(rmq[up[u][i - 1]][i - 1], rmq[u][i - 1]);
  }
  for (auto i : adj[u])
    if (i.first != dad) dfspre(i.first, u, depth + 1, i.second);
  tout[u] = clk++;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> k >> q;
  vector<pair<long long, pair<int, int>>> edges_tmp, edges;
  for (int i = 0, x, y, w; i < m; ++i) {
    cin >> x >> y >> w;
    v[x].emplace_back(y, w);
    v[y].emplace_back(x, w);
    edges_tmp.push_back({w, {x, y}});
  }
  priority_queue<pair<long long, int>, vector<pair<long long, int>>,
                 greater<pair<long long, int>>>
      pq;
  set<int> vis;
  for (int i = 1; i <= k; ++i) {
    par[i] = i;
    pq.push({dis[i] = 0, i});
  }
  while (pq.size()) {
    auto u = pq.top().second;
    pq.pop();
    vis.insert(u);
    for (auto i : v[u]) {
      int d = i.second + dis[u];
      if (dis[i.first] > d) {
        par[i.first] = par[u];
        pq.push({dis[i.first] = d, i.first});
      }
    }
  }
  for (auto e : edges_tmp) {
    if (par[e.second.first] == par[e.second.second]) continue;
    edges.push_back({dis[e.second.first] + dis[e.second.second] + e.first,
                     {par[e.second.first], par[e.second.second]}});
  }
  sort(edges.begin(), edges.end());
  iota(par_dsu, par_dsu + 100005, 0);
  for (auto e : edges) {
    int x, y;
    tie(x, y) = e.second;
    x = get(x), y = get(y);
    if (x != y) {
      adj[x].push_back({y, e.first});
      adj[y].push_back({x, e.first});
      par_dsu[x] = get(y);
    }
  }
  dfspre(1);
  for (int x, y; q--;) {
    cin >> x >> y;
    long long ans = 0;
    for (int l = 17; l--;) {
      if (lvl[x] < lvl[y]) swap(x, y);
      if (!(tin[up[x][l]] <= tin[y] && tout[y] <= tout[up[x][l]])) {
        ans = max(ans, rmq[x][l]);
        x = up[x][l];
      }
    }
    ans = max(ans, rmq[x][0]);
    x = up[x][0];
    if (x != y) ans = max(ans, rmq[y][0]);
    cout << ans << '\n';
  }
}
