#include <bits/stdc++.h>
using namespace std;
const long long maxn = 3e5 + 10;
const long long MAX = 30;
const long long inf = 0x3f3f3f3f;
vector<long long> a[maxn];
vector<long long> w[maxn];
long long dis[maxn];
long long belong[maxn];
priority_queue<pair<long long, long long> > q;
long long n, m, k, Q;
long long fa[maxn];
struct re {
  long long x, y, z;
} c[maxn], b[maxn];
bool cmp(re a, re b) { return a.z < b.z; }
long long find(long long k) {
  if (k == fa[k])
    return k;
  else
    return find(fa[k]);
}
void dijk() {
  for (long long i = (1); i <= (k); ++i) {
    q.push(make_pair(0, i));
    dis[i] = 0;
    belong[i] = i;
  }
  while (!q.empty()) {
    long long now = q.top().second;
    if (-q.top().first != dis[now]) {
      q.pop();
      continue;
    }
    q.pop();
    for (long long j = 0; j < a[now].size(); j++) {
      long long to = a[now][j];
      if (dis[to] > dis[now] + w[now][j]) {
        dis[to] = dis[now] + w[now][j];
        belong[to] = belong[now];
        q.push(make_pair(-dis[to], to));
      }
    }
  }
}
namespace LCA {
long long fa[maxn][MAX + 10];
long long dp[maxn][MAX + 10];
long long dep[maxn];
long long lg[maxn];
void dfs(long long now, long long fat) {
  fa[now][0] = fat;
  dep[now] = dep[fat] + 1;
  for (long long i = 0; i < a[now].size(); i++) {
    long long to = a[now][i];
    if (to == fat) continue;
    dp[to][0] = w[now][i];
    dfs(to, now);
  }
}
void init() {
  for (long long i = (1); i <= (n); ++i) {
    lg[i] = (long long)log2(i);
  }
  for (long long i = (1); i <= (MAX); ++i) {
    for (long long j = (1); j <= (n); ++j) {
      fa[j][i] = fa[fa[j][i - 1]][i - 1];
      dp[j][i] = max(dp[j][i], dp[fa[j][i - 1]][i - 1]);
    }
  }
}
long long lca(long long x, long long y) {
  long long maxx = 0;
  if (dep[y] > dep[x]) swap(x, y);
  while (dep[x] > dep[y]) {
    maxx = max(maxx, dp[x][lg[dep[x] - dep[y]]]);
    x = fa[x][lg[dep[x] - dep[y]]];
  }
  if (x == y) return maxx;
  for (long long i = (lg[dep[x]]); i >= (0); --i)
    if (fa[x][i] != fa[y][i]) {
      maxx = max(maxx, dp[x][i]);
      maxx = max(maxx, dp[y][i]);
      x = fa[x][i];
      y = fa[y][i];
    }
  return max(maxx, dp[x][0]);
}
}  // namespace LCA
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> k >> Q;
  for (long long i = (1); i <= (m); ++i) {
    long long x, y, z;
    cin >> x >> y >> z;
    b[i].x = x, b[i].y = y, b[i].z = z;
    a[x].push_back(y);
    w[x].push_back(z);
    a[y].push_back(x);
    w[y].push_back(z);
  }
  for (long long i = (1); i <= (n); ++i) dis[i] = INT_MAX;
  dijk();
  long long tot = 0;
  for (long long i = (1); i <= (m); ++i) {
    long long x = b[i].x, y = b[i].y, z = b[i].z;
    long long fax = belong[x], fay = belong[y];
    if (fax != fay) {
      tot++;
      c[tot].x = fax;
      c[tot].y = fay;
      c[tot].z = z + dis[x] + dis[y];
    }
  }
  sort(c + 1, c + 1 + tot, cmp);
  for (long long i = (1); i <= (k); ++i) a[i].clear(), w[i].clear();
  long long mark = 0;
  for (long long i = (1); i <= (k); ++i) fa[i] = i;
  for (long long i = (1); i <= (tot); ++i) {
    long long x = c[i].x, y = c[i].y, z = c[i].z;
    if (find(x) == find(y)) continue;
    fa[find(x)] = find(y);
    a[x].push_back(y);
    w[x].push_back(z);
    a[y].push_back(x);
    w[y].push_back(z);
    mark++;
    if (mark == k - 1) break;
  }
  LCA::dfs(1, 0);
  LCA::init();
  for (long long i = (1); i <= (Q); ++i) {
    long long x, y;
    cin >> x >> y;
    printf("%lld\n", LCA::lca(x, y));
  }
}
