#include <bits/stdc++.h>
using namespace std;
const long long mo = 1e9 + 7;
const long long INF = 0x7f7f7f7f;
template <typename _T>
_T Fabs(_T x) {
  return x < 0 ? -x : x;
}
int n, m, p, q, fa[100005], idx, tot;
;
long long sum[100005];
void makeSet(int x) {
  for (int i = 1; i <= x; i++) fa[i] = i;
}
int findSet(int x) { return fa[x] == x ? fa[x] : fa[x] = findSet(fa[x]); }
void unionSet(int a, int b) {
  int u = findSet(a), v = findSet(b);
  if (u != v) fa[u] = v, tot--;
}
struct ming {
  int x;
  long long siz;
  bool friend operator<(const ming &x, const ming &y) { return x.siz > y.siz; }
};
priority_queue<ming> q1;
signed main() {
  scanf("%d %d %d %d", &n, &m, &p, &q);
  makeSet(n);
  tot = n;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    u = findSet(u), v = findSet(v);
    if (u == v)
      sum[u] += 1ll * w;
    else
      unionSet(u, v), sum[v] += 1ll * w + 1ll * sum[u];
  }
  for (int i = 1; i <= n; i++)
    if (fa[i] == i) q1.push((ming){i, sum[i]});
  if (tot - p > q || tot < q || (!m && !(q - n) && p)) {
    puts("NO");
    return 0;
  }
  puts("YES");
  while (tot > q) {
    int t1 = q1.top().x;
    q1.pop();
    int t2 = q1.top().x;
    q1.pop();
    unionSet(t1, t2);
    p--;
    sum[t2] += sum[t1] + min((long long)1e9, sum[t2] + sum[t1] + 1LL);
    printf("%d %d\n", t1, t2);
    q1.push((ming){t2, sum[t2]});
  }
  for (tot = 1; tot <= n; tot++)
    if (findSet(tot) != tot) break;
  while (p) printf("%d %d\n", tot, fa[tot]), p--;
  return 0;
}
