#include <bits/stdc++.h>
using namespace std;
long long N, K, M, Q;
long long A, B, C;
vector<pair<long long, long long> > AdjList[100005];
long long cdist[100005];
priority_queue<pair<long long, long long>, vector<pair<long long, long long> >,
               greater<pair<long long, long long> > >
    pq;
vector<pair<long long, pair<long long, long long> > > EdgeList;
long long par[100005], w[100005], sz[100005];
long long lca[100005][20], mlca[100005][20], depth[100005];
void dfs(int x, int p, int v) {
  lca[x][0] = p;
  mlca[x][0] = v;
  for (int i = 1; i < 20; ++i) {
    lca[x][i] = lca[lca[x][i - 1]][i - 1];
    mlca[x][i] = max(mlca[x][i - 1], mlca[lca[x][i - 1]][i - 1]);
  }
  for (auto it : AdjList[x]) {
    if (it.first == p) continue;
    depth[it.first] = depth[x] + 1;
    dfs(it.first, x, it.second);
  }
}
long long get_mdist(int x, int y) {
  long long md = 0;
  if (depth[x] < depth[y]) swap(x, y);
  int d = depth[x] - depth[y];
  for (int i = 0; i < 20; ++i) {
    if (d & (1 << i)) {
      md = max(md, mlca[x][i]);
      x = lca[x][i];
    }
  }
  if (x == y) return md;
  for (int i = 19; i >= 0; --i) {
    if (lca[x][i] != lca[y][i]) {
      md = max(md, max(mlca[x][i], mlca[y][i]));
      x = lca[x][i];
      y = lca[y][i];
    }
  }
  return max(md, max(mlca[x][0], mlca[y][0]));
}
int find_par(int x) {
  if (par[x] != x) par[x] = find_par(par[x]);
  return par[x];
}
bool merg(int x, int y, long long v) {
  int X = find_par(x), Y = find_par(y);
  if (X == Y) return false;
  if (sz[X] < sz[Y]) swap(X, Y);
  sz[X] += sz[Y];
  par[Y] = X;
  return true;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> M >> K >> Q;
  for (int i = 1; i <= M; ++i) {
    cin >> A >> B >> C;
    AdjList[A].push_back(pair<long long, long long>(B, C));
    AdjList[B].push_back(pair<long long, long long>(A, C));
  }
  for (int i = 1; i <= N; ++i) {
    par[i] = i;
    w[i] = 0;
    sz[i] = 1;
  }
  for (int i = K + 1; i <= N; ++i) cdist[i] = 1e16;
  for (int i = 1; i <= K; ++i) pq.push(pair<long long, long long>(0, i));
  while (!pq.empty()) {
    pair<long long, long long> x = pq.top();
    pq.pop();
    if (x.first != cdist[x.second]) continue;
    for (auto it : AdjList[x.second]) {
      if (cdist[it.first] > cdist[x.second] + it.second) {
        cdist[it.first] = cdist[x.second] + it.second;
        pq.push(pair<long long, long long>(cdist[it.first], it.first));
      }
    }
  }
  for (int i = 1; i <= N; ++i) {
    for (int k = 0; k < AdjList[i].size(); ++k) {
      EdgeList.push_back(pair<long long, pair<long long, long long> >(
          AdjList[i][k].second + cdist[i] + cdist[AdjList[i][k].first],
          pair<long long, long long>(i, AdjList[i][k].first)));
    }
  }
  for (int i = 1; i <= N; ++i) {
    AdjList[i].clear();
  }
  sort(EdgeList.begin(), EdgeList.end());
  for (auto it : EdgeList) {
    if (merg(it.second.first, it.second.second, it.first)) {
      AdjList[it.second.first].push_back(
          pair<long long, long long>(it.second.second, it.first));
      AdjList[it.second.second].push_back(
          pair<long long, long long>(it.second.first, it.first));
    }
  }
  dfs(1, 0, 1e9);
  for (int i = 1; i <= Q; ++i) {
    cin >> A >> B;
    cout << get_mdist(A, B) << '\n';
  }
}
