#include <bits/stdc++.h>
using namespace std;
long long int dist[100005];
int n, m, k, q, ind[100005], parent[100005], depth[100005], maxi[100005][25],
    parent2[100005][25];
vector<pair<int, int> > v[100005];
vector<pair<int, int> > v2[100005];
set<pair<long long int, int> > s;
map<pair<int, int>, int> m1;
vector<pair<int, pair<int, int> > > e;
vector<pair<int, pair<int, int> > > e2;
void dijkstra() {
  for (int i = 0; i < n; i++) {
    dist[i] = 1e18;
    if (i < k) {
      dist[i] = 0;
      ind[i] = i;
    }
    s.insert(make_pair(dist[i], i));
  }
  while (!s.empty()) {
    long long int d = (*s.begin()).first, x = (*s.begin()).second;
    s.erase(s.begin());
    for (int i = 0; i < v[x].size(); i++) {
      if (d + v[x][i].second < dist[v[x][i].first]) {
        ind[v[x][i].first] = ind[x];
        s.erase(make_pair(dist[v[x][i].first], v[x][i].first));
        dist[v[x][i].first] = d + v[x][i].second;
        s.insert(make_pair(dist[v[x][i].first], v[x][i].first));
      }
    }
  }
}
int find_par(int x) {
  if (x == parent[x]) return x;
  int par = find_par(parent[x]);
  parent[x] = par;
  return par;
}
void spoji(int x, int y) {
  x = find_par(x);
  y = find_par(y);
  if (x == y) return;
  if (depth[x] == depth[y]) depth[x] += 1;
  if (depth[x] > depth[y])
    parent[y] = x;
  else
    parent[x] = y;
}
void dfs(int x, int par, int d1) {
  parent2[x][0] = par;
  depth[x] = d1;
  for (int i = 0; i < v2[x].size(); i++) {
    if (v2[x][i].first == par) continue;
    maxi[v2[x][i].first][0] = v2[x][i].second;
    dfs(v2[x][i].first, x, d1 + 1);
  }
}
int lca(int a, int b) {
  if (depth[a] < depth[b]) swap(a, b);
  int sol = 0;
  for (int i = 0; i < 20; i++) {
    if ((depth[a] - depth[b]) & (1 << i)) {
      sol = max(sol, maxi[a][i]);
      a = parent2[a][i];
    }
  }
  if (a == b) return sol;
  for (int i = 19; i >= 0; i--) {
    if (parent2[a][i] == parent2[b][i]) continue;
    sol = max(sol, max(maxi[a][i], maxi[b][i]));
    a = parent2[a][i];
    b = parent2[b][i];
  }
  return max(sol, max(maxi[a][0], maxi[b][0]));
}
int main() {
  cin >> n >> m >> k >> q;
  for (int i = 0; i < m; i++) {
    int a, b, w;
    cin >> a >> b >> w;
    v[a - 1].push_back(make_pair(b - 1, w));
    v[b - 1].push_back(make_pair(a - 1, w));
    e.push_back(make_pair(w, make_pair(a - 1, b - 1)));
  }
  dijkstra();
  for (int i = 0; i < m; i++) {
    int x = e[i].second.first, y = e[i].second.second;
    if (ind[x] == ind[y]) continue;
    if (m1[make_pair(ind[x], ind[y])] == 0 or
        dist[x] + e[i].first + dist[y] < m1[make_pair(ind[x], ind[y])]) {
      m1[make_pair(ind[x], ind[y])] = dist[x] + e[i].first + dist[y];
      m1[make_pair(ind[y], ind[x])] = dist[x] + e[i].first + dist[y];
    }
  }
  for (int i = 0; i < m; i++) {
    int x = e[i].second.first, y = e[i].second.second;
    if (ind[x] == ind[y] or m1[make_pair(ind[x], ind[y])] == 0) continue;
    e2.push_back(
        make_pair(m1[make_pair(ind[x], ind[y])], make_pair(ind[x], ind[y])));
    m1[make_pair(ind[x], ind[y])] = 0;
    m1[make_pair(ind[y], ind[x])] = 0;
  }
  sort(e2.begin(), e2.end());
  for (int i = 0; i < k; i++) parent[i] = i;
  for (int i = 0; i < e2.size(); i++) {
    int x = e2[i].second.first, y = e2[i].second.second;
    if (find_par(x) == find_par(y)) continue;
    spoji(x, y);
    v2[x].push_back(make_pair(y, e2[i].first));
    v2[y].push_back(make_pair(x, e2[i].first));
  }
  memset(depth, 0, sizeof(depth));
  dfs(0, 0, 0);
  for (int i = 1; i < 20; i++) {
    for (int j = 0; j < n; j++) {
      parent2[j][i] = parent2[parent2[j][i - 1]][i - 1];
      maxi[j][i] = max(maxi[parent2[j][i - 1]][i - 1], maxi[j][i - 1]);
    }
  }
  for (int i = 0; i < q; i++) {
    int a, b;
    cin >> a >> b;
    cout << lca(ind[a - 1], ind[b - 1]) << "\n";
  }
  return 0;
}
