#include <cstring>
#include <queue>
using namespace std;
#include <stdio.h>

#define N 100005
#define INF 1000000000

int adj[N];
int rn[N];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	int sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		scanf("%d%d%d", &x, &y, &l);
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum = min(INF, reg.sum + road[ptr].len);
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	int regionNum = first + 1;

	if (regionNum < q || regionNum >= q + p || (regionNum == q && m == 0 && p > 0)) {
		printf("NO\n");
		return ;
	}

	printf("YES\n");

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		printf("%d %d\n", r1.pcity, r2.pcity);
		int tmp = min(INF, r1.sum + r2.sum + 1);
		r1.sum = min(INF, min(INF, r1.sum + tmp) + r2.sum);
		pq.push(r1);
		--regionNum; --p;
	}

	for (int i=0; i<p; ++i) { printf("%d %d\n", extra[0], extra[1]); }
}

int main()
{
	int n, m, p, q;

	while (EOF != scanf("%d%d%d%d", &n, &m, &p, &q)) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

#define N 100005

int adj[N];
int rn[N];
int newRoad[N][2];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	long long sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		cin >> x >> y >> l;
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum += road[ptr].len;
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	for (int i=1; i<=n; ++i) {
		if (adj[i] == -1) {
			Region region = {i, 0LL};
			pq.push(region);
		}
	}

	int regionNum = first + 1;
	int newRoadNum = 0;

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		newRoad[newRoadNum][0] = r1.pcity;
		newRoad[newRoadNum++][1] = r2.pcity;
		r1.sum += min(1000000000LL, r1.sum + r2.sum + 1);
		pq.push(r1);
		--regionNum; --p;
	}

	if (regionNum != q || (p > 0 && findExtra == 0)) {
		cout << "NO" << endl;
	} else {
		cout << "YES" << endl;
		for (int i=0; i<newRoadNum; ++i) { cout << newRoad[i][0] << ' ' << newRoad[i][1] << endl; }
		for (int i=0; i<p; ++i) { cout << extra[0] << ' ' << extra[1] << endl; }
	}
}

int main()
{
	int n, m, p, q;

	while (cin >> n >> m >> p >> q) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <cstring>
#include <queue>
using namespace std;
#include <stdio.h>

#define N 100005
#define INF 1000000000

int adj[N];
int rn[N];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	int sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		scanf("%d%d%d", &x, &y, &l);
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum = min(INF, reg.sum + road[ptr].len);
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	int regionNum = first + 1;

	if (regionNum < q || (regionNum == q && m == 0 && p > 0)) {
		printf("NO\n");
		return ;
	}

	printf("YES\n");

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		printf("%d %d\n", r1.pcity, r2.pcity);
		int tmp = min(INF, r1.sum + r2.sum + 1);
		r1.sum = min(INF, min(INF, r1.sum + tmp) + r2.sum);
		pq.push(r1);
		--regionNum; --p;
	}

	for (int i=0; i<p; ++i) { printf("%d %d\n", extra[0], extra[1]); }
}

int main()
{
	int n, m, p, q;

	while (EOF != scanf("%d%d%d%d", &n, &m, &p, &q)) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <cstring>
#include <queue>
using namespace std;
#include <stdio.h>

#define N 100005
#define INF 1000000000LL

int adj[N];
int rn[N];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	long long sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		scanf("%d%d%d", &x, &y, &l);
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		reg.sum += road[ptr].len;
		if (rn[road[ptr].neighbour] == -1) {
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0};
			++first;
			visit(i, first, region);
			region.sum >>= 1LL;
			pq.push(region);
		}
	}

	int regionNum = first + 1;

	if (regionNum < q || regionNum > q + p || (regionNum == q && m == 0 && p > 0)) {
		printf("NO\n");
		return ;
	}

	/*if (n == 98743 && m == 98000 && p == 89000 && q == 1) {
		printf("%d\n", regionNum);
	}*/
	printf("YES\n");

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		printf("%d %d\n", r1.pcity, r2.pcity);
		/*if (n == 98743 && m == 98000 && q == 1) {
			printf("xx = %d %d\n", r1.sum, r2.sum);
		}*/
		long long tmp = min(INF, r1.sum + r2.sum + 1);
		r1.sum = min(INF, min(INF, r1.sum + tmp) + r2.sum);
		pq.push(r1);
		--regionNum; --p;
	}

	for (int i=0; i<p; ++i) { printf("%d %d\n", extra[0], extra[1]); }
}

int main()
{
	int n, m, p, q;

	while (EOF != scanf("%d%d%d%d", &n, &m, &p, &q)) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <cstring>
#include <queue>
using namespace std;
#include <stdio.h>

#define N 100005
#define INF 1000000000

int adj[N];
int rn[N];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	int sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		scanf("%d%d%d", &x, &y, &l);
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum += road[ptr].len;
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	int regionNum = first + 1;

	if (regionNum < q || (regionNum == q && m == 0 && p > 0)) {
		printf("NO\n");
		return ;
	}

	printf("YES\n");

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		printf("%d %d\n", r1.pcity, r2.pcity);
		int tmp = min(INF, r1.sum + r2.sum + 1);
		r1.sum = min(INF, min(INF, r1.sum + tmp) + r2.sum);
		pq.push(r1);
		--regionNum; --p;
	}

	for (int i=0; i<p; ++i) { printf("%d %d\n", extra[0], extra[1]); }
}

int main()
{
	int n, m, p, q;

	while (EOF != scanf("%d%d%d%d", &n, &m, &p, &q)) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

#define N 100005

int adj[N];
int rn[N];
int newRoad[N][2];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	long long sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		cin >> x >> y >> l;
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum += road[ptr].len;
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	int regionNum = first + 1;
	int newRoadNum = 0;

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		newRoad[newRoadNum][0] = r1.pcity;
		newRoad[newRoadNum++][1] = r2.pcity;
		r1.sum = min(1000000000LL, r1.sum + r2.sum + 1) + r1.sum + r2.sum;
		pq.push(r1);
		--regionNum; --p;
	}

	if (regionNum != q || (p > 0 && findExtra == 0)) {
		cout << "NO" << endl;
	} else {
		cout << "YES" << endl;
		for (int i=0; i<newRoadNum; ++i) { cout << newRoad[i][0] << ' ' << newRoad[i][1] << endl; }
		for (int i=0; i<p; ++i) { cout << extra[0] << ' ' << extra[1] << endl; }
	}
}

int main()
{
	int n, m, p, q;

	while (cin >> n >> m >> p >> q) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <cstring>
#include <queue>
using namespace std;
#include <stdio.h>

#define N 100005
#define INF 1000000000

int adj[N];
int rn[N];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	int sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		scanf("%d%d%d", &x, &y, &l);
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum = min(INF, reg.sum + road[ptr].len);
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	int regionNum = first + 1;

	if (regionNum < q || regionNum > q + p || (regionNum == q && m == 0 && p > 0)) {
		printf("NO\n");
		return ;
	}

	/*if (n == 98743 && m == 98000 && p == 89000 && q == 1) {
		printf("%d\n", regionNum);
	}*/
	printf("YES\n");

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		printf("%d %d\n", r1.pcity, r2.pcity);
		if (n == 98743 && m == 98000 && p == 89000 && q == 1) {
			printf("xx = %d %d\n", r1.sum, r2.sum);
		}
		int tmp = min(INF, r1.sum + r2.sum + 1);
		r1.sum = min(INF, min(INF, r1.sum + tmp) + r2.sum);
		pq.push(r1);
		--regionNum; --p;
	}

	for (int i=0; i<p; ++i) { printf("%d %d\n", extra[0], extra[1]); }
}

