#include <bits/stdc++.h>
using namespace std;
int n, m, k, qq;
const int MAX_N = 100005;
vector<pair<int, int> > allEdges[MAX_N];
const int MAX_D = 16;
int lca[MAX_N][MAX_D];
long long lcamin[MAX_N][MAX_D];
int depth[MAX_N];
vector<pair<long long, long long> > mstEdges[MAX_N];
pair<long long, long long> dist[MAX_N];
bool added[MAX_N];
int qry(int a, int b) {
  long long ret = 0;
  if (depth[a] < depth[b]) {
    swap(a, b);
  }
  for (int d = MAX_D - 1; d >= 0; d--) {
    while (depth[a] - (1 << d) >= depth[b]) {
      ret = max(ret, lcamin[a][d]);
      a = lca[a][d];
    }
  }
  assert(depth[a] == depth[b]);
  for (int d = MAX_D - 1; d >= 0; d--) {
    while (lca[a][d] != lca[b][d]) {
      ret = max(ret, lcamin[a][d]);
      ret = max(ret, lcamin[b][d]);
      a = lca[a][d];
      b = lca[b][d];
    }
  }
  while (a != b) {
    ret = max(ret, lcamin[a][0]);
    ret = max(ret, lcamin[b][0]);
    a = lca[a][0];
    b = lca[b][0];
  }
  return ret;
}
void buildlca() {
  memset(depth, 1, sizeof(depth));
  queue<int> q;
  q.push(1);
  depth[1] = 0;
  lca[1][0] = 1;
  while ((int)(q).size()) {
    int curr = q.front();
    q.pop();
    for (pair<long long, long long> out : mstEdges[curr]) {
      if (depth[out.first] > 1 + depth[curr]) {
        depth[out.first] = 1 + depth[curr];
        lca[out.first][0] = curr;
        lcamin[out.first][0] = out.second;
        q.push(out.first);
      }
    }
  }
  for (int d = 1; d < MAX_D; d++) {
    for (int i = 1; i <= n; i++) {
      lca[i][d] = lca[lca[i][d - 1]][d - 1];
      lcamin[i][d] = max(lcamin[i][d - 1], lcamin[lca[i][d - 1]][d - 1]);
    }
  }
}
typedef pair<pair<long long, long long>, int> vertex;
void mst() {
  for (int i = 2; i <= n; i++) dist[i] = {1e18, 1e18};
  dist[1] = {0, 1};
  priority_queue<vertex> q;
  q.push(vertex({0, 1}, 1));
  added[1] = true;
  int adds = 0;
  while ((int)(q).size()) {
    vertex curr = q.top();
    q.pop();
    int currv = curr.second;
    int src = curr.first.second;
    if (dist[currv].first != -curr.first.first) continue;
    if (currv <= k && !added[currv]) {
      adds++;
      added[currv] = true;
      mstEdges[currv].push_back({dist[currv].second, dist[currv].first});
      mstEdges[dist[currv].second].push_back({curr.second, dist[currv].first});
      dist[currv] = {0, currv};
      src = currv;
    }
    for (pair<int, int> out : allEdges[currv]) {
      int nd = out.first;
      long long nw = out.second + dist[currv].first;
      if (pair<long long, long long>(nw, src) < dist[nd]) {
        dist[nd] = {nw, src};
        q.push(vertex({-nw, src}, nd));
      }
    }
  }
  assert(adds == k - 1);
  buildlca();
}
void solve() {
  cin >> n >> m >> k >> qq;
  while (m--) {
    int a, b, w;
    cin >> a >> b >> w;
    allEdges[a].push_back({b, w});
    allEdges[b].push_back({a, w});
  }
  mst();
  while (qq--) {
    int a, b;
    cin >> a >> b;
    cout << qry(a, b) << "\n";
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  solve();
}
