#include <bits/stdc++.h>
using namespace std;
const long long maxn = 3e5 + 10;
const long long inf = 1e18;
const long long mod = 1e9 + 7;
long long n, m, k, qp, u[maxn], v[maxn], w[maxn], uu[maxn], vv[maxn], par[maxn],
    X, Y;
vector<pair<long long, long long> > G[maxn];
vector<long long> Gp[maxn];
set<pair<long long, long long> > st;
long long s[maxn], d[maxn], sz[maxn], U;
vector<pair<long long, pair<long long, long long> > > vc, q[maxn];
pair<long long, pair<long long, long long> > p;
bool visited[maxn];
vector<pair<long long, long long> > vc2;
vector<long long> comp[maxn];
int get_root(int x) {
  if (par[x] == x) return x;
  return par[x] = get_root(par[x]);
}
void merge(int x, int y, int kk) {
  X = get_root(x);
  Y = get_root(y);
  if (X == Y) return;
  if (sz[X] >= sz[Y]) {
    par[Y] = X;
    sz[X] += sz[Y];
    for (int j = 0; j != comp[Y].size(); j++) {
      for (int l = 0; l != q[comp[Y][j]].size(); l++) {
        if (q[comp[Y][j]][l].second.second == -1 &&
            get_root(q[comp[Y][j]][l].second.first) == X)
          q[comp[Y][j]][l].second.second = kk;
      }
      comp[X].push_back(comp[Y][j]);
    }
  } else {
    par[X] = Y;
    sz[Y] += sz[X];
    for (int j = 0; j != comp[Y].size(); j++) {
      for (int l = 0; l != q[comp[X][j]].size(); l++) {
        if (q[comp[X][j]][l].second.second == -1 &&
            get_root(q[comp[X][j]][l].second.first) == Y)
          q[comp[X][j]][l].second.second = kk;
      }
      comp[Y].push_back(comp[X][j]);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> k >> qp;
  for (int i = 1; i <= k; i++) {
    st.insert({0, i});
    d[i] = 0;
    par[i] = i;
    comp[i].push_back(i);
  }
  for (int i = k + 1; i <= n; i++) {
    d[i] = inf;
  }
  for (int i = 1; i <= m; i++) {
    cin >> u[i] >> v[i] >> w[i];
    G[u[i]].push_back({v[i], w[i]});
    G[v[i]].push_back({u[i], w[i]});
  }
  for (int i = 1; i <= qp; i++) {
    cin >> uu[i] >> vv[i];
    p.first = i;
    p.second.first = vv[i];
    p.second.second = -1;
    q[uu[i]].push_back(p);
    p.second.first = uu[i];
    q[vv[i]].push_back(p);
  }
  while (!st.empty()) {
    U = st.begin()->second;
    st.erase(st.begin());
    for (int j = 0; j != G[U].size(); j++) {
      if (d[G[U][j].first] >= d[U] + G[U][j].second) {
        st.erase({d[G[U][j].first], G[U][j].first});
        d[G[U][j].first] = d[U] + G[U][j].second;
        st.insert({d[G[U][j].first], G[U][j].first});
        par[G[U][j].first] = par[U];
      }
    }
  }
  for (int j = 1; j <= m; j++) {
    if (get_root(u[j]) != get_root(v[j])) {
      p.first = w[j] + d[u[j]] + d[v[j]];
      p.second.first = u[j];
      p.second.second = v[j];
      vc.push_back(p);
    }
  }
  sort(vc.begin(), vc.end());
  for (int i = 0; i < vc.size(); i++) {
    merge(vc[i].second.first, vc[i].second.second, vc[i].first);
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j != q[i].size(); j++) {
      if (q[i][j].second.second != -1)
        vc2.push_back({q[i][j].first, q[i][j].second.second});
    }
  }
  sort(vc2.begin(), vc2.end());
  for (int i = 0; i != vc2.size(); i++) {
    if (i == 0 || (vc2[i].first != vc2[i - 1].first)) {
      cout << vc2[i].second << endl;
    }
  }
  return 0;
}
