#include <bits/stdc++.h>
using namespace std;
inline long long mod(long long n, long long m) {
  long long ret = n % m;
  if (ret < 0) ret += m;
  return ret;
}
long long gcd(long long a, long long b) { return (b == 0 ? a : gcd(b, a % b)); }
long long exp(long long a, long long b, long long m) {
  if (b == 0) return 1;
  if (b == 1) return mod(a, m);
  long long k = mod(exp(a, b / 2, m), m);
  if (b & 1) {
    return mod(a * mod(k * k, m), m);
  } else
    return mod(k * k, m);
}
long long n, m, k, Q;
vector<pair<long long, long long> > adj[100100];
pair<long long, long long> gDsu[100100];
long long dist[100100];
long long pai[100100];
long long sz[100100];
long long vis[100100];
const long long inf = 1e15;
struct aresta {
  long long a, b, c;
};
struct query {
  long long a, b, i;
};
long long find(long long x) {
  return (x == pai[x] ? x : pai[x] = find(pai[x]));
}
void join(long long a, long long b, long long cost) {
  a = find(a);
  b = find(b);
  if (a == b) return;
  if (sz[a] < sz[b]) swap(a, b);
  sz[a] += sz[b];
  pai[b] = a;
  gDsu[b] = (pair<long long, long long>(a, cost));
}
long long cmp(aresta a, aresta b) { return a.c < b.c; }
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> m >> k >> Q;
  vector<aresta> v;
  for (long long i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    adj[a].push_back(pair<long long, long long>(b, c));
    adj[b].push_back(pair<long long, long long>(a, c));
    aresta aux = {a, b, c};
    v.push_back(aux);
  }
  priority_queue<pair<long long, long long>,
                 vector<pair<long long, long long> >,
                 greater<pair<long long, long long> > >
      q;
  for (long long i = 1; i <= n; i++) {
    dist[i] = inf;
    if (i <= k) {
      dist[i] = 0;
      q.push(pair<long long, long long>(0, i));
    }
  }
  while (!q.empty()) {
    long long atual = q.top().second;
    q.pop();
    if (vis[atual]) continue;
    vis[atual] = true;
    for (long long i = 0; i < (long long)adj[atual].size(); i++) {
      long long u = adj[atual][i].first;
      long long d = adj[atual][i].second;
      if (dist[u] > dist[atual] + d) {
        dist[u] = dist[atual] + d;
        if (!vis[u]) q.push(pair<long long, long long>(dist[u], u));
      }
    }
  }
  for (long long i = 0; i < m; i++) {
    v[i].c = dist[v[i].a] + dist[v[i].b] + v[i].c;
  }
  sort(v.begin(), v.end(), cmp);
  for (long long i = 1; i <= n; i++) {
    pai[i] = i;
    sz[i] = 1;
  }
  for (long long i = 0; i < m; i++) {
    long long a = v[i].a;
    long long b = v[i].b;
    if (find(a) != find(b)) {
      join(a, b, v[i].c);
    }
  }
  long long Opai = find(1);
  while (Q--) {
    long long a, b;
    cin >> a >> b;
    long long mx = 0;
    while (a != Opai) {
      mx = max(mx, gDsu[a].second);
      a = gDsu[a].first;
    }
    while (b != Opai) {
      mx = max(mx, gDsu[b].second);
      b = gDsu[b].first;
    }
    cout << mx << "\n";
  }
}