int main()
{
	int n, m, p, q;

	while (EOF != scanf("%d%d%d%d", &n, &m, &p, &q)) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include <cstring>
#include <queue>
using namespace std;
#include <stdio.h>

#define N 100005
#define INF 1000000000

int adj[N];
int rn[N];
int first;
struct Road
{
	int neighbour;
	int len;
	int next;
}road[N * 2];

struct Region
{
	int pcity;
	int sum;
	bool operator <(const Region &r) const
	{
		return sum > r.sum;
	}
};

int findExtra;
int extra[2];

void Read(int n, int m, int p, int q)
{
	int x, y, l;
	first = 0;
	memset(&adj[1], -1, n*sizeof(int));
	findExtra = 0;

	for (int i=0; i<m; ++i) {
		scanf("%d%d%d", &x, &y, &l);
		road[first].neighbour = y;
		road[first].len = l;
		road[first].next = adj[x];
		adj[x] = first++;
		road[first].neighbour = x;
		road[first].len = l;
		road[first].next = adj[y];
		adj[y] = first++;
		if (0 == findExtra) {
			findExtra = 1;
			extra[0] = x; extra[1] = y;
		}
	}
}

void visit(int sta, int arn, Region &reg) /* start number, assigned region number */
{
	rn[sta] = arn;
	int ptr = adj[sta];

	while (ptr != -1) {
		if (rn[road[ptr].neighbour] == -1) {
			reg.sum = min(INF, reg.sum + road[ptr].len);
			visit(road[ptr].neighbour, arn, reg);
		}

		ptr = road[ptr].next;
	}
}

void Solve(int n, int m, int p, int q)
{
	memset(&rn[1], -1, n*sizeof(int));
	first = -1;
	priority_queue<Region> pq;

	for (int i=1; i<=n; ++i) {
		if (rn[i] == -1) {
			Region region = {i, 0LL};
			++first;
			visit(i, first, region);
			pq.push(region);
		}
	}

	int regionNum = first + 1;

	if (regionNum < q || regionNum > q + p || (regionNum == q && m == 0 && p > 0)) {
		printf("NO\n");
		return ;
	}

	if (n == 98743 && m == 98000 && p == 89000 && q == 1) {
		printf("%d\n", regionNum);
	}
	printf("YES\n");

	while (regionNum > q && p > 0) {
		Region r1 = pq.top();
		pq.pop();
		Region r2 = pq.top();
		pq.pop();

		if (findExtra == 0) {
			extra[0] = r1.pcity;
			extra[1] = r2.pcity;
			findExtra = 1;
		}

		printf("%d %d\n", r1.pcity, r2.pcity);
		int tmp = min(INF, r1.sum + r2.sum + 1);
		r1.sum = min(INF, min(INF, r1.sum + tmp) + r2.sum);
		pq.push(r1);
		--regionNum; --p;
	}

	for (int i=0; i<p; ++i) { printf("%d %d\n", extra[0], extra[1]); }
}

int main()
{
	int n, m, p, q;

	while (EOF != scanf("%d%d%d%d", &n, &m, &p, &q)) {
		Read(n, m, p, q);
		Solve(n, m, p, q);
	}

	return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ifor(i, a, b) for(int i=a; i<=b; i++)
#define dfor(i, a, b) for(int i=a; i>=b; i--)
#define iprint(x) printf("%d", x)
#define llprint(x) printf("%lld", x)
#define iscan(x) scanf("%d", &x)
#define llscan(x) scanf("%lld", &x)

using namespace std;
ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
vector < pair < ll,ll > > ps;
ll dfs_region_sum(ll x,ll sum)
{
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].second;
                sum=dfs_region_sum(am[x][i].first,sum);
    }
return sum;
}

int main()
{

    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(x>y)
        {
            ll t=x;
            x=y;
            y=t;
        }
    flag=0;
    temp=am[x].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[x][j].first==y)
        {
            am[x][j].second+=l,flag=1;
            break;
        }
    }
    if(flag==0)
        {
            pvar1=make_pair(y,l);
            am[x].pb(pvar1);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            //cout<<diff<<endl;
            if(diff>0 && p==0 && flagsum==0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
                cout<<"YES"<<endl;
            while(p--)
            {
            sum=0;
            p1=pq.top();
            sum+=p1.first;
            pq.pop();
            p2=pq.top();
            sum+=p2.first;
            pq.pop();
            cout<<p1.second<<" "<<p2.second<<endl;
            if(p1.second>p2.second)
            {
                psvar.second=p1.second;
                p1.second=p2.second;
                p2.second=psvar.second;
            }
            pvar1=make_pair(p2.second,sum+1);
            am[p1.second].push_back(pvar1);
            p2=make_pair(sum+1,p1.second);
            pq.push(p2);
            }
            while(pq.size()!=1)
                pq.pop();
            while(diff--)
            {
            sum=0;
            p1=pq.top();
            sum=sum+1000+p1.first;
            pq.pop();
            ll yoo;
            yoo=am[p1.second][0].first;
            cout<<p1.second<<" "<<yoo<<endl;
            p2=make_pair(sum+1,p1.second);
            pq.push(p2);
            }
    }

    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ifor(i, a, b) for(int i=a; i<=b; i++)
#define dfor(i, a, b) for(int i=a; i>=b; i--)
#define iprint(x) printf("%d", x)
#define llprint(x) printf("%lld", x)
#define iscan(x) scanf("%d", &x)
#define llscan(x) scanf("%lld", &x)

using namespace std;
ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
vector < pair < ll,ll > > ps;
ll dfs_region_sum(ll x,ll sum)
{
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].second;
                sum=dfs_region_sum(am[x][i].first,sum);
    }
return sum;
}

int main()
{

    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(x>y)
        {
            ll t=x;
            x=y;
            y=t;
        }
    flag=0;
    temp=am[x].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[x][j].first==y)
        {
            am[x][j].second+=l,flag=1;
            break;
        }
    }
    if(flag==0)
        {
            pvar1=make_pair(y,l);
            am[x].pb(pvar1);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            //cout<<diff<<endl;
            if(diff>0 && p==0 && flagsum==0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
                cout<<"YES"<<endl;
            while(p--)
            {
            sum=0;
            p1=pq.top();
            sum-=p1.first;
            pq.pop();
            p2=pq.top();
            sum-=p2.first;
            pq.pop();
            cout<<p1.second<<" "<<p2.second<<endl;
            if(p1.second>p2.second)
            {
                psvar.second=p1.second;
                p1.second=p2.second;
                p2.second=psvar.second;
            }
            pvar1=make_pair(p2.second,sum-1);
            am[p1.second].push_back(pvar1);
            p2=make_pair(sum-1,p1.second);
            pq.push(p2);
            }
            while(pq.size()!=1)
                pq.pop();
            while(diff--)
            {
            sum=0;
            p1=pq.top();
            sum=sum-1000-p1.first;
            pq.pop();
            ll yoo;
            yoo=am[p1.second][0].first;
            cout<<p1.second<<" "<<yoo<<endl;
            p2=make_pair(sum-1,p1.second);
            pq.push(p2);
            }
    }

    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ifor(i, a, b) for(int i=a; i<=b; i++)
#define dfor(i, a, b) for(int i=a; i>=b; i--)
#define iprint(x) printf("%d", x)
#define llprint(x) printf("%lld", x)
#define iscan(x) scanf("%d", &x)
#define llscan(x) scanf("%lld", &x)

using namespace std;
ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
vector < pair < ll,ll > > ps;
ll dfs_region_sum(ll x,ll sum)
{
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].second;
                sum=dfs_region_sum(am[x][i].first,sum);
    }
return sum;
}

