#include <bits/stdc++.h>
using namespace std;
const long long maxn = 1e5 + 7, inf = 1e9;
long long n, m, p, q, sz[maxn], fa[maxn], tot;
struct node {
  long long x, sz;
  bool operator<(const node& rhs) const { return sz > rhs.sz; }
} t1, t2;
priority_queue<node> Q;
long long find(long long x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
long long merge(long long x, long long y, long long l) {
  x = find(x), y = find(y);
  if (x == y)
    sz[x] += l;
  else
    fa[x] = y, sz[y] += l + sz[x], tot--;
}
int main() {
  scanf("%lld%lld%lld%lld", &n, &m, &p, &q), tot = n;
  for (long long i = 1; i <= n; ++i) fa[i] = i;
  for (long long i = 1, x, y, l; i <= m; ++i)
    scanf("%lld%lld%lld", &x, &y, &l), merge(x, y, l);
  if (tot - p > q || tot < q || (!m && !(q - n) && p))
    return 0 * puts("NO");
  else
    puts("YES");
  for (int i = 1; i <= n; ++i)
    if (find(i) == i) Q.push((node){i, sz[fa[i]]});
  while (tot > q)
    t1 = Q.top(), Q.pop(), t2 = Q.top(), Q.pop(), p--, tot--,
    printf("%lld %lld\n", t1.x, t2.x), fa[t2.x] = t1.x,
    sz[t1.x] += min(inf, t1.sz + t2.sz + 1) + t2.sz,
    Q.push((node){t1.x, sz[t1.x]});
  for (tot = 1; tot <= n; ++tot)
    if (find(tot) != tot) break;
  while (p--) printf("%lld %lld\n", tot, fa[tot]);
  return 0;
}
