#include <bits/stdc++.h>
using namespace std;
const int maxx = 600010;
const double pi = acos(-1.0);
const double eps = 1e-15;
struct node {
  int num;
  long long val;
  bool operator<(const node &X) const { return val > X.val; }
};
priority_queue<node> q;
int t, n, m, p, k, u, v;
int res = 0;
int b[maxx], fa[maxx], siz[maxx], vis[maxx];
long long w;
long long ans = 0, total = 0, sum = 0, cnt = 0;
long long a[maxx];
struct nod {
  int l, r;
} s[maxx];
int find(int x) {
  if (fa[x] == x) return x;
  return fa[x] = find(fa[x]);
}
int main() {
  scanf("%d%d%d%d", &n, &m, &p, &k);
  for (int i = 1; i <= n; i++) fa[i] = i, siz[i] = 1;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%lld", &u, &v, &w);
    int X = find(u), Y = find(v);
    if (X != Y)
      fa[X] = Y, a[Y] += a[X] + w, a[X] = 0, siz[Y] += siz[X], siz[X] = 0;
    else
      a[X] += w;
  }
  for (int i = 1; i <= n; i++) {
    int X = find(i);
    if (!vis[X])
      q.push(node{i, a[X]}), vis[X] = 1, total++, res = max(res, siz[X]);
  }
  if (total < k || total - p > k)
    printf("NO");
  else {
    if (res == 1 && total == k && p) {
      printf("NO");
      return 0;
    }
    while (total != k) {
      p--, total--;
      int n1 = q.top().num;
      long long v1 = q.top().val;
      q.pop();
      int n2 = q.top().num;
      long long v2 = q.top().val;
      q.pop();
      int X = find(n1), Y = find(n2);
      fa[X] = Y,
      a[Y] += a[X] + min((long long)1e9, (long long)(a[X] + a[Y] + 1)),
      a[X] = 0, siz[Y] += siz[X], siz[X] = 0;
      s[++cnt].l = X, s[cnt].r = Y;
      q.push(node{n1, a[Y]});
    }
    for (int i = 1; i <= n; i++) {
      int X = find(i);
      if (siz[X] >= 2) {
        for (int j = i + 1; j <= n; j++) {
          int Y = find(j);
          if (X == Y) {
            b[1] = i, b[2] = j;
            break;
          }
        }
        break;
      }
    }
    while (p--) s[++cnt].l = b[1], s[cnt].r = b[2];
    printf("YES\n");
    for (int i = 1; i <= cnt; i++) printf("%d %d\n", s[i].l, s[i].r);
  }
  return 0;
}