int main()
{

    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(x>y)
        {
            ll t=x;
            x=y;
            y=t;
        }
    flag=0;
    temp=am[x].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[x][j].first==y)
        {
            am[x][j].second+=l,flag=1;
            break;
        }
    }
    if(flag==0)
        {
            pvar1=make_pair(y,l);
            am[x].pb(pvar1);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            //cout<<diff<<endl;
            if(diff>0 && p==0 && flagsum==0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
                cout<<"YES"<<endl;
            while(p--)
            {
            sum=0;
            p1=pq.top();
            sum+=p1.first;
            pq.pop();
            p2=pq.top();
            sum+=p2.first;
            pq.pop();
            cout<<p1.second<<" "<<p2.second<<endl;
            if(p1.second>p2.second)
            {
                psvar.second=p1.second;
                p1.second=p2.second;
                p2.second=psvar.second;
            }
            pvar1=make_pair(p2.second,sum-1);
            am[p1.second].push_back(pvar1);
            p2=make_pair(sum-1,p1.second);
            pq.push(p2);
            }
            while(pq.size()!=1)
                pq.pop();
            while(diff--)
            {
            sum=0;
            p1=pq.top();
            sum=sum-1000+p1.first;
            pq.pop();
            ll yoo;
            yoo=am[p1.second][0].first;
            cout<<p1.second<<" "<<yoo<<endl;
            p2=make_pair(sum-1,p1.second);
            pq.push(p2);
            }
    }

    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ifor(i, a, b) for(int i=a; i<=b; i++)
#define dfor(i, a, b) for(int i=a; i>=b; i--)
#define iprint(x) printf("%d", x)
#define llprint(x) printf("%lld", x)
#define iscan(x) scanf("%d", &x)
#define llscan(x) scanf("%lld", &x)

using namespace std;
ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
vector < pair < ll,ll > > ps;
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].second;
                sum=dfs_region_sum(am[x][i].first,sum);
    }
return sum;
}

int main()
{

    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(x>y)
        {
            ll t=x;
            x=y;
            y=t;
        }
    flag=0;
    temp=am[x].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[x][j].first==y)
        {
            am[x][j].second+=l,flag=1;
            break;
        }
    }
    temp=am[y].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[y][j].first==x)
        {
            am[y][j].second+=l,flag=1;
            break;
        }
    }
    if(flag==0)
        {
            pvar1=make_pair(y,l);
            pvar2=make_pair(x,l);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    //cout<<cd<<endl;
    /*while(pq.size()!=0)
    {
        psvar=pq.top();
        cout<<psvar.first<<" "<<psvar.second<<endl;
        pq.pop();
    }*/
    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            //cout<<diff<<endl;
            if(diff>0 && p==0 && flagsum==0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
                cout<<"YES"<<endl;
            while(p--)
            {
            sum=0;
            p1=pq.top();
            sum+=p1.first;
            pq.pop();
            p2=pq.top();
            sum+=p2.first;
            minimum=max(tenp9,sum-1);
            pq.pop();
            cout<<p1.second<<" "<<p2.second<<endl;
            if(p1.second>p2.second)
            {
                psvar.second=p1.second;
                p1.second=p2.second;
                p2.second=psvar.second;
            }
            pvar1=make_pair(p2.second,sum+minimum);
            am[p1.second].push_back(pvar1);
            p2=make_pair(sum+minimum,p1.second);
            pq.push(p2);
            }
            while(pq.size()!=1)
                pq.pop();
            while(diff--)
            {
            sum=0;
            p1=pq.top();
            sum=sum-1000+p1.first;
            pq.pop();
            ll yoo;
            yoo=am[p1.second][0].first;
            cout<<p1.second<<" "<<yoo<<endl;
            p2=make_pair(sum,p1.second);
            pq.push(p2);
            }
    }

    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
using namespace std;

ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].first;
                sum=dfs_region_sum(am[x][i].second,sum);
    }
return sum;
}
int main()
{
    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000,yoo;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2,last;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(l>1000000000)
            l=1000000000;
        if(l>0)
        {
            last=make_pair(x,y);
        }
        flag=0;
        temp=am[x].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[x][j].second==y)
            {
                if(am[x][j].first>l)
                    am[x][j].first=l;
                flag=1;
                break;
            }
        }
        temp=am[y].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[y][j].second==x)
            {
                if(am[y][j].first>l)
                    am[y][j].first=l;
                flag=1;
                break;
            }
        }
        if(flag==0)
        {
            pvar1=make_pair(l,y);
            pvar2=make_pair(l,x);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            if(diff>0 && p==0 && flagsum==0){cout<<"NO"<<endl;return 0;}
            else cout<<"YES"<<endl;
            while(p--)
            {
                sum=0;
                 p1=pq.top(),sum+=p1.first,pq.pop();
                p2=pq.top(),sum+=p2.first,pq.pop();
                minimum=max(tenp9,sum-1);
                cout<<p1.second<<" "<<p2.second<<endl;
                last=make_pair(p1.second,p2.second);
                p2=make_pair(sum+minimum,p1.second),pq.push(p2);
            }
            while(diff--)
            {cout<<last.first<<" "<<last.second<<endl;}
    }
    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
using namespace std;

ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].first;
                sum=dfs_region_sum(am[x][i].second,sum);
    }
return sum;
}
int main()
{
    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000,yoo;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2,last;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(l>1000000000)
            l=1000000000;
        if(l>0)
        {
            last=make_pair(x,y);
        }
        flag=0;
        temp=am[x].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[x][j].second==y)
            {
                am[x][j].first+=l,flag=1;
                break;
            }
        }
        temp=am[y].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[y][j].second==x)
            {
                am[y][j].first+=l,flag=1;
                break;
            }
        }
        if(flag==0)
        {
            pvar1=make_pair(l,y);
            pvar2=make_pair(l,x);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            if(diff>0 && p==0 && flagsum==0){cout<<"NO"<<endl;return 0;}
            else cout<<"YES"<<endl;
            while(p--)
            {
                sum=0;
                 p1=pq.top(),sum+=p1.first,pq.pop();
                p2=pq.top(),sum+=p2.first,pq.pop();
                minimum=max(tenp9,sum-1);
                cout<<p1.second<<" "<<p2.second<<endl;
                last=make_pair(p1.second,p2.second);
                p2=make_pair(sum+minimum,p1.second),pq.push(p2);
            }
            while(diff--)
            {cout<<last.first<<" "<<last.second<<endl;}
    }
    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ifor(i, a, b) for(int i=a; i<=b; i++)
#define dfor(i, a, b) for(int i=a; i>=b; i--)
#define iprint(x) printf("%d", x)
#define llprint(x) printf("%lld", x)
#define iscan(x) scanf("%d", &x)
#define llscan(x) scanf("%lld", &x)

using namespace std;
ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
vector < pair < ll,ll > > ps;
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].second;
                sum=dfs_region_sum(am[x][i].first,sum);
    }
return sum;
}

int main()
{

    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(x>y)
        {
            ll t=x;
            x=y;
            y=t;
        }
    flag=0;
    temp=am[x].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[x][j].first==y)
        {
            am[x][j].second+=l,flag=1;
            break;
        }
    }
    temp=am[y].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[y][j].first==x)
        {
            am[y][j].second+=l,flag=1;
            break;
        }
    }
    if(flag==0)
        {
            pvar1=make_pair(y,l);
            pvar2=make_pair(x,l);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    //cout<<cd<<endl;
    /*while(pq.size()!=0)
    {
        psvar=pq.top();
        cout<<psvar.first<<" "<<psvar.second<<endl;
        pq.pop();
    }*/
    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            //cout<<diff<<endl;
            if(diff>0 && p==0 && flagsum==0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
                cout<<"YES"<<endl;
            while(p--)
            {
            sum=0;
            p1=pq.top();
            sum+=p1.first;
            pq.pop();
            p2=pq.top();
            sum+=p2.first;
            minimum=min(tenp9,sum-1);
            pq.pop();
            cout<<p1.second<<" "<<p2.second<<endl;
            if(p1.second>p2.second)
            {
                psvar.second=p1.second;
                p1.second=p2.second;
                p2.second=psvar.second;
            }
            pvar1=make_pair(p2.second,sum+minimum);
            am[p1.second].push_back(pvar1);
            p2=make_pair(sum+minimum,p1.second);
            pq.push(p2);
            }
            while(pq.size()!=1)
                pq.pop();
            while(diff--)
            {
            sum=0;
            p1=pq.top();
            sum=sum-1000+p1.first;
            pq.pop();
            ll yoo;
            yoo=am[p1.second][0].first;
            cout<<p1.second<<" "<<yoo<<endl;
            p2=make_pair(sum,p1.second);
            pq.push(p2);
            }
    }

    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
using namespace std;

ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].first;
                sum=dfs_region_sum(am[x][i].second,sum);
    }
