#include <bits/stdc++.h>
using namespace std;
void addmod(int &a, long long b) {
  a = (a + b);
  if (a >= 1000000007) a -= 1000000007;
}
void mulmod(int &a, long long b) { a = (a * b) % 1000000007; }
template <class T>
bool domin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <class T>
bool domax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
int gi() {
  int a;
  scanf("%d", &a);
  return a;
}
long long gll() {
  long long a;
  scanf("%lld", &a);
  return a;
}
class disjoint {
 public:
  vector<int> p;
  vector<long long> sz;
  disjoint(int n) : p(n, -1), sz(n, 0) {}
  int find(int ix) { return p[ix] < 0 ? ix : p[ix] = find(p[ix]); }
  bool join(int a, int b) {
    if ((a = find(a)) == (b = find(b))) return false;
    if (p[a] < p[b]) swap(a, b);
    p[a] += p[b];
    sz[a] += sz[b];
    p[b] = a;
    return true;
  }
  void add(int a, int b, long long s) {
    join(a, b);
    a = find(a);
    sz[a] += s;
  }
};
struct comp {
 public:
  bool operator()(pair<int, long long> a, pair<int, long long> b) {
    return a.second > b.second;
  }
};
class graphwal {
 public:
  int n, m, p, q;
  vector<vector<pair<int, long long>>> ed;
  vector<bool> vis;
  disjoint dj;
  graphwal(int n, int m, int p, int q)
      : n(n), m(m), p(p), q(q), ed(n), vis(n, false), dj(n) {}
  void add(int a, int b, long long w) {
    ed[a].push_back(make_pair(b, w));
    ed[b].push_back(make_pair(a, w));
  }
  void load() {
    for (int i = 0; i < m; i++) {
      int a = gi(), b = gi();
      long long w = gll();
      add(a - 1, b - 1, w);
      dj.add(a - 1, b - 1, w);
    }
  }
  void doit() {
    vector<pair<int, int>> ans;
    priority_queue<pair<int, long long>, vector<pair<int, long long>>, comp> pq;
    for (int i = 0; i < n; i++)
      if (dj.find(i) == i) {
        pq.push({i, dj.sz[i]});
      }
    while (pq.size() > q && p > 0) {
      pair<int, long long> na = pq.top();
      pq.pop();
      pair<int, long long> nb = pq.top();
      pq.pop();
      p--;
      ans.push_back({na.first, nb.first});
      long long nsz =
          min((long long)1e9, dj.sz[na.first] + dj.sz[nb.first] + 1);
      dj.add(na.first, nb.first, nsz);
      na.first = dj.find(na.first);
      na.second = dj.sz[na.first];
      pq.push(na);
    }
    if (pq.size() != q) {
      printf("NO\n");
      return;
    }
    int a = -1, b = -1;
    for (int i = 0; i < n && a == -1; i++)
      if (dj.find(i) != i) {
        a = i, b = dj.find(i);
      }
    if (a == -1 && p > 0) {
      printf("NO\n");
      return;
    }
    printf("YES\n");
    for (auto i : ans) {
      printf("%d %d\n", i.first + 1, i.second + 1);
    }
    for (int i = 0; i < p; i++) {
      printf("%d %d\n", a + 1, b + 1);
    }
  }
};
int main() {
  int n = gi(), m = gi(), p = gi(), q = gi();
  graphwal g(n, m, p, q);
  g.load();
  g.doit();
  return 0;
}
