#include <bits/stdc++.h>
using namespace std;
const long long MAX_INT = 1e18;
vector<vector<pair<int, long long>>> a;
vector<pair<long long, pair<int, int>>> edge_list;
vector<long long> dis, par, cnt, res;
vector<set<int>> query_set;
int n, m, k, q;
void dijktra() {
  priority_queue<pair<long long, int>, vector<pair<long long, int>>,
                 greater<pair<long long, int>>>
      heap;
  for (int i = 0; i < k; ++i) {
    dis[i] = 0;
    heap.push({0, i});
  }
  while (!heap.empty()) {
    auto item = heap.top();
    heap.pop();
    if (item.first != dis[item.second]) continue;
    for (auto edge : a[item.second]) {
      if (dis[edge.first] > dis[item.second] + edge.second) {
        dis[edge.first] = dis[item.second] + edge.second;
        heap.push({dis[edge.first], edge.first});
      }
    }
  }
}
int get_gid(int x) {
  if (par[x] == -1) return x;
  return get_gid(par[x]);
}
void join(int u, int v, long long w) {
  int gid1 = get_gid(u);
  int gid2 = get_gid(v);
  if (gid1 == gid2) return;
  if (cnt[gid1] < cnt[gid2]) swap(gid1, gid2);
  par[gid2] = gid1;
  cnt[gid1] += cnt[gid2];
  for (auto query_id : query_set[gid2]) {
    if (query_set[gid1].find(query_id) != query_set[gid1].end()) {
      res[query_id] = w;
      query_set[gid1].erase(query_id);
    } else {
      query_set[gid1].insert(query_id);
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> k >> q;
  dis.resize(n, MAX_INT);
  a.resize(n);
  for (int i = 0; i < m; ++i) {
    int x, y, z;
    cin >> x >> y >> z;
    --x, --y;
    a[x].push_back({y, z});
    a[y].push_back({x, z});
    edge_list.push_back({z, {x, y}});
  }
  query_set.resize(n);
  for (int i = 0; i < q; ++i) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    query_set[x].insert(i);
    query_set[y].insert(i);
  }
  dijktra();
  for (auto& item : edge_list)
    item.first = item.first + dis[item.second.first] + dis[item.second.second];
  sort(edge_list.begin(), edge_list.end());
  par.resize(n, -1);
  cnt.resize(n, 1);
  res.resize(q);
  for (auto item : edge_list) {
    int u = item.second.first;
    int v = item.second.second;
    int weight = item.first;
    join(u, v, weight);
  }
  for (auto val : res) cout << val << endl;
  return 0;
}