return sum;
}
int main()
{
    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000,yoo;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2,last;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(l>1000000000)
            l=1000000000;
        if(l>0)
        {
            last=make_pair(x,y);
        }
        flag=0;
        temp=am[x].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[x][j].second==y)
            {
                am[x][j].first+=l,flag=1;
                if(am[x][j].first>1000000000)
                    am[x][j].first=1000000000;
                break;
            }
        }
        temp=am[y].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[y][j].second==x)
            {
                am[y][j].first+=l,flag=1;
                if(am[y][j].first>1000000000)
                    am[y][j].first=1000000000;
                break;
            }
        }
        if(flag==0)
        {
            pvar1=make_pair(l,y);
            pvar2=make_pair(l,x);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            //cout<<sum<<" "<<i<<endl;
            sum=sum/2;
            if(sum>1000000000)
                sum=1000000000;
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            if(diff>0 && p==0 && flagsum==0){cout<<"NO"<<endl;return 0;}
            else cout<<"YES"<<endl;
            while(p--)
            {
                sum=0;
                 p1=pq.top(),sum+=p1.first,pq.pop();
                p2=pq.top(),sum+=p2.first,pq.pop();
                minimum=max(tenp9,sum-1);
                cout<<p1.second<<" "<<p2.second<<endl;
                last=make_pair(p1.second,p2.second);
                p2=make_pair(sum+minimum,p1.second),pq.push(p2);
            }
            while(diff--)
            {cout<<last.first<<" "<<last.second<<endl;}
    }
    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ifor(i, a, b) for(int i=a; i<=b; i++)
#define dfor(i, a, b) for(int i=a; i>=b; i--)
#define iprint(x) printf("%d", x)
#define llprint(x) printf("%lld", x)
#define iscan(x) scanf("%d", &x)
#define llscan(x) scanf("%lld", &x)

using namespace std;
ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
vector < pair < ll,ll > > ps;
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].second;
                sum=dfs_region_sum(am[x][i].first,sum);
    }
return sum;
}

int main()
{

    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(x>y)
        {
            ll t=x;
            x=y;
            y=t;
        }
    flag=0;
    temp=am[x].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[x][j].first==y)
        {
            am[x][j].second+=l,flag=1;
            break;
        }
    }
    temp=am[y].size();
    for(ll j=0;j<temp;j++)
    {
        if(am[y][j].first==x)
        {
            am[y][j].second+=l,flag=1;
            break;
        }
    }
    if(flag==0)
        {
            pvar1=make_pair(y,l);
            pvar2=make_pair(x,l);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    //cout<<cd<<endl;
    /*while(pq.size()!=0)
    {
        psvar=pq.top();
        cout<<psvar.first<<" "<<psvar.second<<endl;
        pq.pop();
    }*/
    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            //cout<<diff<<endl;
            if(diff>0 && p==0 && flagsum==0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
                cout<<"YES"<<endl;
            while(p--)
            {
            sum=0;
            p1=pq.top();
            sum+=p1.first;
            pq.pop();
            p2=pq.top();
            sum+=p2.first;
            pq.pop();
            cout<<p1.second<<" "<<p2.second<<endl;
            if(p1.second>p2.second)
            {
                psvar.second=p1.second;
                p1.second=p2.second;
                p2.second=psvar.second;
            }
            pvar1=make_pair(p2.second,sum-1);
            am[p1.second].push_back(pvar1);
            p2=make_pair(sum-1,p1.second);
            pq.push(p2);
            }
            while(pq.size()!=1)
                pq.pop();
            while(diff--)
            {
            sum=0;
            p1=pq.top();
            sum=sum-1000+p1.first;
            pq.pop();
            ll yoo;
            yoo=am[p1.second][0].first;
            cout<<p1.second<<" "<<yoo<<endl;
            p2=make_pair(sum-1,p1.second);
            pq.push(p2);
            }
    }

    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
using namespace std;

ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].first;
                sum=dfs_region_sum(am[x][i].second,sum);
    }
return sum;
}
int main()
{
    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000,yoo;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2,last;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(l>1000000000)
            l=1000000000;
        if(l>0)
        {
            last=make_pair(x,y);
        }
        flag=0;
        temp=am[x].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[x][j].second==y)
            {
                am[x][j].first+=l,flag=1;
                if(am[x][j].first>1000000000)
                    am[x][j].first=1000000000;
                break;
            }
        }
        temp=am[y].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[y][j].second==x)
            {
                am[y][j].first+=l,flag=1;
                if(am[y][j].first>1000000000)
                    am[y][j].first=1000000000;
                break;
            }
        }
        if(flag==0)
        {
            pvar1=make_pair(l,y);
            pvar2=make_pair(l,x);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            if(diff>0 && p==0 && flagsum==0){cout<<"NO"<<endl;return 0;}
            else cout<<"YES"<<endl;
            while(p--)
            {
                sum=0;
                 p1=pq.top(),sum+=p1.first,pq.pop();
                p2=pq.top(),sum+=p2.first,pq.pop();
                minimum=max(tenp9,sum-1);
                cout<<p1.second<<" "<<p2.second<<endl;
                last=make_pair(p1.second,p2.second);
                p2=make_pair(sum+minimum,p1.second),pq.push(p2);
            }
            while(diff--)
            {cout<<last.first<<" "<<last.second<<endl;}
    }
    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
using namespace std;

ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].first;
                sum=dfs_region_sum(am[x][i].second,sum);
    }
return sum;
}
int main()
{
    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000,yoo;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(l>10000000000)
            l=1000000000;
        flag=0;
        temp=am[x].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[x][j].second==y)
            {
                am[x][j].first+=l,flag=1;
                break;
            }
        }
        temp=am[y].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[y][j].second==x)
            {
                am[y][j].first+=l,flag=1;
                break;
            }
        }
        if(flag==0)
        {
            pvar1=make_pair(l,y);
            pvar2=make_pair(l,x);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            if(diff>0 && p==0 && flagsum==0){cout<<"NO"<<endl;return 0;}
            else cout<<"YES"<<endl;
            while(p--)
            {
                sum=0;
                p1=pq.top(),sum+=p1.first,pq.pop();
                p2=pq.top(),sum+=p2.first,pq.pop();
                minimum=max(tenp9,sum-1);
                cout<<p1.second<<" "<<p2.second<<endl;
                pvar1=make_pair(sum+minimum,p2.second),am[p1.second].push_back(pvar1);
                pvar2=make_pair(sum+minimum,p1.second),am[p2.second].push_back(pvar2);
                p2=make_pair(sum+minimum,p1.second),pq.push(p2);
            }
            while(pq.size()!=1) pq.pop();
            p1=pq.top(),pq.pop();
            yoo=am[p1.second][0].second;
            while(diff--)
            {
                cout<<p1.second<<" "<<yoo<<endl;
            }
    }
    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000007
#define ll long long int
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
using namespace std;

