#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int n, m, k, q;
int dis[N];
bool vis[N];
int cnt;
struct node {
int u, v, c;
} edge[N * 6];
vector < pair <int, int> > g[N];
vector < pair <int, int> > e[N];
void dijkstra () {
for (int i = 1; i <= n; i++) dis[i] = INF;
priority_queue < pair <int, int> > q;
for (int i = 1; i <= k; i++) dis[i] = 0, q.push (make_pair (0, i));
while (!q.empty()) {
int u = q.top().second;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i].first;
int c = g[u][i].second;
if (dis[v] > dis[u] + c) {
dis[v] = dis[u] + c;
q.push (make_pair (-dis[v], v));
}
}
}
for (int u = 1; u <= n; u++)
for (int i = 0; i < g[u].size(); i++)
edge[++cnt] = (node) {u, g[u][i].first, g[u][i].second + dis[u] + dis[g[u][i].first]};
}
int fa[N];
int find (int x) {
return (fa[x] == x ? x : fa[x] = find (fa[x]));
}
bool cmp (node a, node b) {
return a.c < b.c;
}
void kruskal () {
int len = 1;
sort (edge + 1, edge + 1 + cnt, cmp);
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 1; i <= cnt; i++) {
int c = edge[i].c;
int x = edge[i].u;
int y = edge[i].v;
int fx = find (x);
int fy = find (y);
if (fx == fy) continue;
fa[fx] = fy;
len++;
e[x].push_back (make_pair (y, c));
e[y].push_back (make_pair (x, c));
if (len == n) return;
}
}
int dep[N];
int maxn[N][21];
int f[N][21];
void dfs (int u, int father) {
f[u][0] = father;
dep[u] = dep[father] + 1;
for (int i = 0; i < e[u].size(); i++) {
int v = e[u][i].first;
int c = e[u][i].second;
if (v == father) continue;
maxn[v][0] = c;
dfs (v, u);
}
for (int i = 1; i <= 20; i++)
f[u][i] = f[f[u][i - 1]][i - 1], maxn[u][i] = max (maxn[u][i - 1], maxn[f[u][i - 1]][i - 1]);
}
void slove () {
dijkstra ();
kruskal ();
dfs (1, 0);
}
int LCA (int x, int y) {
int ans = 0;
if (dep[x] < dep[y]) swap (x, y);
for (int i = 20; i >= 0; i--)
if (dep[f[x][i]] > dep[y]) ans = max (ans, maxn[x][i]), x = f[x][i];
ans = max (ans, maxn[x][0]);
x = f[x][0];
if (x == y) return ans;
for (int i = 20; i >= 0; i--)
if (f[x][i] != f[y][i]) ans = max (ans, max (maxn[x][i], maxn[y][i])), x = f[x][i], y = f[y][i];
ans = max (ans, max (maxn[x][0], maxn[y][0]));
return ans;
}
signed main () {
// freopen ("robot.in", "r", stdin);
// freopen ("robot.out", "w", stdout);
ios :: sync_with_stdio (false);
cin.tie (0);
cout.tie (0);
cin >> n >> m >> k >> q;
for (int i = 1; i <= m; i++) {
int u, v, c;
cin >> u >> v >> c;
g[u].push_back (make_pair (v, c));
g[v].push_back (make_pair (u, c));
}
slove ();
while (q--) {
int x, y;
cin >> x >> y;
cout << LCA (x, y) << endl;
}
return 0;
}