#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << ' ' << *it << " = " << a;
  err(++it, args...);
}
inline void ip() {}
template <typename T, typename... Types>
inline void ip(T& var1, Types&... var2) {
  cin >> var1;
  ip(var2...);
}
template <typename T, typename U>
inline void min_self(T& x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
inline void max_self(T& x, U y) {
  if (x < y) x = y;
}
template <class T1, class T2>
ostream& operator<<(ostream& out, pair<T1, T2> pair) {
  return out << "(" << pair.first << ", " << pair.second << ")";
}
template <class T>
ostream& operator<<(ostream& out, vector<T> vec) {
  for (auto& v : vec) out << v << ' ';
  return out << "\n";
}
template <class T>
ostream& operator<<(ostream& out, set<T> vec) {
  out << "(";
  for (auto& v : vec) out << v << ", ";
  return out << ")";
}
template <class L, class R>
ostream& operator<<(ostream& out, map<L, R> vec) {
  out << "(";
  for (auto& v : vec) out << "[" << v.first << ", " << v.second << "]";
  return out << ")";
}
template <class A, class B>
istream& operator>>(istream& in, pair<A, B>& a) {
  return in >> a.first >> a.second;
}
template <class A>
istream& operator>>(istream& in, vector<A>& a) {
  for (A& i : a) in >> i;
  return in;
}
template <class Container>
void split(const std::string& str, Container& cont, char delim = ',') {
  stringstream ss(str);
  string token;
  while (std::getline(ss, token, delim)) {
    cont.push_back(token);
  }
}
int px[4] = {-1, 0, 1, 0};
int py[4] = {0, -1, 0, 1};
struct edge {
  int u, v, wt;
  edge(int a = 0, int b = 0, int c = 0) : u(a), v(b), wt(c) {}
  bool operator<(edge const& other) { return wt < other.wt; }
  friend ostream& operator<<(ostream& out, const edge& x) {
    return out << "(" << x.u << ", " << x.v << ", " << x.wt << ")";
  }
};
int n, m, to_build, required_edges, res;
const int maxn = 1e5 + 5;
vector<pair<int, int>> v[maxn];
vector<int> group[maxn], number(maxn);
long long cnt[maxn];
bool vis[maxn];
void dfs(int node, int group_number) {
  vis[node] = true;
  if (group[group_number].size() < 2) group[group_number].push_back(node);
  number[node] = group_number;
  for (auto& p : v[node]) {
    if (!vis[p.first]) {
      dfs(p.first, group_number);
    }
  }
  return;
}
void abcd() {
  ip(n, m, to_build, required_edges);
  int x, y, wt;
  for (int i = 1; i <= m; i++) {
    ip(x, y, wt);
    v[x].push_back({y, wt});
    v[y].push_back({x, wt});
  }
  int num = 1;
  set<pair<long long int, int>> s;
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      dfs(i, num);
      num++;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (auto& p : v[i]) cnt[number[i]] += (long long)p.second;
  }
  for (int i = 1; i <= num - 1; i++) cnt[i] >>= 1;
  for (int i = 1; i <= num - 1; i++) {
    s.insert({cnt[i], i});
  }
  int GroupWithMoreThanOneMembers = -1;
  for (int i = 1; i <= num - 1; i++) {
    if (group[i].size() > 1) {
      GroupWithMoreThanOneMembers = i;
      break;
    }
  }
  vector<pair<int, int>> ans;
  int diff = (int)s.size() - required_edges;
  if (required_edges > (int)s.size() ||
      (int)s.size() - required_edges > to_build) {
    cout << "NO\n";
    return;
  } else {
    bool flag = true;
    while ((int)s.size() > required_edges) {
      auto it = s.begin();
      pair<long long, int> g1 = *it;
      it++;
      pair<long long, int> g2 = *it;
      s.erase(g1);
      s.erase(g2);
      s.insert(
          {g1.first + g2.first + min(1000000000LL, 1LL + g1.first + g2.first),
           g1.second});
      if (GroupWithMoreThanOneMembers == -1) {
        GroupWithMoreThanOneMembers = g1.second;
        group[g1.second].push_back(group[g2.second][0]);
      }
      ans.push_back({group[g1.second][0], group[g2.second][0]});
      to_build--;
    }
    if (to_build && GroupWithMoreThanOneMembers == -1) {
      cout << "NO\n";
      return;
    }
    while (to_build--) {
      ans.push_back({group[GroupWithMoreThanOneMembers][0],
                     group[GroupWithMoreThanOneMembers][1]});
    }
  }
  cout << "YES\n";
  for (auto p : ans) cout << p.first << ' ' << p.second << '\n';
  return;
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int t = 1;
  while (t--) {
    abcd();
  }
  return 0;
}
