#include <bits/stdc++.h>
using namespace std;
template <class T>
void rd(T &x) {
  x = 0;
  int f = 1;
  char c;
  while (!isdigit(c = getchar()))
    if (c == '-') f = -1;
  do {
    x = (x << 3) + (x << 1) + (c ^ 48);
  } while (isdigit(c = getchar()));
  x *= f;
}
const int N = 1e5 + 5;
const long long com = 1e9;
int n, m, p, q, tot, fa[N], tu, tv;
long long cost[N];
vector<pair<int, int> > Vec;
int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); }
void link(int u, int v, int w) {
  u = findset(u), v = findset(v);
  if (u == v)
    cost[u] += w;
  else
    fa[u] = v, cost[v] += cost[u] + w;
}
priority_queue<pair<long long, int>, vector<pair<long long, int> >,
               greater<pair<long long, int> > >
    Que;
int main() {
  rd(n), rd(m), rd(p), rd(q);
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1, x, y, z; i <= m; i++)
    rd(x), rd(y), rd(z), link(x, y, z), tu = x, tv = y;
  for (int i = 1; i <= n; i++)
    if (findset(i) == i) Que.push({cost[i], i}), tot++;
  int res = tot - q;
  if (res < 0 || res > p) return !printf("NO");
  while (res--) {
    p--;
    int t1 = findset(Que.top().second);
    Que.pop();
    int t2 = findset(Que.top().second);
    Que.pop();
    Vec.push_back({t1, t2});
    tu = t1, tv = t2;
    long long w = min(com, cost[t1] + cost[t2] + 1);
    cost[t2] += cost[t1] + w;
    Que.push({cost[t2], t2});
  }
  if (p && !tu) return !printf("NO");
  while (p--) Vec.push_back({tu, tv});
  printf("YES\n");
  for (auto it : Vec) printf("%d %d\n", it.first, it.second);
  return 0;
}