ll visit[100050]={0};
vector < pair < ll,ll > > am[100050];
ll dfs_region_sum(ll x,ll sum)
{
    if(visit[x]==1)
        return sum;
    visit[x]=1;
    ll l=am[x].size();
    for(ll i=0;i<l;i++)
    {
                //cout<<am[x][i].first<<" "<<am[x][i].second<<endl;
                sum=sum+am[x][i].first;
                sum=dfs_region_sum(am[x][i].second,sum);
    }
return sum;
}
int main()
{
    ll n,m,p,q,x,y,l,sum,temp,flag=0,cd=0,flagsum=0,minimum=0,tenp9=-1000000000,yoo;
    cin>>n>>m>>p>>q;
    pair <ll,ll> pvar1,psvar,p1,p2,pvar2;
    priority_queue < pair< ll,ll > > pq;
    for(ll i=1;i<=m;i++)
    {
        cin>>x>>y>>l;
        if(l>1000000000)
            l=1000000000;
        flag=0;
        temp=am[x].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[x][j].second==y)
            {
                am[x][j].first+=l,flag=1;
                break;
            }
        }
        temp=am[y].size();
        for(ll j=0;j<temp;j++)
        {
            if(am[y][j].second==x)
            {
                am[y][j].first+=l,flag=1;
                break;
            }
        }
        if(flag==0)
        {
            pvar1=make_pair(l,y);
            pvar2=make_pair(l,x);
            am[x].pb(pvar1);
            am[y].pb(pvar2);
        }
    }

    for(ll i=1;i<=n;i++)
    {
        sum=0;
        if(visit[i]==0)
        {
            sum=dfs_region_sum(i,sum);
            if(sum>0)
                flagsum++;
            psvar=(make_pair((-1)*(sum),i));
            pq.push(psvar);
        }
    }

    cd=pq.size();
    if((cd-p)<=q  && cd>=q)
    {
            ll diff=0;
            diff=(q-(cd-p));
            p=p-diff;
            if(diff>0 && p==0 && flagsum==0){cout<<"NO"<<endl;return 0;}
            else cout<<"YES"<<endl;
            while(p--)
            {
                sum=0;
                p1=pq.top(),sum+=p1.first,pq.pop();
                p2=pq.top(),sum+=p2.first,pq.pop();
                minimum=max(tenp9,sum-1);
                cout<<p1.second<<" "<<p2.second<<endl;
                pvar1=make_pair(sum+minimum,p2.second),am[p1.second].push_back(pvar1);
                pvar2=make_pair(sum+minimum,p1.second),am[p2.second].push_back(pvar2);
                p2=make_pair(sum+minimum,p1.second),pq.push(p2);
            }
            while(pq.size()!=1) pq.pop();
            while(diff--)
            {
                sum=0;
                p1=pq.top(),sum=sum-1000+p1.first,pq.pop();
                yoo=am[p1.second][0].second;
                cout<<p1.second<<" "<<yoo<<endl;
                p2=make_pair(sum,p1.second);
                pq.push(p2);
            }
    }
    else
    {
        cout<<"NO"<<endl;
    }
    return 0;
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a)   memset(x,a,sizeof(x))
typedef long long 	 ll;
typedef pair<ll,int> PI;
const int INF    = 0x3fffffff;
const int MOD    = 100000007;
const double EPS = 1e-7;

int par[N];
ll sum[N];

priority_queue<PI, vector<PI>, greater<PI> > que;

void init(int n)
{
	for(int i=1;i<=n;i++)
		par[i]=i,sum[i]=0;
}

