#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct Node {
  int v;
  long long weight;
  Node() {}
  Node(int a, long long b) {
    v = a;
    weight = b;
  }
};
int f[maxn], cnt[maxn];
long long w[maxn];
Node g[maxn];
int n, m, p, q, t;
int ea, eb;
bool operator<(Node a, Node b) { return a.weight > b.weight; }
int find(int x) {
  if (x != f[x]) f[x] = find(f[x]);
  return f[x];
}
void merge(int a, int b, int c) {
  int x = find(a), y = find(b);
  if (x == y) {
    w[y] = w[y] + c;
  } else {
    f[x] = y;
    cnt[y] = cnt[y] + cnt[x];
    w[y] = w[y] + c + w[x];
  }
}
void solve() {
  priority_queue<Node> que;
  vector<pair<int, int> > ans;
  for (int i = 1; i <= t; i++) {
    que.push(g[i]);
  }
  while (p) {
    if (t == q) {
      if (ea == -1) {
        puts("NO");
        return;
      }
      p--;
      ans.push_back(make_pair(ea, eb));
      continue;
    }
    Node a = que.top();
    que.pop();
    Node b = que.top();
    que.pop();
    p--;
    Node big =
        Node(a.v, a.weight + b.weight +
                      min((long long)1000000000, a.weight + b.weight + 1));
    que.push(big);
    ans.push_back(make_pair(a.v, b.v));
    ea = a.v;
    eb = b.v;
    t--;
  }
  if (t == q) {
    puts("YES");
    for (int i = 0; i < (int)ans.size(); i++) {
      printf("%d %d\n", ans[i].first, ans[i].second);
    }
  } else {
    puts("NO");
  }
}
int main() {
  while (scanf("%d%d%d%d", &n, &m, &p, &q) != EOF) {
    for (int i = 1; i <= n; i++) {
      f[i] = i;
      cnt[i] = 1;
    }
    memset(w, 0, sizeof(w));
    ea = -1;
    eb = -1;
    while (m--) {
      int a, b, c;
      scanf("%d%d%d", &a, &b, &c);
      ea = a;
      eb = b;
      merge(a, b, c);
    }
    t = 0;
    for (int i = 1; i <= n; i++) {
      if (f[i] == i) {
        t++;
        g[t] = Node(i, w[i]);
      }
    }
    if (t < q) {
      puts("NO");
      continue;
    }
    solve();
  }
  return 0;
}
