#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, P, Q;
int p[N];
long long sum[N];
long long res;
pair<int, int> temp;
int find(int x) {
  if (p[x] != x) p[x] = find(p[x]);
  return p[x];
}
int main() {
  cin >> n >> m >> P >> Q;
  for (int i = 1; i <= n; i++) p[i] = i, sum[i] = 0;
  for (int i = 0; i < m; i++) {
    int a, b, s;
    scanf("%d%d%d", &a, &b, &s);
    temp = {a, b};
    int pa = find(a), pb = find(b);
    if (pa != pb) {
      p[pa] = pb;
      sum[pb] += sum[pa];
    }
    sum[pb] += s;
  }
  priority_queue<pair<long long, int>, vector<pair<long long, int>>,
                 greater<pair<long long, int>>>
      heap;
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (i == find(i)) {
      cnt++;
      heap.push({sum[i], i});
    }
  }
  if (cnt < Q) return 0 * printf("NO\n");
  auto check = []() {
    for (int i = 1; i <= n; i++)
      if (sum[i]) return false;
    return true;
  };
  if (cnt == Q && P > 0 && check()) return 0 * printf("NO\n");
  if (P == 0 && cnt != Q) return 0 * printf("NO\n");
  if (cnt - P > Q) return 0 * printf("NO\n");
  puts("YES");
  int merge_cnt = 0;
  while (heap.size() > Q) {
    merge_cnt++;
    auto x = heap.top();
    heap.pop();
    auto y = heap.top();
    heap.pop();
    int a = x.second, b = y.second;
    int pa = find(a), pb = find(b);
    cout << pa << " " << pb << endl;
    temp = {pa, pb};
    p[pa] = pb;
    res += min((long long)1e9, sum[pb] + sum[pa] + 1);
    sum[pb] = sum[pb] * 2 + sum[pa] * 2 + 1;
    heap.push({sum[pb], pb});
  }
  int left_cnt = P - merge_cnt;
  while (left_cnt--) printf("%d %d\n", temp.first, temp.second);
  return 0;
}
