#include <bits/stdc++.h>
using namespace std;
const int maxn = 100011, inf = 1e9;
inline int read() {
  char ch = getchar();
  int x = 0;
  while (!isdigit(ch)) ch = getchar();
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return x;
}
int n, m, p, q, fa[maxn];
long long size[maxn];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void init() {
  n = read();
  m = read();
  p = read();
  q = read();
  int a, b, c;
  for (int i = 1; i <= n; ++i) fa[i] = i;
  for (int i = 1; i <= m; ++i) {
    a = read();
    b = read();
    c = read();
    if (find(a) != find(b)) {
      size[find(a)] += size[find(b)] + c;
      fa[find(b)] = find(a);
    } else
      size[find(a)] += c;
  }
}
struct ltk {
  int p;
  long long x;
  ltk() {}
  ltk(int p_, long long x_) {
    p = p_;
    x = x_;
  }
  bool operator<(ltk const &a) const { return x > a.x; }
};
priority_queue<ltk> w;
bool vis[maxn];
void work() {
  int t;
  for (int i = 1; i <= n; ++i)
    if (!vis[t = find(i)]) {
      w.push(ltk(t, size[t]));
      vis[t] = 1;
    }
  if (w.size() < q || w.size() - q > p ||
      ((w.size() == q && p != 0) && m == 0)) {
    puts("NO");
    return;
  }
  puts("YES");
  int tmp = p - w.size() + q;
  while (w.size() > q) {
    if (w.empty()) break;
    ltk a = w.top();
    w.pop();
    if (w.empty()) break;
    ltk b = w.top();
    w.pop();
    size[a.p] =
        size[a.p] + size[b.p] + min(size[a.p] + size[b.p] + 1, 1000000000LL);
    fa[b.p] = a.p;
    printf("%d %d\n", a.p, b.p);
    w.push(ltk(a.p, size[a.p]));
  }
  int x;
  for (x = 1; x <= n; ++x)
    if (find(x) != x) break;
  while (tmp--) printf("%d %d\n", x, find(x));
}
int main() {
  init();
  work();
  return 0;
}
