#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
long long pr[((long long)(1e5 + 900))];
long long sz[((long long)(1e5 + 900))];
long long par(long long x) {
  if (pr[x] == x)
    return x;
  else
    return pr[x] = par(pr[x]);
}
set<pair<long long, long long> > st;
vector<pair<long long, long long> > pas;
void join(long long x, long long y, long long c = -1) {
  x = par(x);
  y = par(y);
  if (c == -1) {
    if (x == y)
      c = 1000;
    else
      c = min(1000000000ll, sz[x] + sz[y] + 1);
  }
  if (x == y) {
    st.erase({sz[x], x});
    sz[x] += c;
    st.insert({sz[x], x});
    return;
  }
  st.erase({sz[x], x});
  st.erase({sz[y], y});
  sz[x] = sz[x] + sz[y] + c;
  pr[y] = x;
  st.insert({sz[x], x});
}
int main() {
  ios::sync_with_stdio(0);
  long long n, m, P, Q, k, p, c;
  cin >> n >> m >> P >> Q;
  if (n == 1 && P) {
    cout << "NO";
    return 0;
  } else if (n == 1) {
    cout << "YES";
    return 0;
  }
  for (int i = 1; i <= n; i++) pr[i] = i, st.insert({0, i});
  for (int i = 0; i < m; i++) {
    cin >> k >> p >> c;
    join(k, p, c);
  }
  while (P && st.size() > Q) {
    auto a = *st.begin();
    auto b = *++st.begin();
    join(a.second, b.second);
    pas.push_back({a.second, b.second});
    P--;
  }
  for (int i = 1; i <= n; i++) {
    if (pr[i] != i)
      while (P > 0) P--, pas.push_back({i, pr[i]});
  }
  if (P == 0 && st.size() == Q) {
    cout << "YES" << endl;
    for (auto x : pas) cout << x.first << " " << x.second << endl;
  } else
    cout << "NO";
}