int find(int x)
{
	return x==par[x]?x:par[x]=find(par[x]);
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
	sum[y]+=sum[x];
}
PI p1,p2;
int main()
{
	int n,m,p,q,u,v,len;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	init(n);
	while(m--){
		scanf("%d%d%d",&u,&v,&len);
		sum[find(u)]+=len;
		merge(u,v);
	}
	int cnt=0;
	for(int i=1;i<=n;i++) if(par[i]==i){
	   	cnt++;
		que.push((PI){sum[i],i});
	}
	if( (cnt==n && p && q==n) || cnt-q<0 || p<cnt-q) puts("NO");
	else{
		puts("YES");
		m=cnt-q;
		p-=m;
		while(m--){
			p1=que.top(); que.pop();
			p2=que.top(); que.pop();
			printf("%d %d\n",p1.second,p2.second);
			ll val=p1.first+p2.first+min(1000000000ll,p1.first+p2.first+1);
			que.push((PI){val,p1.second});
		}
		if(!p1.second && !p2.second) p1.second=1, p2.second=2;
		while(p--) printf("%d %d\n",p1.second,p2.second);
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a)   memset(x,a,sizeof(x))
typedef long long 	 ll;
typedef pair<ll,int> PI;
const int INF    = 0x3fffffff;
const int MOD    = 100000007;
const double EPS = 1e-7;

int par[N];
ll sum[N];

priority_queue<PI, vector<PI>, greater<PI> > que;

void init(int n)
{
	for(int i=1;i<=n;i++)
		par[i]=i,sum[i]=0;
}

int find(int x)
{
	return x==par[x]?x:par[x]=find(par[x]);
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
	sum[y]+=sum[x];
}

int main()
{
	int n,m,p,q,u,v,len;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	init(n);
	while(m--){
		scanf("%d%d%d",&u,&v,&len);
		sum[find(u)]+=len;
		merge(u,v);
	}
	int cnt=0;
	for(int i=1;i<=n;i++) if(par[i]==i){
	   	cnt++;
		que.push((PI){sum[i],i});
	}
	if( (cnt==n && p && q==n) || cnt-q<0 || p<cnt-q) puts("NO");
	else{
		puts("YES");
		m=cnt-q;
		while(m--){
			PI p1=que.top(); que.pop();
			PI p2=que.top(); que.pop();
			printf("%d %d\n",p1.second,p2.second);
			ll val=p1.first+p2.first+min(1000000000ll,p1.first+p2.first);
			que.push((PI){val,p1.second});
		}
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a)   memset(x,a,sizeof(x))
typedef long long 	 ll;
typedef pair<ll,int> PI;
const int INF    = 0x3fffffff;
const int MOD    = 100000007;
const double EPS = 1e-7;

int par[N];
ll sum[N];

priority_queue<PI, vector<PI>, greater<PI> > que;

void init(int n)
{
	for(int i=1;i<=n;i++)
		par[i]=i,sum[i]=0;
}

int find(int x)
{
	return x==par[x]?x:par[x]=find(par[x]);
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
	sum[y]+=sum[x];
}
PI p1,p2;
int main()
{
	int n,m,p,q,u,v,len;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	init(n);
	while(m--){
		scanf("%d%d%d",&u,&v,&len);
		sum[find(u)]+=len;
		merge(u,v);
	}
	int cnt=0;
	for(int i=1;i<=n;i++) if(par[i]==i){
	   	cnt++;
		que.push((PI){sum[i],i});
	}
	if( (cnt==n && p && q==n) || cnt-q<0 || p<cnt-q) puts("NO");
	else{
		puts("YES");
		m=cnt-q;
		p-=m;
		while(m--){
			p1=que.top(); que.pop();
			p2=que.top(); que.pop();
			printf("%d %d\n",p1.second,p2.second);
			ll val=p1.first+p2.first+min(1000000000ll,p1.first+p2.first+1);
			que.push((PI){val,p1.second});
		}
		if(!p1.second && !p2.second) p1.second=u, p2.second=v;
		while(p--) printf("%d %d\n",p1.second,p2.second);
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a)   memset(x,a,sizeof(x))
typedef long long 	 ll;
typedef pair<ll,int> PI;
const int INF    = 0x3fffffff;
const int MOD    = 100000007;
const double EPS = 1e-7;

int par[N];
ll sum[N];

priority_queue<PI, vector<PI>, greater<PI> > que;

void init(int n)
{
	for(int i=1;i<=n;i++)
		par[i]=i,sum[i]=0;
}

int find(int x)
{
	return x==par[x]?x:par[x]=find(par[x]);
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
	sum[y]+=sum[x];
}
PI p1,p2;
int main()
{
	int n,m,p,q,u,v,len;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	init(n);
	while(m--){
		scanf("%d%d%d",&u,&v,&len);
		sum[find(u)]+=len;
		merge(u,v);
	}
	int cnt=0;
	for(int i=1;i<=n;i++) if(par[i]==i){
	   	cnt++;
		que.push((PI){sum[i],i});
	}
	if( (cnt==n && p && q==n) || cnt-q<0 || p<cnt-q) puts("NO");
	else{
		puts("YES");
		m=cnt-q;
		p-=m;
		while(m--){
			p1=que.top(); que.pop();
			p2=que.top(); que.pop();
			printf("%d %d\n",p1.second,p2.second);
			ll val=p1.first+p2.first+min(1000000000ll,p1.first+p2.first+1);
			que.push((PI){val,p1.second});
		}
		//if(!p1.second && !p2.second) p1.second=1, p2.second=2;
		while(p--) printf("%d %d\n",u,v);
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a)   memset(x,a,sizeof(x))
typedef long long 	 ll;
typedef pair<ll,int> PI;
const int INF    = 0x3fffffff;
const int MOD    = 100000007;
const double EPS = 1e-7;

int par[N];
ll sum[N];

priority_queue<PI, vector<PI>, greater<PI> > que;

void init(int n)
{
	for(int i=1;i<=n;i++)
		par[i]=i,sum[i]=0;
}

int find(int x)
{
	return x==par[x]?x:par[x]=find(par[x]);
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
	sum[y]+=sum[x];
}
PI p1,p2;
int main()
{
	int n,m,p,q,u,v,len;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	init(n);
	while(m--){
		scanf("%d%d%d",&u,&v,&len);
		sum[find(u)]+=len;
		merge(u,v);
	}
	int cnt=0;
	for(int i=1;i<=n;i++) if(par[i]==i){
	   	cnt++;
		que.push((PI){sum[i],i});
	}
	if( (cnt==n && p && q==n) || cnt-q<0 || p<cnt-q) puts("NO");
	else{
		puts("YES");
		m=cnt-q;
		p-=m;
		while(m--){
			p1=que.top(); que.pop();
			p2=que.top(); que.pop();
			printf("%d %d\n",p1.second,p2.second);
			ll val=p1.first+p2.first+min(1000000000ll,p1.first+p2.first);
			que.push((PI){val,p1.second});
		}
		if(!p1.second && !p2.second) p1.second=1, p2.second=2;
		while(p--) printf("%d %d\n",p1.second,p2.second);
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a)   memset(x,a,sizeof(x))
typedef long long 	 ll;
typedef pair<ll,int> PI;
const int INF    = 0x3fffffff;
const int MOD    = 100000007;
const double EPS = 1e-7;

int par[N];
ll sum[N];

priority_queue<PI, vector<PI>, greater<PI> > que;

void init(int n)
{
	for(int i=1;i<=n;i++)
		par[i]=i,sum[i]=0;
}

int find(int x)
{
	return x==par[x]?x:par[x]=find(par[x]);
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
	sum[y]+=sum[x];
}

int main()
{
	int n,m,p,q,u,v,len;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	init(n);
	while(m--){
		scanf("%d%d%d",&u,&v,&len);
		sum[find(u)]+=len;
		merge(u,v);
	}
	int cnt=0;
	for(int i=1;i<=n;i++) if(par[i]==i){
	   	cnt++;
		que.push((PI){sum[i],i});
	}
	if( (cnt==n && p && q==n) || cnt-q<0 || p<cnt-q) puts("NO");
	else{
		puts("YES");
		m=cnt-q;
		p-=m;
		PI p1,p2;
		while(m--){
			p1=que.top(); que.pop();
			p2=que.top(); que.pop();
			printf("%d %d\n",p1.second,p2.second);
			ll val=p1.first+p2.first+min(1000000000ll,p1.first+p2.first);
			que.push((PI){val,p1.second});
		}
		while(p--) printf("%d %d\n",p1.second,p2.second);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

struct Res {
    int x, y;

    Res(int u, int v) {
        x = u; y = v;
    }
};

const int maxN = 1e5 + 5;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;
vector <Res> res;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        sum += head[u][i].l;
        if (!mark[v])
            DFS(v);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            s.insert(ii(sum / 2, i));
        }
    if (com < q) printf("NO\n");
    else {
        while (com > q && p > 0) {
            --p; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            s.erase(it);
            it = s.begin();
            sum += it->l;
            int v = it->v;
            s.erase(it);
            s.insert(ii(sum, v));
            res.pb(Res(u, v));
        }
        while (p-- > 0)
            res.pb(Res(v1, v2));

        if (com != q) printf("NO\n");
        else {
            printf("YES\n");
            FR(i, sz(res)) printf("%d %d\n", res[i].x, res[i].y);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

struct Res {
    int x, y;

    Res(int u, int v) {
        x = u; y = v;
    }
};

const int maxN = 1e5 + 5;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;
vector <Res> res;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        sum += head[u][i].l;
        if (!mark[v])
            DFS(v);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            s.insert(ii(sum / 2, i));
        }
    if (com < q) printf("NO\n");
    else {
        while (com > q && p > 0) {
            --p; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            v1 = u;
            s.erase(it);
            it = s.begin();
            sum += it->l;
            int v = it->v;
            v2 = v;
            s.erase(it);
            s.insert(ii(sum, v));
            res.pb(Res(u, v));
        }

        if (v1 == v2 && p > 0) {
            printf("NO\n");
            return 0;
        }
        while (p-- > 0) {
            set <ii> :: iterator it;
            it = s.begin();
            ll sum1 = it->l;
            int u = it->v;
            s.erase(it);
            it = s.begin();
            ll sum2 = it->l;
            int v = it->v;
            s.erase(it);
            if (sum1 + sum2 < 1000) {
                res.pb(Res(u, v));
                s.insert(ii(sum1 + sum2, u));
                v1 = u; v2 = v;
            }
            else {
                s.insert(ii(sum1, u));
                s.insert(ii(sum2, v));
                res.pb(Res(v1, v2));
            }
        }

        if (com != q) printf("NO\n");
        else {
            printf("YES\n");
            FR(i, sz(res)) printf("%d %d\n", res[i].x, res[i].y);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

const int maxN = 1e5 + 5;
const ll oo = 1e9;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        sum += (ll)head[u][i].l;
        if (!mark[v])
            DFS(v);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            sum /= 2;
            s.insert(ii(sum, i));
        }
    if (q > com || p < (com - q) || (q == n && p != 0))
        printf("NO\n");
    else {
        printf("YES\n");
        while (q < com) {
            --p; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            s.erase(s.begin());
            it = s.begin();
            sum += it->l;
            int v = it->v;
            s.erase(s.begin());
            printf("%d %d\n", u, v);
            v1 = u; v2 = v;
            s.insert(ii(min(oo, sum + 1) + sum, u));
        }
        while (p--) printf("%d %d\n", v1, v2);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

struct Res {
    int x, y;

    Res(int u, int v) {
        x = u; y = v;
    }
};

const int maxN = 1e5 + 5;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;
vector <Res> res;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        sum += head[u][i].l;
        if (!mark[v])
            DFS(v);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            s.insert(ii(sum / 2, i));
        }
    if (q > com || p < (com - q) || (q == n && p != 0))
        printf("NO\n");
    else {
        printf("YES\n");
        while (q < com) {
            p--; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            s.erase(s.begin());
            it = s.begin();
            sum += it->l;
            int v = it->v;
            s.erase(s.begin());
            printf("%d %d\n", u, v);
            v1 = u; v2 = v;
            s.insert(ii(sum, u));
        }
        while (p--) printf("%d %d\n", v1, v2);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

struct Res {
    int x, y;

    Res(int u, int v) {
        x = u; y = v;
    }
};

const int maxN = 1e5 + 5;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;
vector <Res> res;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        if (!mark[v]) {
            sum += head[u][i].l;
            DFS(v);
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            s.insert(ii(sum, i));
        }
    if (com < q) printf("NO\n");
    else {
        while (com > q && p > 0) {
            --p; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            s.erase(it);
            it = s.begin();
            sum += it->l;
            int v = it->v;
            s.erase(it);
            s.insert(ii(sum, v));
            res.pb(Res(u, v));
        }
        while (p-- > 0)
            res.pb(Res(v1, v2));

        if (com != q) printf("NO\n");
        else {
            printf("YES\n");
            FR(i, sz(res)) printf("%d %d\n", res[i].x, res[i].y);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

struct Res {
    int x, y;

    Res(int u, int v) {
        x = u; y = v;
    }
};

const int maxN = 1e5 + 5;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;
vector <Res> res;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        sum += head[u][i].l;
        if (!mark[v])
            DFS(v);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            s.insert(ii(sum / 2, i));
        }
    if (com < q) printf("NO\n");
    else {
        while (com > q && p > 0) {
            --p; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            v1 = u;
            s.erase(it);
            it = s.begin();
            sum += it->l;
            int v = it->v;
            v2 = v;
            s.erase(it);
            s.insert(ii(sum, v));
            res.pb(Res(u, v));
        }

        if (v1 == v2 && p > 0) {
            printf("NO\n");
            return 0;
        }
        while (p-- > 0)
            res.pb(Res(v1, v2));

        if (com != q) printf("NO\n");
        else {
            printf("YES\n");
            FR(i, sz(res)) printf("%d %d\n", res[i].x, res[i].y);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>
#include <numeric>

#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FRD(i, a, b) for(int i = a; i >= b; --i)
#define FR(i, a) for(int i = 0; i < a; ++i)
#define REP(i, a) for(int i = 0; i <= a; ++i)
#define pb push_back
#define sz(x) (int)x.size()
#define reset(a, b) memset(a, b, sizeof a)
#define bug(x) cout << #x << " = " << x << endl
#define bg(a, m, n) FOR(i, m, n) cout << a[i] << " "; cout << endl
using namespace std;

typedef long long ll;
typedef unsigned long long qword;
typedef pair <ll, int> ii;
#define l first
#define v second

const int maxN = 1e5 + 5;
const ll oo = 1e9;

int n, m, q, p;
vector <ii> head[maxN];
bool mark[maxN];
int com, v1, v2;
ll sum;
set <ii> s;

void DFS(int u) {
    mark[u] = true;
    FR(i, sz(head[u])) {
        int v = head[u][i].v;
        sum += head[u][i].l;
        if (!mark[v])
            DFS(v);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("TEST.INP", "r", stdin);
#else
    ios_base::sync_with_stdio(false);
#endif // ONLINE_JUDGE
    scanf("%d%d%d%d", &n, &m, &p, &q);
    int x, y, c;
    FOR(i, 1, m) {
        scanf("%d%d%d", &x, &y, &c);
        v1 = x; v2 = y;
        head[x].pb(ii((ll)c, y));
        head[y].pb(ii((ll)c, x));
    }
    reset(mark, false);
    FOR(i, 1, n)
        if (!mark[i]) {
            ++com;
            sum = 0;
            DFS(i);
            s.insert(ii(sum / 2, i));
        }
    if (q > com || p < (com - q) || (q == n && p != 0))
        printf("NO\n");
    else {
        printf("YES\n");
        while (q < com) {
            p--; --com;
            set <ii> :: iterator it;
            it = s.begin();
            ll sum = it->l;
            int u = it->v;
            s.erase(s.begin());
            it = s.begin();
            sum += it->l;
            int v = it->v;
            s.erase(s.begin());
            printf("%d %d\n", u, v);
            v1 = u; v2 = v;
            s.insert(ii(min(oo, sum + 1), u));
        }
        while (p--) printf("%d %d\n", v1, v2);
    }
    return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
}roads[N];

int set[N];
long long sum[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	if(fx > fy)
		swap(fx,fy);
	set[fy] = fx;
	sum[fx] += sum[fy] + length;
	if(sum[fx] < 0)
	{
		cout << fy << endl;
		cout << sum[fy] << endl;
		cout << length << endl;
		puts("ne");
	}
}

int main()
{
	while(cin >> n >> m >> p >> q)
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 0;i < m;i++)
			cin >> roads[i].x >> roads[i].y >> roads[i].length;
		for(int i = 1;i <= n;i++)
			set[i] = i;
		memset(sum,0,sizeof(sum));
		for(int i = 0;i < m;i++)
			merge(roads[i].x,roads[i].y,roads[i].length);
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(i)] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum[i];
				Q.push(tmp);
				t++;
				if(n == 1000)
					cout << tmp.length << endl;
			}
		if(t < q || p < t - q || (n == 2 && q == 2 && p) || (n == 1 && p))
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();

				if(n == 1000)
					cout << tmp1.length << " " << tmp2.length << endl;
				long long lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				cout << tmp1.x << " " << tmp2.x << endl;
				set[find(tmp1.x)] = find(tmp2.x);
				sum[find(tmp2.x)] += sum[find(tmp1.x)] + lmin;
				tmp2.x = tmp2.y = find(tmp2.x);
				tmp2.length = sum[find(tmp2.x)];
				Q.push(tmp2);
			}
			int v1,v2;
			for(int i = 1;i <= n;i++)
				if(set[i] != i)
				{
					v1 = i;
					v2 = set[i];
				}
			for(int i = 0;i < p - t + q;i++)
				cout << v1 << " " << v2 << endl;
		}
	}
	return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
};

int set[N];
long long sum1[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	if(fx > fy)
		swap(fx,fy);
	set[fy] = fx;
	sum1[fx] += sum1[fy] + length;
	if(sum1[fx] < 0)
	{
		cout << fy << endl;
		cout << sum1[fy] << endl;
		cout << length << endl;
		puts("ne");
	}
}

int main()
{
	while(cin >> n >> m >> p >> q)
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 1;i <= n;i++)
		{
			set[i] = i;
			sum1[i] = 0;
		}
		int a,b;
		long long c;
		for(int i = 0;i < m;i++)
		{
			cin >> a >> b >> c;
			if(n == 1000 && sum1[71] < 0)
				cout << "a: " << a << " b: " << b << " ";
			merge(a,b,c);
		}
		if(n == 1000)
			cout << "71end" << endl;
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(i)] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum1[i];
				Q.push(tmp);
				t++;
				if(n == 1000)
					cout << tmp.length << endl;
			}
		if(t < q || p < t - q || (n == 2 && q == 2 && p) || (n == 1 && p))
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();

				if(n == 1000)
					cout << tmp1.length << " " << tmp2.length << endl;
				long long lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				cout << tmp1.x << " " << tmp2.x << endl;
				set[find(tmp1.x)] = find(tmp2.x);
				sum1[find(tmp2.x)] += sum1[find(tmp1.x)] + lmin;
				tmp2.x = tmp2.y = find(tmp2.x);
				tmp2.length = sum1[find(tmp2.x)];
				Q.push(tmp2);
			}
			int v1,v2;
			for(int i = 1;i <= n;i++)
				if(set[i] != i)
				{
					v1 = i;
					v2 = set[i];
				}
			for(int i = 0;i < p - t + q;i++)
				cout << v1 << " " << v2 << endl;
		}
	}
	return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
}roads[N];

int set[N];
long long sum[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	if(fx > fy)
		swap(fx,fy);
	set[fy] = fx;
	sum[fx] += sum[fy] + length;
}

int main()
{
	while(cin >> n >> m >> p >> q)
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 0;i < m;i++)
			cin >> roads[i].x >> roads[i].y >> roads[i].length;
		for(int i = 1;i <= n;i++)
			set[i] = i;
		memset(sum,0,sizeof(sum));
		for(int i = 0;i < m;i++)
			merge(roads[i].x,roads[i].y,roads[i].length);
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(i)] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum[i];
				Q.push(tmp);
				t++;
				if(n == 1000)
					cout << tmp.length << endl;
			}
		if(t < q || p < t - q || (n == 2 && q == 2 && p) || (n == 1 && p))
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();

				if(n == 1000)
					cout << tmp1.length << " " << tmp2.length << endl;
				long long lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				cout << tmp1.x << " " << tmp2.x << endl;
				set[find(tmp1.x)] = find(tmp2.x);
				sum[find(tmp2.x)] += sum[find(tmp1.x)] + lmin;
				tmp2.x = tmp2.y = find(tmp2.x);
				tmp2.length = sum[find(tmp2.x)];
				Q.push(tmp2);
			}
			int v1,v2;
			for(int i = 1;i <= n;i++)
				if(set[i] != i)
				{
					v1 = i;
					v2 = set[i];
				}
			for(int i = 0;i < p - t + q;i++)
				cout << v1 << " " << v2 << endl;
		}
	}
	return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
};

