#include <bits/stdc++.h>
using namespace std;
struct unio {
  unio* parent;
  long long rank;
  long long ind;
  long long lsum;
  unio* head() {
    if (parent != parent->parent) {
      parent = parent->head();
    }
    return parent;
  }
  void merge(unio* sec, long long sum) {
    unio* fir = head();
    sec = sec->head();
    if (fir->rank > sec->rank) {
      sec->parent = fir;
      if (fir != sec) {
        fir->lsum += sec->lsum;
      }
      fir->lsum += sum;
    } else if (fir->rank < sec->rank) {
      fir->parent = sec;
      if (fir != sec) {
        sec->lsum += sum;
      }
      sec->lsum += fir->lsum;
    } else {
      sec->parent = fir;
      if (fir != sec) {
        fir->lsum += sec->lsum;
      }
      fir->lsum += sum;
      fir->rank++;
    }
  }
};
int main() {
  ios::sync_with_stdio(false);
  long long v, e, n, r;
  cin >> v >> e >> n >> r;
  unio un[v];
  for (long long i = 0; i < v; i++) {
    un[i].parent = &un[i];
    un[i].rank = 0;
    un[i].ind = i;
    un[i].lsum = 0;
  }
  for (long long i = 0; i < e; i++) {
    long long f, s, l;
    cin >> f >> s >> l;
    f--, s--;
    un[f].merge(&un[s], l);
  }
  long long startreg = 0, endreg = r;
  priority_queue<pair<long long, long long>,
                 vector<pair<long long, long long> >,
                 greater<pair<long long, long long> > >
      pq;
  for (long long i = 0; i < v; i++) {
    if (un[i].head()->ind == un[i].ind) {
      startreg++;
      pq.push(make_pair(un[i].lsum, i));
    }
  }
  long long regions = startreg;
  vector<pair<long long, long long> > gen;
  while (pq.size() >= 2 and regions > r) {
    long long f = pq.top().second;
    pq.pop();
    long long s = pq.top().second;
    pq.pop();
    long long sum = un[f].lsum + un[s].lsum + 1;
    sum = min(sum, 1000000000LL);
    un[f].merge(&un[s], sum);
    gen.push_back(make_pair(f, s));
    pq.push(make_pair(un[f].head()->lsum, un[f].head()->ind));
    regions--;
  }
  long long found = 0, secfound = 0;
  for (long long i = 0; i < v; i++) {
    if (un[i].head()->ind != un[i].ind) {
      found = i;
      secfound = un[i].head()->ind;
      break;
    }
  }
  for (long long i = 0; i < n - (startreg - endreg); i++) {
    gen.push_back(make_pair(found, secfound));
  }
  bool good = true;
  long long actualregions = 0;
  for (long long i = 0; i < v; i++) {
    if (un[i].head()->ind == i) {
      actualregions++;
    }
  }
  for (long long i = 0; i < gen.size(); i++) {
    if (gen[i].first == gen[i].second) {
      good = false;
      break;
    }
  }
  if (actualregions != r) {
    good = false;
  }
  if (endreg > startreg) {
    good = false;
  }
  if (gen.size() != n) {
    good = false;
  }
  if (good) {
    cout << "YES" << '\n';
    for (long long i = 0; i < gen.size(); i++) {
      cout << gen[i].first + 1 << ' ' << gen[i].second + 1 << '\n';
    }
  } else {
    cout << "NO";
  }
  return 0;
}