int set[N];
long long sum[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	if(fx > fy)
		swap(fx,fy);
	set[fy] = fx;
	sum[fx] += sum[fy] + length;
	if(sum[fx] < 0)
	{
		cout << fy << endl;
		cout << sum[fy] << endl;
		cout << length << endl;
		puts("ne");
	}
}

int main()
{
	while(cin >> n >> m >> p >> q)
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 1;i <= n;i++)
		{
			set[i] = i;
			sum[i] = 0;
		}
		int a,b;
		long long c;
		for(int i = 0;i < m;i++)
		{
			cin >> a >> b >> c;
			merge(a,b,c);
		}
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(i)] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum[i];
				Q.push(tmp);
				t++;
				if(n == 1000)
					cout << tmp.length << endl;
			}
		if(t < q || p < t - q || (n == 2 && q == 2 && p) || (n == 1 && p))
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();

				if(n == 1000)
					cout << tmp1.length << " " << tmp2.length << endl;
				long long lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				cout << tmp1.x << " " << tmp2.x << endl;
				set[find(tmp1.x)] = find(tmp2.x);
				sum[find(tmp2.x)] += sum[find(tmp1.x)] + lmin;
				tmp2.x = tmp2.y = find(tmp2.x);
				tmp2.length = sum[find(tmp2.x)];
				Q.push(tmp2);
			}
			int v1,v2;
			for(int i = 1;i <= n;i++)
				if(set[i] != i)
				{
					v1 = i;
					v2 = set[i];
				}
			for(int i = 0;i < p - t + q;i++)
				cout << v1 << " " << v2 << endl;
		}
	}
	return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
}roads[N];

int set[N];
long long sum[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	if(fx > fy)
		swap(fx,fy);
	set[fy] = fx;
	sum[fx] += sum[fy] + length;
}

int main()
{
	while(cin >> n >> m >> p >> q)
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 0;i < m;i++)
			cin >> roads[i].x >> roads[i].y >> roads[i].length;
		for(int i = 1;i <= n;i++)
			set[i] = i;
		for(int i = 0;i <= n;i++)
			sum[i] = 0;
		for(int i = 0;i < m;i++)
			merge(roads[i].x,roads[i].y,roads[i].length);
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(i)] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum[i];
				Q.push(tmp);
				t++;
			}
		if(t < q || p < t - q || (n == 2 && q == 2 && p) || (n == 1 && p))
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();

				if(n == 1000)
					cout << tmp1.length << " " << tmp2.length << endl;
				long long lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				cout << tmp1.x << " " << tmp2.x << endl;
				set[find(tmp1.x)] = find(tmp2.x);
				sum[find(tmp2.x)] += sum[find(tmp1.x)] + lmin;
				tmp2.x = tmp2.y = find(tmp2.x);
				tmp2.length = sum[find(tmp2.x)];
				Q.push(tmp2);
			}
			int v1,v2;
			for(int i = 1;i <= n;i++)
				if(set[i] != i)
				{
					v1 = i;
					v2 = set[i];
				}
			for(int i = 0;i < p - t + q;i++)
				cout << v1 << " " << v2 << endl;
		}
	}
	return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
};

int set[N];
long long sum[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	if(fx > fy)
		swap(fx,fy);
	set[fy] = fx;
	sum[fx] += sum[fy] + length;
	if(sum[fx] < 0)
	{
		cout << fy << endl;
		cout << sum[fy] << endl;
		cout << length << endl;
		puts("ne");
	}
}

int main()
{
	while(cin >> n >> m >> p >> q)
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 1;i <= n;i++)
		{
			set[i] = i;
			sum[i] = 0;
		}
		int a,b;
		long long c;
		for(int i = 0;i < m;i++)
		{
			cin >> a >> b >> c;
			if(n == 1000 && sum[71] < 0)
				cout << i << " ";
			merge(a,b,c);
		}
		if(n == 1000)
			cout << "71end" << endl;
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(i)] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum[i];
				Q.push(tmp);
				t++;
				if(n == 1000)
					cout << tmp.length << endl;
			}
		if(t < q || p < t - q || (n == 2 && q == 2 && p) || (n == 1 && p))
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();

				if(n == 1000)
					cout << tmp1.length << " " << tmp2.length << endl;
				long long lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				cout << tmp1.x << " " << tmp2.x << endl;
				set[find(tmp1.x)] = find(tmp2.x);
				sum[find(tmp2.x)] += sum[find(tmp1.x)] + lmin;
				tmp2.x = tmp2.y = find(tmp2.x);
				tmp2.length = sum[find(tmp2.x)];
				Q.push(tmp2);
			}
			int v1,v2;
			for(int i = 1;i <= n;i++)
				if(set[i] != i)
				{
					v1 = i;
					v2 = set[i];
				}
			for(int i = 0;i < p - t + q;i++)
				cout << v1 << " " << v2 << endl;
		}
	}
	return 0;
}


//============================================================================
// Name        : ACM.cpp
// Author      : Moment
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

#define N 100005

long long min(long long a,long long b)
{
	return a < b ? a : b;
}

struct Road
{
	int x,y;
	long long length;

	friend bool operator < (Road A,Road B)
	{
		return A.length > B.length;
	}
}roads[N];

int set[N];
long long sum[N];
bool visited[N];
int n,m,p,q;
priority_queue<Road> Q;

int find(int x)
{
	if(set[x] == x)
		return x;
	return set[x] = find(set[x]);
}

void merge(int x,int y,long long length)
{
	int fx = find(x);
	int fy = find(y);
	set[fy] = fx;
	sum[fx] += sum[fy] + length;
}

int main()
{
	while(~scanf("%d %d %d %d",&n,&m,&p,&q))
	{
		while(!Q.empty())
			Q.pop();
		for(int i = 0;i < m;i++)
			//scanf("%d %d %lld",&roads[i].x,&roads[i].y,&roads[i].length);
			cout << roads[i].x << roads[i].y << roads[i].length;
		for(int i = 1;i <= n;i++)
			set[i] = i;
		memset(sum,0,sizeof(sum));
		for(int i = 0;i < m;i++)
			merge(roads[i].x,roads[i].y,roads[i].length);
		memset(visited,0,sizeof(visited));
		for(int i = 1;i <= n;i++)
			visited[find(set[i])] = 1;
		int t = 0;
		for(int i = 1;i <= n;i++)
			if(visited[i])
			{
				//printf("root: %d\n",i);
				Road tmp;
				tmp.x = tmp.y = i;
				tmp.length = sum[i];
				Q.push(tmp);
				t++;
			}
		//printf("visited9 %d\n",visited[9]);
		//printf("t: %d\n",t);
		if(t - p < q)
			puts("NO");
		else
		{
			puts("YES");
			Road tmp1,tmp2;
			for(int i = 0;i < t - q;i++)
			{
				tmp1 = Q.top();
				Q.pop();
				tmp2 = Q.top();
				Q.pop();
				int lmin = min(1000000000,tmp1.length + tmp2.length + 1);
				printf("%d %d\n",tmp1.x,tmp2.x);
				set[tmp1.x] = set[tmp2.x];
				sum[tmp2.x] += set[tmp1.x] + lmin;
				tmp2.length = lmin;
				Q.push(tmp2);
			}
			for(int i = 0;i < p - t + q;i++)
				printf("1 2\n");
		}
	}
	return 0;
}