#include <iostream>
using namespace std;
int n, i, j;
string b, a, s;
int main(){
cin >> n >> s;
b = s;
for(; i<10; ++i){
for(j=0;j<n;++j) s[j]=(s[j]-'0'+1)%10+'0';
a=s+s;
for(j=0;j<n;++j) b=min(b, a.substr(j,n));
}
cout << b;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n,x,y;
    string s,a,b;
    cin>>n>>s;
    vector<string>v;
    for(int i=0;i<n;++i){
        a.clear(),b.clear();
        x=(s[i]-'0'),x=10-x;
        if(i==0){
            for(int j=0;j<n;++j){
                y=((s[j]-'0')+x)%10;
                a+=(y+'0');
            }
            v.push_back(a);
        }else if(s[i]!=s[i-1]){
            for(int j=0;j<i;++j){
                y=((s[j]-'0')+x)%10;
                a+=(y+'0');
            }
            for(int j=i;j<n;++j){
                y=((s[j]-'0')+x)%10;
                b+=(y+'0');
            }
        v.push_back(b+a);
        }
    }
    sort(v.begin(),v.end());
    cout<<v[0];
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n,x,y;
    string s,a,b;
    cin>>n>>s;
    vector<string>v;
    for(int i=0;i<n;++i){
        a.clear(),b.clear();
        x=(s[i]-'0');
        if(i==0){
            for(int j=0;j<n;++j){
                y=((s[j]-'0')+x)%10;
                a+=(y+'0');
            }
            v.push_back(a);
        }else if(s[i]!=s[i-1]){
            for(int j=0;j<i;++j){
                y=((s[j]-'0')+x)%10;
                a+=(y+'0');
            }
            for(int j=i;j<n;++j){
                y=((s[j]-'0')+x)%10;
                b+=(y+'0');
            }
        }
        v.push_back(b+a);
    }
    sort(v.begin(),v.end());
    cout<<v[0];
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n,x,y;
    string s,a,b;
    cin>>n>>s;
    vector<string>v;
    for(int i=0;i<n;++i){
        a.clear(),b.clear();
        x=(s[i]-'0'),x=10-x;
        if(i==0){
            for(int j=0;j<n;++j){
                y=((s[j]-'0')+x)%10;
                a+=(y+'0');
            }
            v.push_back(a);
        }else if(s[i]!=s[i-1]){
            for(int j=0;j<i;++j){
                y=((s[j]-'0')+x)%10;
                a+=(y+'0');
            }
            for(int j=i;j<n;++j){
                y=((s[j]-'0')+x)%10;
                b+=(y+'0');
            }
        }
        v.push_back(b+a);
    }
    sort(v.begin(),v.end());
    cout<<v[0];
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int (i) = (int)a; (i) <=(int)n; ++(i))
#define repa(i,a) for(auto &(i):a)
#define repr(i,a,n) for(int (i) = (int)a; i >=(int)n; --(i))
#define pii pair<int,int>
#define set(x, v) memset(x, v, sizeof(x))
#define vi vector<int>
#define FRead std::ios::sync_with_stdio(false);
#define vii vector<pii>
#define sz(s) s.size()
#define sortAr(x,n) sort(x, x+n)
#define ALL(x) x.begin(), x.end()
#define REV(x) reverse(ALL(x));
using namespace std;
int ar[(int)2e5];
int main() {
	FRead;
	int n;
	string s;
	cin >>n>> s;
	string res = s;
	if (sz(s) == 1)
		return cout << "0\n", 0;
	rep(i, 1, 10*n) {
		string t = s;
		do {
			char a = t[sz(t) - 1];
			t.erase(sz(t) - 1);
			t = a + t;
			res = min(res, t);
		} while (t != s);
		string tmp = s;
		rep(j, 1, sz(s)) {
			int x = s[j - 1] - '0';
			x = (x + 1) % 10;
			s[j - 1] = x + '0';
		}
		res = min(res, s);
	}
	cout << res << endl;
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int (i) = (int)a; (i) <=(int)n; ++(i))
#define repa(i,a) for(auto &(i):a)
#define repr(i,a,n) for(int (i) = (int)a; i >=(int)n; --(i))
#define pii pair<int,int>
#define set(x, v) memset(x, v, sizeof(x))
#define vi vector<int>
#define FRead std::ios::sync_with_stdio(false);
#define vii vector<pii>
#define sz(s) s.size()
#define sortAr(x,n) sort(x, x+n)
#define ALL(x) x.begin(), x.end()
#define REV(x) reverse(ALL(x));
using namespace std;
int ar[(int)2e5];
int main() {
	FRead;
	int n;
	string s;
	cin >>n>> s;
	string res = s;
	if (sz(s) == 1)
		return cout << "0\n", 0;
	rep(i, 1, 10) {
		string t = s;
		rep(k, 1, n) {
			repr(j, sz(s) - 1, 1) {
				swap(t[j], t[j - 1]);
			}
			res = min(res, t);
		}
		string tmp = s;
		rep(j, 1, sz(s)) {
			int x = s[j - 1] - '0';
			x = (x + 1) % 10;
			s[j - 1] = x + '0';
		}
		res = min(res, s);
	}
	cout << res << endl;
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int (i) = (int)a; (i) <=(int)n; ++(i))
#define repa(i,a) for(auto &(i):a)
#define repr(i,a,n) for(int (i) = (int)a; i >=(int)n; --(i))
#define pii pair<int,int>
#define set(x, v) memset(x, v, sizeof(x))
#define vi vector<int>
#define FRead std::ios::sync_with_stdio(false);
#define vii vector<pii>
#define sz(s) s.size()
#define sortAr(x,n) sort(x, x+n)
#define ALL(x) x.begin(), x.end()
#define REV(x) reverse(ALL(x));
using namespace std;
int ar[(int)2e5];
int main() {
	FRead;
	int n;
	string s;
	cin >>n>> s;
	string res = s;
	if (sz(s) == 1)
		return cout << "0\n", 0;
	rep(i, 1, 10) {
		rep(k, 1, n) {
			repr(j, sz(s) - 1, 1) {
				swap(s[j], s[j - 1]);
			}
			res = min(res, s);
		}
		rep(j, 1, sz(s)) {
			int x = s[j - 1] - '0';
			x = (x + 1) % 10;
			s[j - 1] = x + '0';
		}
		res = min(res, s);
	}
	cout << res << endl;
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int (i) = (int)a; (i) <=(int)n; ++(i))
#define repa(i,a) for(auto &(i):a)
#define repr(i,a,n) for(int (i) = (int)a; i >=(int)n; --(i))
#define pii pair<int,int>
#define set(x, v) memset(x, v, sizeof(x))
#define vi vector<int>
#define FRead std::ios::sync_with_stdio(false);
#define vii vector<pii>
#define sz(s) s.size()
#define sortAr(x,n) sort(x, x+n)
#define ALL(x) x.begin(), x.end()
#define REV(x) reverse(ALL(x));
using namespace std;
int ar[(int)2e5];
int main() {
	FRead;
	int n;
	string s;
	cin >>n>> s;
	string res = s;
	if (sz(s) == 1)
		return cout << "0\n", 0;
	rep(i, 1, 9) {
		string t = s;
		do {
			char a = t[sz(t) - 1];
			t.erase(sz(t) - 1);
			t = a + t;
			res = min(res, t);
		} while (t != s);
		string tmp = s;
		rep(j, 1, sz(s)) {
			int x = s[j - 1] - '0';
			x = (x + 1) % 10;
			s[j - 1] = x + '0';
		}
		res = min(res, s);
	}
	cout << res << endl;
}


#include <iostream>
#include <cmath>

using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int N;
	char M[10];
	while (cin >> N >> M) {
		int mn = 1e9;
		for (int i=0; i<N; i++) {
			for (int j=0; j<=9; j++) {
				int n = 0;
				for (int k=0; k<N; k++) {
					n += (M[(2*N-k-i)%N] - '0' + j)%10 * pow(10, k);
				}

				mn = min(mn, n);

//				printf("%d %d  %d %d\n", i, j, n, mn);
			}
		}

		for (int k=0; k<N; k++)
			M[k] = '0' + (mn/(int)pow(10, N-k-1))%10;
		cout << M << '\n';
	}
	return 0;
}


#include <iostream>
#include <cmath>

using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int N;
	char M[1234];
	while (cin >> N >> M) {
		char mn[1234];
		char n[1234];
		strcpy(mn, M);
		strcpy(n, M);
		for (int i=0; i<N; i++) {
			for (int j=0; j<=9; j++) {
				for (int k=0; k<N; k++) {
					n[k] = (M[(k+i)%N] - '0' + j)%10 + '0';
//					n += (M[(2*N-k-i)%N] - '0' + j)%10 * pow(10, k);
				}

				if (strcmp(n, mn) < 0)
					strcpy(mn, n);

//				printf("%d %d  %d %d\n", i, j, n, mn);
			}
		}

//		for (int k=0; k<N; k++)
//			M[k] = '0' + (mn/(int)pow(10, N-k-1))%10;
		cout << mn << '\n';
	}
	return 0;
}


#include <iostream>
#include <cmath>

using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int N;
	char M[10];
	while (cin >> N >> M) {
		int mn = 1234;
		for (int i=0; i<N; i++) {
			for (int j=0; j<=9; j++) {
				int n = 0;
				for (int k=0; k<N; k++) {
					n += (M[(2*N-k-i)%N] - '0' + j)%10 * pow(10, k);
				}

				mn = min(mn, n);
			}
		}

		for (int k=0; k<N; k++)
			M[k] = '0' + (mn/(int)pow(10, N-k-1))%10;
		cout << M << '\n';
	}
	return 0;
}


#include <iostream>
#include <cstring>

using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int N;
	char M[1234];
	while (cin >> N >> M) {
		char mn[1234];
		char n[1234];
		strcpy(mn, M);
		strcpy(n, M);
		for (int i=0; i<N; i++) {
			for (int j=0; j<=9; j++) {
				for (int k=0; k<N; k++)
					n[k] = (M[(k+i)%N] - '0' + j)%10 + '0';

				if (strcmp(n, mn) < 0)
					strcpy(mn, n);
			}
		}
		cout << mn << '\n';
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

int ans[1005][1005];
class pp{
public:
    int a[1005];
};

int a[1005];
bool flag[1005];
int k=0;
int main(){
    int len;
    cin>>len;
    char ch;
    int num=0;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
        if(a[i]-a[i-1]==0&&i>1)
        num++;
    }
    if(len==1){
        cout<<0<<endl;
        return 0;
    }
    if(num==len-1){
        for(int i=1;i<=len;i++)
        cout<<0;
        cout<<endl;
        return 0;
    }
    for(int i=1;i<=len;i++){
    k++;
    int l=0;
    for(int j=i;j<=len;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    for(int j=1;j<i;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    }

   /*  for(int i=1;i<=k;i++){
        for(int j=0;j<len;j++)
        cout<<ans[i][j];
        cout<<endl;
    } */

    /*  */
    queue<pp> qu;
    while(!qu.empty())
        qu.pop();
    for(int j=1;j<len;j++){//第几个数字
       /* for(int i=1;i<=k;i++){
            for(int h=0;h<len;h++)
            cout<<ans[i][h];
            cout<<endl;       } */

        for(int i=1;i<=k;i++){//对于所有符合的情况筛选j位置最小的那些数
            if(qu.empty()){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
                continue;
            }
            pp t=qu.front();
            if(ans[i][j]==t.a[j]){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else if(ans[i][j]<t.a[j]){
                while(!qu.empty())
                    qu.pop();
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else continue;
       }
        k=0;     //取出队列中的放进数组
        while(!qu.empty()){
        pp t=qu.front();
        qu.pop();
        ++k;
        for(int h=0;h<len;h++)
            ans[k][h]=t.a[h];
       }
       //cout<<k<<endl;
       if(k==1||j==len-1){
            //cout<<"len="<<len<<endl;
            for(int i=0;i<len;i++)
            cout<<ans[1][i];//<<" ";
            cout<<endl;
            break;
       }
    }
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

int ans[1005][1005];
class pp{
public:
    int a[1005];
};

int a[1005];
bool flag[1005];
int k=0;
int main(){
    int len;
    cin>>len;
    char ch;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
    }
    if(len==1){
        cout<<0<<endl;
        return 0;
    }
    for(int i=1;i<=len;i++){
    k++;
    int l=0;
    for(int j=i;j<=len;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    for(int j=1;j<i;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    }

   /*  for(int i=1;i<=k;i++){
        for(int j=0;j<len;j++)
        cout<<ans[i][j];
        cout<<endl;
    } */

    /*  */
    queue<pp> qu;
    while(!qu.empty())
        qu.pop();
    for(int j=1;j<len;j++){//第几个数字
       /* for(int i=1;i<=k;i++){
            for(int h=0;h<len;h++)
            cout<<ans[i][h];
            cout<<endl;       } */

        for(int i=1;i<=k;i++){//对于所有符合的情况筛选j位置最小的那些数
            if(qu.empty()){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
                continue;
            }
            pp t=qu.front();
            if(ans[i][j]==t.a[j]){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else if(ans[i][j]<t.a[j]){
                while(!qu.empty())
                    qu.pop();
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else continue;
       }
        k=0;     //取出队列中的放进数组
        while(!qu.empty()){
        pp t=qu.front();
        qu.pop();
        ++k;
        for(int h=0;h<len;h++)
            ans[k][h]=t.a[h];
       }
       //cout<<k<<endl;
       if(k==1||j==len-1){
            //cout<<"len="<<len<<endl;
            for(int i=0;i<len;i++)
            cout<<ans[1][i];//<<" ";
            cout<<endl;
            break;
       }
    }
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

int ans[1005][1005];
class pp{
public:
    int a[1005];
};

int a[1005];
bool flag[1005];
int k=0;
int main(){
    int len;
    cin>>len;
    char ch;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
    }
    if(len==1){
        cout<<0<<endl;
        return 0;
    }
    for(int i=1;i<=len;i++){
    k++;
    int l=0;
    for(int j=i;j<=len;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    for(int j=1;j<i;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    }

   /*  for(int i=1;i<=k;i++){
        for(int j=0;j<len;j++)
        cout<<ans[i][j];
        cout<<endl;
    } */

    /*  */
    queue<pp> qu;
    while(!qu.empty())
        qu.pop();
    for(int j=1;j<len;j++){//第几个数字
       /* for(int i=1;i<=k;i++){
            for(int h=0;h<len;h++)
            cout<<ans[i][h];
            cout<<endl;       } */

        for(int i=1;i<=k;i++){//对于所有符合的情况筛选j位置最小的那些数
            if(qu.empty()){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
                continue;
            }
            pp t=qu.front();
            if(ans[i][j]==t.a[j]){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else if(ans[i][j]<t.a[j]){
                while(!qu.empty())
                    qu.pop();
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else continue;
       }
        k=0;     //取出队列中的放进数组
        while(!qu.empty()){
        pp t=qu.front();
        qu.pop();
        ++k;
        for(int h=0;h<len;h++)
            ans[k][h]=t.a[h];
       }
       //cout<<k<<endl;
       if(k==1||j==len-1){
            //cout<<"len="<<len<<endl;
            for(int h=1;h<=k;h++)
            for(int i=0;i<len;i++)
            cout<<ans[h][i];//<<" ";
            cout<<endl;
            break;
       }
    }
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

class pp{
public:
    string a;
    bool operator<(const pp &t)const{
        return a>t.a;
    }
};

priority_queue< pp >qu;

string  ans[1005];
int a[1005];

int main(){
    int len;
    cin>>len;
    char ch;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
    }
    if(len==1){
        cout<<0<<endl;
        return 0;
    }
    int k=0;
    for(int i=1;i<=len;i++){
        k++;
        for(int j=i;j<=len;j++)
            ans[k]+=((a[j]-a[i]+10)%10+'0');
        for(int j=1;j<i;j++)
            ans[k]+=((a[j]-a[i]+10)%10+'0');
        pp m;
        m.a=ans[k];
        qu.push(m);
    }
    pp t=qu.top();
    cout<<t.a<<endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

string  ans[1005];
class pp{
public:
    string a;
    bool operator<(const pp &t)const{
        return a<t.a;
    }
};

priority_queue<pp,vector<pp>,greater<pp> >qu;

int a[1005];
int k=0;
int main(){
    int len;
    cin>>len;
    char ch;
    int num=0;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
    }
    if(len==1){
        cout<<0<<endl;
        return 0;
    }
    for(int i=1;i<=len;i++){
        k++;
        for(int j=i;j<=len;j++)
            ans[k]+=(a[j]-a[i]+10)%10+'0';
        for(int j=1;j<i;j++)
            ans[k]+=(a[j]-a[i]+10)%10+'0';
        pp m;
        m.a=ans[k];
        qu.push(m);
    }
    pp t=qu.top();
    cout<<t.a<<endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

int ans[1005][1005];
class pp{
public:
    int a[1005];
};

int a[1005];
bool flag[1005];
int k=0;
int main(){
    int len;
    cin>>len;
    char ch;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
    }

    for(int i=1;i<=len;i++){
    k++;
    int l=0;
    for(int j=i;j<=len;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    for(int j=1;j<i;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    }

   /*  for(int i=1;i<=k;i++){
        for(int j=0;j<len;j++)
        cout<<ans[i][j];
        cout<<endl;
    } */

    /*  */
    queue<pp> qu;
    while(!qu.empty())
        qu.pop();
    for(int j=1;j<len;j++){//第几个数字
       /* for(int i=1;i<=k;i++){
            for(int h=0;h<len;h++)
            cout<<ans[i][h];
            cout<<endl;       } */

        for(int i=1;i<=k;i++){//对于所有符合的情况筛选j位置最小的那些数
            if(qu.empty()){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
                continue;
            }
            pp t=qu.front();
            if(ans[i][j]==t.a[j]){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else if(ans[i][j]<t.a[j]){
                while(!qu.empty())
                    qu.pop();
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else continue;
       }
        k=0;     //取出队列中的放进数组
        while(!qu.empty()){
        pp t=qu.front();
        qu.pop();
        ++k;
        for(int h=0;h<len;h++)
            ans[k][h]=t.a[h];
       }
       //cout<<k<<endl;
       if(k==1||j==len-1){
            //cout<<"len="<<len<<endl;
            for(int h=1;h<=k;h++)
            for(int i=0;i<len;i++)
            cout<<ans[h][i];//<<" ";
            cout<<endl;
            break;
       }
    }
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

int ans[1005][1005];
class pp{
public:
    int a[1005];
};

int a[1005];
bool flag[1005];
int k=0;
int main(){
    int len;
    cin>>len;
    char ch;
    int num=0;
    for(int i=1;i<=len;i++){
        cin>>ch;
        a[i]=ch-'0';
        if(a[i]-a[i-1]==0&&i>1)
        num++;
    }
    if(len==1){
        cout<<0<<endl;
        return 0;
    }
    if(num==len-1){
        for(int i=1;i<=len;i++)
        cout<<0;
        cout<<endl;
    }
    for(int i=1;i<=len;i++){
    k++;
    int l=0;
    for(int j=i;j<=len;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    for(int j=1;j<i;j++)
    ans[k][l++]=(a[j]-a[i]+10)%10;
    }

   /*  for(int i=1;i<=k;i++){
        for(int j=0;j<len;j++)
        cout<<ans[i][j];
        cout<<endl;
    } */

    /*  */
    queue<pp> qu;
    while(!qu.empty())
        qu.pop();
    for(int j=1;j<len;j++){//第几个数字
       /* for(int i=1;i<=k;i++){
            for(int h=0;h<len;h++)
            cout<<ans[i][h];
            cout<<endl;       } */

        for(int i=1;i<=k;i++){//对于所有符合的情况筛选j位置最小的那些数
            if(qu.empty()){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
                continue;
            }
            pp t=qu.front();
            if(ans[i][j]==t.a[j]){
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else if(ans[i][j]<t.a[j]){
                while(!qu.empty())
                    qu.pop();
                pp c;
                for(int h=0;h<len;h++)
                c.a[h]=ans[i][h];
                qu.push(c);
            }
            else continue;
       }
        k=0;     //取出队列中的放进数组
        while(!qu.empty()){
        pp t=qu.front();
        qu.pop();
        ++k;
        for(int h=0;h<len;h++)
            ans[k][h]=t.a[h];
       }
       //cout<<k<<endl;
       if(k==1||j==len-1){
            //cout<<"len="<<len<<endl;
            for(int i=0;i<len;i++)
            cout<<ans[1][i];//<<" ";
            cout<<endl;
            break;
       }
    }
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

int main()
{
    int n; cin >> n;
    string s; cin >> s;
    int sum = INT_MAX;
    char m = '9';
    string ans = "";
    for(int i = 0; i < 10; i++)
    {
        int t = 0;
        for(int j = 0; j < n; j++)
        {
            if(s[j] == '9')
                s[j] = '0';
            else
                s[j]++;
            t+=s[j];
        }
        if(t < sum)
        {
            sum = t;
            ans = s;
        }
    }
    int ctr[10];
    vector<int> v;
    for(int i = 0; i < n; i++)
        m = min(m, ans[i]);
    for(int i = 0; i < n; i++)
        if(ans[i] == m)
            v.push_back(i);
    vector<string> str;
    for(int i = 0; i < v.size(); i++)
    {
        string t1 = ans.substr(v[i], n-v[i]);
        string t2 = ans.substr(0, v[i]);
        string t = t1+t2;
        str.push_back(t);
    }
    sort(str.begin(), str.end());
    cout << str[0];

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

int main()
{
    int n; cin >> n;
    string s; cin >> s;
    string ans = s;
    for(int i = 0; i < n; i++)
    {
        s = s[n-1]+s.substr(0, n-1);
        for(int j = 0; j < 10; j++)
        {
            for(int k = 0; k < n; k++)
            {
                if(s[k] == '9')
                    s[k] = '0';
                else
                    s[k]++;
            }
            ans = min(ans, s);
        }
    }
    cout << ans;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

int main()
{
    int n; cin >> n;
    string s; cin >> s;
    int sum = INT_MAX;
    char m = '9';
    vector<string> ans;
    for(int i = 0; i < 10; i++)
    {
        int t = 0;
        for(int j = 0; j < n; j++)
        {
            if(s[j] == '9')
                s[j] = '0';
            else
                s[j]++;
            t+=s[j];
        }
        if(t <= sum)
        {
            sum = t;
            ans.push_back(s);
        }
    }
    //for(int i = 0; i < ans.size(); i++)
        //cout << ans[i] << endl;
    vector<string> str;
    for(int j = 0; j < ans.size(); j++)
    {
        vector<int> v;
        for(int i = 0; i < n; i++)
            m = min(m, ans[j][i]);
        for(int i = 0; i < n; i++)
            if(ans[j][i] == m)
                v.push_back(i);
        for(int i = 0; i < v.size(); i++)
        {
            string t1 = ans[j].substr(v[i], n-v[i]);
            string t2 = ans[j].substr(0, v[i]);
            string t = t1+t2;
            str.push_back(t);
        }
    }
    sort(str.begin(), str.end());
    cout << str[0];
    //for(int i = 0; i < str.size(); i++)
        //cout << str[i]<<endl;

    return 0;
}


#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

int main()
{
    string mystr ;
    int disp ;
    vector<string> myans;
    while(cin>>disp>>mystr)
    {
        int sz = mystr.length() ;
        myans.clear();
        for(int i = 0 ; i < 10 ;i++)
        {
            // Add All bit 1  First butt
            for(int j = 0 ; j < sz  ; j++)
            {
             //   cout<<mystr<<"*"<<endl;
                mystr[j] = ( (mystr[j]-'0'+1)%10 ) +'0' ;
            }

                string tm = mystr ;
            // second Shift digit
            for(int j = 1 ; j < disp ; j++)
            {
                 myans.push_back(tm);
                    char dele_char = tm[0] ;
                tm.erase(0,1);
                tm+= dele_char ;

            /*    char dele_char = mystr[0] ;
                mystr.erase(0,1);
                mystr+= dele_char ;
                myans.push_back(mystr);*/
            }
        }
        sort(myans.begin() , myans.end());
        cout<<myans[0]<<endl;
    }

}


#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

int main()
{
    string mystr ;
    int disp ;
    vector<string> myans;
    while(cin>>disp>>mystr)
    {
        int sz = mystr.length() ;
        myans.clear();
        for(int i = 0 ; i < sz ;i++)
        {
            // Add All bit 1  First butt
            for(int j = 0 ; j < sz  ; j++)
            {
             //   cout<<mystr<<"*"<<endl;
                mystr[j] = ( (mystr[j]-'0'+1)%10 ) +'0' ;
            }

                string tm = mystr ;
            // second Shift digit
            for(int j = 1 ; j < disp ; j++)
            {
                 myans.push_back(tm);
                    char dele_char = tm[0] ;
                tm.erase(0,1);
                tm+= dele_char ;

            /*    char dele_char = mystr[0] ;
                mystr.erase(0,1);
                mystr+= dele_char ;
                myans.push_back(mystr);*/
            }
        }
        sort(myans.begin() , myans.end());
        cout<<myans[0]<<endl;
    }

}


#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

int main()
{
    string mystr ;
    int disp ;
    vector<string> myans;
    while(cin>>disp>>mystr)
    {
        int sz = mystr.length() ;
        myans.clear();
        for(int i = 0 ; i < 10 ;i++)
        {
            // Add All bit 1  First butt
            for(int j = 0 ; j < sz  ; j++)
            {
             //   cout<<mystr<<"*"<<endl;
                mystr[j] = ( (mystr[j]-'0'+1)%10 ) +'0' ;
            }

                string tm = mystr ;
            // second Shift digit
            for(int j = 0 ; j < disp ; j++)
            {
                 myans.push_back(tm);
                    char dele_char = tm[0] ;
                tm.erase(0,1);
                tm+= dele_char ;

            /*    char dele_char = mystr[0] ;
                mystr.erase(0,1);
                mystr+= dele_char ;
                myans.push_back(mystr);*/
            }
        }
        sort(myans.begin() , myans.end());
        cout<<myans[0]<<endl;
    }

}


#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 100010;
const LL INF = 1000000000;
LL val[MAXN];
int fa[MAXN];
int sz[MAXN];
int N,M,P,Q;
int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}
struct node
{
    int root;
    LL val;
    bool operator < (const node &rhs) const
    {
        return val > rhs.val;
    }
};
priority_queue<node>q;
vector<pair<int,int> >res;

int main()
{
    while (scanf("%d%d%d%d",&N,&M,&P,&Q) != EOF)
    {
        for (int i = 0 ; i <= N ; i++)
        {
            fa[i] = i;
            val[i] = 0;
            sz[i] = 1;
        }
        for (int i = 0 ; i < M ; i++)
        {
            int u,v;
            LL w;
            scanf("%d%d%I64d",&u,&v,&w);
            int fu = Find(u);
            int fv = Find(v);
           // printf("%d %d %I64d %I64d\n",fu,fv,val[fu],val[fv]);
            if (fu != fv)
            {
                fa[fv] = fu;
                val[fu] += (val[fv] + w);
                sz[fu] += sz[fv];
                sz[fv] = 0;
            }
            else val[fu] += w;
        }
        int cnt = 0;
        for (int i = 1 ; i <= N ; i++)
        {
            int fi = Find(i);
            if (fi == i)
            {
                node tmp;
                tmp.root = i;
                tmp.val = val[fi];
               // printf("%d %I64d\n",i,val[fi]);
                q.push(tmp);
                cnt++;
            }
        }
       // puts("");
        if (cnt < Q)
        {
            puts("NO");
            continue;
        }
        bool found = true;
        res.clear();
        for (int i = 1 ; i <= P ; i++)
        {
            if (cnt == Q)
            {
                int tot = P - i + 1;
                if (found && M == 0)
                {
                    puts("NO");
                    return 0;
                }
                else
                {
                    bool flag = false;
                    for (int j = 1 ; j <= N && !flag; j++)
                    {
                        int fj = Find(j),fk,pos;
                        if (sz[fj] >= 2)
                        {
                            for (int k = j + 1 ; k <= N ; k++)
                            {
                                fk = Find(k);
                                if (fj == fk)
                                {
                                    flag = true;
                                    pos = k;
                                    break;
                                }

                            }
                        }
                        //if (flag) printf("%d %d %d\n",j,pos,tot);
                        if (flag) for (int k = 1 ; k <= tot ; k++) res.push_back(make_pair(j,pos));
                    }
                }
                break;
            }
            if(q.empty())  break;
            node x = q.top(); q.pop();
            if (q.empty()) break;
            node y = q.top(); q.pop();
            found = false;
            int fx = x.root;
            int fy = y.root;
            fa[fy] = fx;
            val[fx] += val[fy];
            val[fx] += min(INF,val[fx] + 1);
            sz[fx] += sz[fy];
            sz[fy] = 0;
            node tmp;
            tmp.root = fx;
            tmp.val = val[fx];
            cnt--;
            q.push(tmp);
            res.push_back(make_pair(fx,fy));
        }
        if (cnt == Q)
        {
            puts("YES");
            for (int i = 0 ; i < (int)res.size() ; i++)
                printf("%d %d\n",res[i].first,res[i].second);
        }
        else puts("NO");
    }
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<cstring>
#include<map>
#include<set>
#include<list>
#include<stack>
#include<algorithm>
#include<queue>
#include<vector>
#include<time.h>
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const long long INF=1e9;
typedef long long ll;
const double eps = 1e-8;
const int row=3000;
const int cow=220;
const int MAXN=cow*cow;

int n,m,all,p,q;
ll f[200000],dp[200000];

struct node{
    ll x,v;
    bool operator <(const node k)const{
        return v>k.v;
    }
}ans[110000];

int Find(int x){
    if(x!=f[x])f[x]=Find(f[x]);
    return f[x];
}

void Link(ll x,ll y,ll v){
    int fx=Find(x);
    int fy=Find(y);
    if(fx==fy){
        dp[fx]+=v;
        dp[fx]=min(dp[fx]+1,INF);
    }
    else{
        f[fx]=fy;
        dp[fy]+=dp[fx];
        dp[fy]+=v;
        dp[fy]=min(dp[fy]+1,INF);
        all--;
    }
}

int main()
{
    //freopen("1","r",stdin);
    int i,j,t;
    scanf("%d%d%d%d",&n,&m,&p,&q);
    for(i=1;i<=n;i++)f[i]=i;
    memset(dp,0,sizeof(dp));
    all=n;
    bool flag=false;
    int x1,y1;
    for(i=0;i<m;i++){
        ll a,b,c;
        cin>>a>>b>>c;
        Link(a,b,c);
        x1=a,y1=b;
        flag=true;
    }
    if(all-p>q||all<q)printf("NO\n");
    else{

        if(m==0&&all==q&&p){
            printf("NO\n");
            return 0;
        }
        priority_queue<node> que;
        for(i=1;i<=n;i++){
            if(f[i]==i){
                node x={i,dp[i]};
                que.push(x);
            }
        }
        //cout<<x1<<"  "<<y1<<endl;
        for(i=0;i<p;i++){
            //cout<<i<<endl;
            if(all==q){
                ans[i].x=x1;
                ans[i].v=y1;
                int fx=Find(x1);
                dp[fx]+=1000;
                dp[fx]=min(dp[fx]+1,INF);
                continue;
            }
            node x=que.top();
            que.pop();
            node y=que.top();
            que.pop();
            ll v=min(INF,x.v+y.v+1);
            Link(x.x,y.x,v);
            node w={y.x,v};
            que.push(w);
            ans[i].x=x.x;
            ans[i].v=y.x;
            if(!flag){
                x1=x.x;
                y1=y.x;
                flag=true;
            }
        }
        printf("YES\n");
        for(j=0;j<p;j++){
            cout<<ans[j].x<<" "<<ans[j].v<<endl;
        }
    }
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<cstring>
#include<map>
#include<set>
#include<list>
#include<stack>
#include<algorithm>
#include<queue>
#include<vector>
#include<time.h>
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const long long INF=1e9;
typedef long long ll;
const double eps = 1e-8;
const int row=3000;
const int cow=220;
const int MAXN=cow*cow;

int n,m,all,p,q;
ll f[200000],dp[200000];

struct node{
    ll x,v;
    bool operator <(const node k)const{
        return v>k.v;
    }
}ans[110000];

int Find(int x){
    if(x!=f[x])f[x]=Find(f[x]);
    return f[x];
}

void Link(ll x,ll y,ll v){
    int fx=Find(x);
    int fy=Find(y);
    if(fx==fy){
        dp[fx]+=v;
        dp[fx]=min(dp[fx],INF);
    }
    else{
        f[fx]=fy;
        dp[fy]+=dp[fx];
        dp[fy]+=v;
        dp[fy]=min(dp[fy],INF);
        all--;
    }
}

int main()
{
    //freopen("1","r",stdin);
    int i,j,t;
    scanf("%d%d%d%d",&n,&m,&p,&q);
    for(i=1;i<=n;i++)f[i]=i;
    memset(dp,0,sizeof(dp));
    all=n;
    for(i=0;i<m;i++){
        ll a,b,c;
        cin>>a>>b>>c;
        Link(a,b,c);
    }
    if(all-p>q||all<q)printf("NO\n");
    else{

        if(m==0&&all==q&&p){
            printf("NO\n");
            return 0;
        }
        if(all==q){
            printf("YES\n");
            return 0;
        }
        priority_queue<node> que;
        for(i=1;i<=n;i++){
            if(f[i]==i){
                node x={i,dp[i]};
                que.push(x);
            }
        }
        for(i=0;i<p;i++){
            node x=que.top();
            que.pop();
            if(que.empty())break;
            node y=que.top();
            que.pop();
            if(que.empty())break;
            ll v=min(INF,x.v+y.v);
            Link(x.x,y.x,v);
            node w={y.x,v};
            que.push(w);
            ans[i].x=x.x;
            ans[i].v=y.x;
            if(all==q)break;
        }
        printf("YES\n");
        for(j=0;j<=i;j++){
            cout<<ans[j].x<<" "<<ans[j].v<<endl;
        }
    }
    return 0;
}


#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 100010;
const LL INF = 1000000000;
LL val[MAXN];
int fa[MAXN];
int sz[MAXN];
int N,M,P,Q;
int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}
struct node
{
    int root;
    LL val;
    bool operator < (const node &rhs) const
    {
        return val > rhs.val;
    }
};
priority_queue<node>q;
vector<pair<int,int> >res;

int main()
{
    while (scanf("%d%d%d%d",&N,&M,&P,&Q) != EOF)
    {
        for (int i = 0 ; i <= N ; i++)
        {
            fa[i] = i;
            val[i] = 0;
            sz[i] = 1;
        }
        for (int i = 0 ; i < M ; i++)
        {
            int u,v;
            LL w;
            scanf("%d%d%I64d",&u,&v,&w);
            int fu = Find(u);
            int fv = Find(v);
           // printf("%d %d %I64d %I64d\n",fu,fv,val[fu],val[fv]);
            if (fu != fv)
            {
                fa[fv] = fu;
                val[fu] += (val[fv] + w);
                sz[fu] += sz[fv];
            }
            else val[fu] += w;
        }
        int cnt = 0;
        for (int i = 1 ; i <= N ; i++)
        {
            int fi = Find(i);
            if (fi == i)
            {
                node tmp;
                tmp.root = i;
                tmp.val = val[fi];
               // printf("%d %I64d\n",i,val[fi]);
                q.push(tmp);
                cnt++;
            }
        }
       // puts("");
        if (cnt < Q)
        {
            puts("NO");
            continue;
        }
        res.clear();
        for (int i = 1 ; i <= P ; i++)
        {
            if (cnt == Q)
            {
                int tot = P - i + 1;
                if (M == 0)
                {
                    puts("NO");
                    return 0;
                }
                else
                {
                    bool flag = false;
                    for (int j = 1 ; j <= N && !flag; j++)
                    {
                        int fj = Find(j),fk,pos;
                        if (sz[fj] >= 2)
                        {
                            for (int k = j + 1 ; k <= N ; k++)
                            {
                                fk = Find(k);
                                if (fj == fk)
                                {
                                    flag = true;
                                    pos = k;
                                    break;
                                }

                            }
                        }
                        if (flag) for (int j = 1 ; j <= tot ; j++) res.push_back(make_pair(j,pos));
                    }
                }
            }
            if(q.empty())  break;
            node x = q.top(); q.pop();
            if (q.empty()) break;
            node y = q.top(); q.pop();
            int fx = x.root;
            int fy = y.root;
            fa[fy] = fx;
            val[fx] += val[fy];
            val[fx] += min(INF,val[fx] + 1);
            node tmp;
            tmp.root = fx;
            tmp.val = val[fx];
            cnt--;
            q.push(tmp);
            res.push_back(make_pair(fx,fy));
        }
        if (cnt == Q)
        {
            puts("YES");
            for (int i = 0 ; i < (int)res.size() ; i++)
                printf("%d %d\n",res[i].first,res[i].second);
        }
        else puts("NO");
    }
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<cstring>
#include<map>
#include<set>
#include<list>
#include<stack>
#include<algorithm>
#include<queue>
#include<vector>
#include<time.h>
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const long long INF=1e9;
typedef long long ll;
const double eps = 1e-8;
const int row=3000;
const int cow=220;
const int MAXN=cow*cow;

int n,m,all,p,q;
ll f[200000],dp[200000];

struct node{
    ll x,v;
    bool operator <(const node k)const{
        return v>k.v;
    }
}ans[110000];

int Find(int x){
    if(x!=f[x])f[x]=Find(f[x]);
    return f[x];
}

void Link(ll x,ll y,ll v){
    int fx=Find(x);
    int fy=Find(y);
    if(fx==fy){
        dp[fx]+=v;
    }
    else{
        f[fx]=fy;
        dp[fy]+=dp[fx];
        dp[fy]+=v;
        all--;
    }
}

int main()
{
    //freopen("1","r",stdin);
    int i,j,t;
    scanf("%d%d%d%d",&n,&m,&p,&q);
    for(i=1;i<=n;i++)f[i]=i;
    memset(dp,0,sizeof(dp));
    all=n;
    bool flag=false;
    int x1,y1;
    for(i=0;i<m;i++){
        ll a,b,c;
        cin>>a>>b>>c;
        Link(a,b,c);
        x1=a,y1=b;
        flag=true;
    }
    if(all-p>q||all<q)printf("NO\n");
    else{

        if(m==0&&all==q&&p){
            printf("NO\n");
            return 0;
        }
        priority_queue<node> que;
        for(i=1;i<=n;i++){
            if(f[i]==i){
                node x={i,dp[i]};
                que.push(x);
            }
        }
        //cout<<x1<<"  "<<y1<<endl;
        for(i=0;i<p;i++){
            //cout<<i<<endl;
            if(all==q){
                ans[i].x=x1;
                ans[i].v=y1;
                int fx=Find(x1);
                dp[fx]+=1000;
                continue;
            }
            node x=que.top();
            que.pop();
            node y=que.top();
            que.pop();
            ll v=min(INF,x.v+y.v+1);
            Link(x.x,y.x,v);
            node w={y.x,v};
            que.push(w);
            ans[i].x=x.x;
            ans[i].v=y.x;
            if(!flag){
                x1=x.x;
                y1=y.x;
                flag=true;
            }
        }
        printf("YES\n");
        for(j=0;j<p;j++){
            cout<<ans[j].x<<" "<<ans[j].v<<endl;
        }
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int a, int b)
{
	int para = get(a), parb = get(b);
	if (size[para] >= size[parb]) {
        size[para] += size[parb];
        pred[parb] = para;
        s[para] += s[parb];
    }
	else {
        size[parb] += size[para];
        pred[para] = parb;
        s[parb] += s[para];
    }
	c--;
}

priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        adj[x].pb(mp(y,cost));
        if (get(x)!=get(y))union_set(x, y);
        s[get(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (get(i)==i) h.push(mp(-s[i],i));

    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(u, v);
        int p=get(u);
        ll add=min(1000000000ll,s[p]+1ll);
        s[p]+=add;
        h.push(mp(-s[p],p));
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size()<p){
        int razn=(int)p-(int)ans.size();
        for (int i=1;i<=n;++i)
            if (adj[i].size()>=1){
                for (int j=1;j<=razn;++j)
                    cout << i << " " << adj[i][j].F << endl;
                break;
            }
    }
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int a, int b)
{
	int para = get(a), parb = get(b);
	if (size[para] >= size[parb]) {
        size[para] += size[parb];
        pred[parb] = para;
        s[para] += s[parb];
    }
	else {
        size[parb] += size[para];
        pred[para] = parb;
        s[parb] += s[para];
    }
	c--;
}

priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        adj[x].pb(mp(y,cost));
        adj[y].pb(mp(x,cost));
        if (get(x)!=get(y))union_set(x, y);
        s[get(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (get(i)==i) h.push(mp(-s[i],i));

    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(u, v);
        int p=get(u);
        ll add=min(1000000000ll,s[p]+1ll);
        s[p]+=add;
        h.push(mp(-s[p],p));
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size()<p){
        int razn=(int)p-(int)ans.size();
        for (int i=1;i<=n;++i)
            if (adj[i].size()>=1){
                for (int j=1;j<=razn;++j)
                    ans.pb(mp(i,adj[i][0].F));
                break;
            }
    }
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y, cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001];

vector<vector<pair<int, int> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;return;
}
priority_queue<pair<long long, int> > h;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    for (int i=1;i<=n;++i)pred[i]=i;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
    }

    for (int i=1;i<=n;++i){
        int com=get(i);
        if (key[com]) a[i]=key[com];
        else {
            ++all;
            key[com]=all;
            a[i]=all;
        }
        first[a[i]]=i;
    }

    if (all==q && p==0){
        cout << "YES" << endl;
        for (int i=1;i<=p;++i)
            cout << x << " " << y << endl;
        return 0;
    }
    if (all<q ||(all==q && p!=0)){
        cout << "NO" << endl;
        return 0;
    }
    if (all>q){
        int ost=all-q;
        if (p<ost) {
            cout << "NO";
            return 0;
        }
        cout << "YES" << endl;
        for (int i=1;i<=n;++i)
            for (int j=0;j<adj[i].size();++j){
                int cost=adj[i][j].S;
                int com=a[i];
                s[com]+=cost;
            }
        for (int i=1;i<=all;++i)
            h.push(mp(-s[i],i));
        int add=min(p,ost);
        for (int i=1;i<=add;++i){
            pair<ll, int> cur1=h.top(); h.pop();
            pair<ll, int> cur2=h.top(); h.pop();
            int u=first[cur1.S], v=first[cur2.S];
            ll S=min(-cur1.F+-cur2.F+1,(ll)1e9);
            cout << u << " " << v << endl;
            h.push(mp(-S,cur1.S));
        }
        for(int i=1;i<=p-add;++i)
            cout << x << " " << y << endl;

    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y, cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001];

vector<vector<pair<int, int> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;return;
}
priority_queue<pair<long long, int> > h;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    for (int i=1;i<=n;++i)pred[i]=i;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
    }

    for (int i=1;i<=n;++i){
        int com=get(i);
        if (key[com]) a[i]=key[com];
        else {
            ++all;
            key[com]=all;
            a[i]=all;
        }
        first[a[i]]=i;
    }

    if (all==q && p==0){
        cout << "YES";
        return 0;
    }
    if (all==q && p!=0){
        if (all==1){
            cout << "YES" << endl;
            for (int i=1;i<=p;++i)
                cout << x << " " << y << endl;
            return 0;
        }
        cout << "NO";
    }

    if (all>q){
        int ost=all-q;
        if (p<ost) {
            cout << "NO";
            return 0;
        }
        cout << "YES" << endl;
        for (int i=1;i<=n;++i)
            for (int j=0;j<adj[i].size();++j){
                int cost=adj[i][j].S;
                int com=a[i];
                s[com]+=cost;
            }
        for (int i=1;i<=all;++i)
            h.push(mp(-s[i],i));
        int add=min(p,ost);
        for (int i=1;i<=add;++i){
            pair<ll, int> cur1=h.top(); h.pop();
            pair<ll, int> cur2=h.top(); h.pop();
            int u=first[cur1.S], v=first[cur2.S];
            ll S=min(-cur1.F+-cur2.F+1,(ll)1e9);
            cout << u << " " << v << endl;
            h.push(mp(-S,cur1.S));
        }
        for(int i=1;i<=p-add;++i)
            cout << x << " " << y << endl;

    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
ll s[100001];
int comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int getPar(int x) { return pred[x] == x? x: pred[x] = getPar(pred[x]); }

void union_set(int a, int b)
{
	int para = getPar(a), parb = getPar(b);
	if (size[para] >= size[parb]) {
        size[para] += size[parb];
        pred[parb] = para;
        s[para] += s[parb];
    }
	else {
        size[parb] += size[para];
        pred[para] = parb;
        s[parb] += s[para];
    }
	c--;
}

priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);

    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        adj[x].pb(mp(y,cost));
        adj[y].pb(mp(x,cost));
        if (getPar(x)!=getPar(y))union_set(x, y);
        s[getPar(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (getPar(i)==i) h.push(mp(-s[i],i));

    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(v, u);
        int pr=getPar(v);
        ll add=min(1000000000ll,s[pr]+1ll);
        s[pr]+=add;
        h.push(mp(-s[pr],pr));
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size() < p) {
		int pr = 1;
		while (pr <= n && (getPar(pr) != pr || size[pr] < 2)) pr++;
		if (pr > n) { cout << "NO"; return 0; }
		int i = 1;
		while (getPar(i) != pr) i++;
		int j = i + 1;
		while (getPar(j) != pr) j++;
		while (ans.size() < p)
            ans.push_back(mp(i,j));
	}
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

ll n, m, p, q, x, y;
int pred[100001];
ll cost, s[100001], comp=0, a[100001],all, first[100001];

vector<vector<pair<int, int> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;return;
}
priority_queue<pair<long long, int> > h;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    for (int i=1;i<=n;++i)pred[i]=i;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
    }

    for (int i=1;i<=n;++i){
        int com=get(i);
        if (key[com]) a[i]=key[com];
        else {
            ++all;
            key[com]=all;
            a[i]=all;
        }
        first[a[i]]=i;
    }

    if (all==q && p==0){
        cout << "YES";
        return 0;
    }
    if (all==q && p!=0){
        if (all==1){
            cout << "YES" << endl;
            for (int i=1;i<=p;++i)
                cout << x << " " << y << endl;
            return 0;
        }
        cout << "NO";
    }
    if (all<q){
        cout << "NO";
        return 0;
    }

    if (all>q){
        ll ost=all-q;
        if (p<ost) {
            cout << "NO";
            return 0;
        }
        cout << "YES" << endl;
        for (int i=1;i<=n;++i)
            for (int j=0;j<adj[i].size();++j){
                ll cost=adj[i][j].S;
                ll com=a[i];
                s[com]+=cost;
            }
        for (int i=1;i<=all;++i)
            h.push(mp(-s[i],i));
        ll add=min(p,ost);
        for (int i=1;i<=add;++i){
            pair<ll, int> cur1=h.top(); h.pop();
            pair<ll, int> cur2=h.top(); h.pop();
            x=first[cur1.S], y=first[cur2.S];
            ll S=min(-cur1.F-cur2.F+1ll,(ll)1e9);
            cout << x << " " << y << endl;
            h.push(mp(-S,cur1.S));
        }
        for(int i=1;i<=p-add;++i)
            cout << x << " " << y << endl;

    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
ll s[100001];
int comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int getPar(int x) { return pred[x] == x? x: pred[x] = getPar(pred[x]); }

void union_set(int a, int b)
{
	int para = getPar(a), parb = getPar(b);
	if (size[para] >= size[parb]) {
        size[para] += size[parb];
        pred[parb] = para;
        s[para] += s[parb];
    }
	else {
        size[parb] += size[para];
        pred[para] = parb;
        s[parb] += s[para];
    }
	c--;
}

priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        adj[x].pb(mp(y,cost));
        adj[y].pb(mp(x,cost));
        if (getPar(x)!=getPar(y))union_set(x, y);
        s[getPar(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (getPar(i)==i) h.push(mp(-s[i],i));

    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(v, u);
        int pr=getPar(v);
        ll add=min(1000000000ll,s[pr]+1ll);
        s[pr]+=add;
        h.push(mp(-s[pr],pr));
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size() < p) {
		int pr = 1;
		while (pr <= n && (getPar(pr) != pr || size[pr] < 2)) pr++;
		if (pr > n) { cout << "NO"; return 0; }
		int i = 1;
		while (getPar(i) != pr) i++;
		int j = i + 1;
		while (getPar(j) != pr) j++;
		while (ans.size() < pr)
            ans.push_back(mp(i,j));
	}
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
ll s[100001];
int comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int a, int b)
{
	int para = get(a), parb = get(b);
	if (size[para] >= size[parb]) {
        size[para] += size[parb];
        pred[parb] = para;
        s[para] += s[parb];
    }
	else {
        size[parb] += size[para];
        pred[para] = parb;
        s[parb] += s[para];
    }
	c--;
}

priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        adj[x].pb(mp(y,cost));
        adj[y].pb(mp(x,cost));
        if (get(x)!=get(y))union_set(x, y);
        s[get(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (get(i)==i) h.push(mp(-s[i],i));

    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(u, v);
        int p=get(u);
        ll add=min(1000000000ll,s[p]+1ll);
        s[p]+=add;
        h.push(mp(-s[p],p));
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size()<p){
        int razn=(int)p-(int)ans.size();
        for (int i=1;i<=n;++i)
            if (adj[i].size()>=1){
                for (int j=1;j<=razn;++j)
                    ans.pb(mp(i,adj[i][0].F));
                break;
            }
    }
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y, cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001];

vector<vector<pair<int, int> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;return;
}
priority_queue<pair<long long, int> > h;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    for (int i=1;i<=n;++i)pred[i]=i;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
    }

    for (int i=1;i<=n;++i){
        int com=get(i);
        if (key[com]) a[i]=key[com];
        else {
            ++all;
            key[com]=all;
            a[i]=all;
        }
        first[a[i]]=i;
    }

    if (all==q && p==0){
        cout << "YES";
        return 0;
    }
    if (all==q && p!=0){
        if (all==1){
            cout << "YES" << endl;
            for (int i=1;i<=p;++i)
                cout << x << " " << y << endl;
            return 0;
        }
        cout << "NO";
    }
    if (all<q){
        cout << "NO";
        return 0;
    }

    if (all>q){
        int ost=all-q;
        if (p<ost) {
            cout << "NO";
            return 0;
        }
        cout << "YES" << endl;
        for (int i=1;i<=n;++i)
            for (int j=0;j<adj[i].size();++j){
                int cost=adj[i][j].S;
                int com=a[i];
                s[com]+=cost;
            }
        for (int i=1;i<=all;++i)
            h.push(mp(-s[i],i));
        int add=min(p,ost);
        for (int i=1;i<=add;++i){
            pair<ll, int> cur1=h.top(); h.pop();
            pair<ll, int> cur2=h.top(); h.pop();
            x=first[cur1.S], y=first[cur2.S];
            ll S=min(-cur1.F-cur2.F+1,(ll)1e9);
            cout << x << " " << y << endl;
            h.push(mp(-S,cur1.S));
        }
        for(int i=1;i<=p-add;++i)
            cout << x << " " << y << endl;

    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;
    s[v]+=s[u];
    size[v]+=size[u];
    --c;
}
priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
        s[get(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (get(i)==i) h.push(mp(-s[i],i));
    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(u, v);
        int p=get(u);
        s[p]+=min(1000000000ll, s[p]+1ll);
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size()<p){
        int razn=(int)p-(int)ans.size();
        for (int i=1;i<=n;++i)
            if (adj[i].size()>=1){
                for (int j=1;j<=razn;++j)
                    cout << i << " " << adj[i][j].F << endl;
                break;
            }
    }
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

ll n, m, p, q, x, y;
int pred[100001];
ll cost, s[100001], comp=0, a[100001],all, first[100001];

vector<vector<pair<int, int> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;return;
}
priority_queue<pair<long long, int> > h;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    for (int i=1;i<=n;++i)pred[i]=i;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
    }

    for (int i=1;i<=n;++i){
        int com=get(i);
        if (key[com]) a[i]=key[com];
        else {
            ++all;
            key[com]=all;
            a[i]=all;
        }
        first[a[i]]=i;
    }

    if (all==q && p==0){
        cout << "YES";
        return 0;
    }
    if (all==q && p!=0){
        if (all==1){
            if (x==0 && y==0){
                cout << "NO";
                return 0;
            }
            cout << "YES" << endl;
            for (int i=1;i<=p;++i)
                cout << x << " " << y << endl;
            return 0;
        }
        cout << "NO";
    }
    if (all<q){
        cout << "NO";
        return 0;
    }

    if (all>q){
        ll ost=all-q;
        if (p<ost) {
            cout << "NO";
            return 0;
        }
        cout << "YES" << endl;
        for (int i=1;i<=n;++i)
            for (int j=0;j<adj[i].size();++j){
                ll cost=adj[i][j].S;
                ll com=a[i];
                s[com]+=cost;
            }
        for (int i=1;i<=all;++i)
            h.push(mp(-s[i],i));
        ll add=min(p,ost);
        for (int i=1;i<=add;++i){
            pair<ll, int> cur1=h.top(); h.pop();
            pair<ll, int> cur2=h.top(); h.pop();
            x=first[cur1.S], y=first[cur2.S];
            ll S=min(-cur1.F-cur2.F+1ll,(ll)1e9);
            cout << x << " " << y << endl;
            h.push(mp(-S,cur1.S));
        }
        for(int i=1;i<=p-add;++i)
            cout << x << " " << y << endl;

    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y;
ll cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001], c, size[100001];

vector<vector<pair<int, ll> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int a, int b)
{
	int para = get(a), parb = get(b);
	if (size[para] >= size[parb]) {
        size[para] += size[parb];
        pred[parb] = para;
        s[para] += s[parb];
    }
	else {
        size[parb] += size[para];
        pred[para] = parb;
        s[parb] += s[para];
    }
	c--;
}

priority_queue<pair<long long, int> > h;
vector<pair<int, int> > ans;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    c=n;
    for (int i=1;i<=n;++i)pred[i]=i, size[i]=1;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        adj[x].pb(mp(y,cost));
        if (get(x)!=get(y))union_set(x, y);
        s[get(x)]+=cost;
    }
    if (c<q){
        cout << "NO";
        return 0;
    }
    for (int i=1;i<=n;++i)
        if (get(i)==i) h.push(mp(-s[i],i));

    while (c>q){
        int v=h.top().S; h.pop();
        int u=h.top().S; h.pop();
        union_set(u, v);
        int p=get(u);
        ll add=min(1000000000ll,s[p]+1ll);
        s[p]+=add;
        h.push(mp(-s[p],p));
        ans.pb(mp(u,v));
    }
    if (ans.size()>p){
        cout << "NO";
        return 0;
    }
    if (ans.size()<p){
        int razn=(int)p-(int)ans.size();
        for (int i=1;i<=n;++i)
            if (adj[i].size()>=1){
                for (int j=1;j<=razn;++j)
                    ans.pb(mp(i,adj[i][j].F));
                break;
            }
    }
    if (ans.size()<p) cout << "NO";
    else {
        cout << "YES" << endl;
        for (int i=0;i<p;++i)
            cout << ans[i].F << " " << ans[i].S << endl;
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>
#include <time.h>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <map>

#define INF 1000000000
#define LLINF 1000000000000000000
#define ll long long
#define F first
#define S second
#define pb push_back
#define mp make_pair

using namespace std;

int n, m, p, q, x, y, cost;
int pred[100001];
int s[100001], comp=0, a[100001],all, first[100001];

vector<vector<pair<int, int> > > adj;
map<int, int> key;

int get(int v){
    if (pred[v]==v) return v;
    return pred[v]=get(pred[v]);
}

void union_set(int u, int v){
    u=get(u), v=get(v);
    if (u==v) return;
    if (rand()&1) swap(u,v);
    pred[u]=v;return;
}
priority_queue<pair<long long, int> > h;

int main(){
    srand(time(NULL));
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);
    cin >> n >> m >> p >> q;
    for (int i=1;i<=n;++i)pred[i]=i;
    adj.resize(n+1);
    for (int i=0;i<m;++i){
        cin >> x >> y >> cost;
        if (x>y) swap(x,y);
        adj[x].pb(mp(y,cost));
        union_set(x, y);
    }

    for (int i=1;i<=n;++i){
        int com=get(i);
        if (key[com]) a[i]=key[com];
        else {
            ++all;
            key[com]=all;
            a[i]=all;
        }
        first[a[i]]=i;
    }

    if (all==q && p==0){
        cout << "YES";
        return 0;
    }
    if (all==q && p!=0){
        if (all==1){
            cout << "YES" << endl;
            for (int i=1;i<=p;++i)
                cout << x << " " << y << endl;
            return 0;
        }
        cout << "NO";
    }
    if (all<q){
        cout << "NO";
        return 0;
    }

    if (all>q){
        int ost=all-q;
        if (p<ost) {
            cout << "NO";
            return 0;
        }
        cout << "YES" << endl;
        for (int i=1;i<=n;++i)
            for (int j=0;j<adj[i].size();++j){
                int cost=adj[i][j].S;
                int com=a[i];
                s[com]+=cost;
            }
        for (int i=1;i<=all;++i)
            h.push(mp(-s[i],i));
        int add=min(p,ost);
        for (int i=1;i<=add;++i){
            pair<ll, int> cur1=h.top(); h.pop();
            pair<ll, int> cur2=h.top(); h.pop();
            int u=first[cur1.S], v=first[cur2.S];
            ll S=min(-cur1.F+-cur2.F+1,(ll)1e9);
            cout << u << " " << v << endl;
            h.push(mp(-S,cur1.S));
        }
        for(int i=1;i<=p-add;++i)
            cout << x << " " << y << endl;

    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
int  N,M,P,Q;
struct node
{
    long long cost;
    int id;
    node(){}
    node(int a,long long b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
int p[maxn];
long long val[maxn];
int find(int x)
{
    return x==p[x]? x:p[x]=find(p[x]);
}

int A,B;
int main()
{
    //freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    for(i=1;i<=N;i++)
    {
        p[i]=i;
    }
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        A=a,B=b;
        a=find(a);
        b=find(b);
        val[a]+=c;
        if(a!=b)
        {
            val[a]+=val[b];
            p[b]=a;
        }
    }
    for(i=1;i<=N;i++)
    {
        if(p[i]==i)
        {
            q.push(node(i,val[i]));
        }
    }

    int num=q.size()-Q;
    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0&&P)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();

            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            q.push(node(t1.id,min((long long)1000000000,t1.cost+t2.cost+1)));
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
struct Edge
{
    int from,to,cost,next;
    Edge(){}
    Edge(int from_,int to_,int cost_,int next_)
    {
        from=from_,to=to_,cost=cost_,next=next_;
    }
}edges[maxn*2];
int cnt;
int head[maxn];
int vis[maxn];
void addedge(int x,int y,int c)
{
    edges[cnt]=Edge(x,y,c,head[x]);
    head[x]=cnt++;
}
int  N,M,P,Q;
struct node
{
    int cost;
    int id;
    node(){}
    node(int a,int b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
struct ANS
{
    int a,b;
    ANS(){}
    ANS(int x,int y)
    {
        a=x,b=y;
    }
};
vector<int> ans;

void dfs(int cur,int& sum)
{
    int i,j;
    vis[cur]=1;
    for(i=head[cur];i!=-1;i=edges[i].next)
    {
        int v=edges[i].to;
        if(vis[v]) continue;
        sum+=edges[i].cost;
        dfs(v,sum);
    }
}
int A,B;
int main()
{
   // freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    cnt=0;
    memset(head,-1,sizeof(head));
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
        A=a,B=b;
    }
    for(i=1;i<=N;i++)
    {
        if(!vis[i])
        {
            int temp=0;
            dfs(i,temp);
            q.push(node(i,temp));
        }
    }
    int num=q.size()-Q;

    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();
            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            q.push(node(t1.id,t1.cost+t2.cost));
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
struct Edge
{
    int from,to,cost,next;
    Edge(){}
    Edge(int from_,int to_,int cost_,int next_)
    {
        from=from_,to=to_,cost=cost_,next=next_;
    }
}edges[maxn*2];
int cnt;
int head[maxn];
int vis[maxn];
void addedge(int x,int y,int c)
{
    edges[cnt]=Edge(x,y,c,head[x]);
    head[x]=cnt++;
}
int  N,M,P,Q;
struct node
{
    int cost;
    int id;
    node(){}
    node(int a,int b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
struct ANS
{
    int a,b;
    ANS(){}
    ANS(int x,int y)
    {
        a=x,b=y;
    }
};
vector<int> ans;

void dfs(int cur,int& sum)
{
    int i,j;
    vis[cur]=1;
    for(i=head[cur];i!=-1;i=edges[i].next)
    {
        int v=edges[i].to;
        if(vis[v]) continue;
        sum+=edges[i].cost;
        dfs(v,sum);
    }
}
int A,B;
int main()
{
    //freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    cnt=0;
    memset(head,-1,sizeof(head));
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
        A=a,B=b;
    }
    for(i=1;i<=N;i++)
    {
        if(!vis[i])
        {
            int temp=0;
            dfs(i,temp);
            q.push(node(i,temp));
        }
    }
    int num=q.size()-Q;

    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0&&P)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();

            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            q.push(node(t1.id,min(1000000000,t1.cost+t2.cost+1)));
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define lowbit(x) ((x) & (-(x)))
using namespace std;
typedef long long LL;
const LL MOD = 1000000007LL;
const int N = 100005;
int pre[N] , n , m , p , q;
LL r[N];
vector <pair <int , int> > ans;
int find (int x) {
    if (pre[x] != x) {
        int fa = pre[x];
        pre[x] = find (pre[x]);
        // r[pre[x]] += r[fa];
        // r[fa] = 0;
    }
    return pre[x];
}
struct Node {
    int r;
    LL v;
    Node () {}
    Node (int _r , LL _v) {
        r = _r;v = _v;
    }
    bool operator < (const Node &n) const {
        return v > n.v;
    }
};
priority_queue <Node> root;
int main () {
    #ifndef ONLINE_JUDGE
        freopen ("input.txt" , "r" , stdin);
    #endif
    scanf ("%d %d %d %d" , &n , &m , &p , &q);
    for (int i = 1 ; i <= n ; i ++)
        pre[i] = i , r[i] = 0LL;
    int u = -1 , v , w;
    for (int i = 0 ; i < m ; i ++) {
        scanf ("%d %d %d" , &u , &v , &w);
        // cout << w << endl;
        int ra = find (u) , rb = find (v);
        if (ra == rb) r[ra] += w;
        else {
            // cout << ra << " " << rb << " " << r[ra] << " " << r[rb] << endl;
            pre[ra] = rb;
            r[rb] += r[ra];
            r[rb] += w;

        }
    }
    for (int i = 1 ; i <= n ; i ++) {
        if (pre[i] == i) {
            root.push (Node (i , r[i]));
            // cout << i << " " << r[i] << endl;
        }
    }
    if (root.size() < q) {
        puts ("NO");
        return 0;
    }
    for (int i = 0 ; i < p ; i ++) {
        if (root.size() > q) {
            Node a = root.top ();root.pop ();
            Node b = root.top ();root.pop ();
            ans.push_back (make_pair (a.r , b.r));
            a.v += min (a.v + b.v + 1 , 1000000000LL);
            a.v += b.v;
            u = a.r;v = b.r;
            root.push (a);
        }
        else {
            if (u != -1)   ans.push_back (make_pair (u , v));
        }
    }
    if (root.size() > q || ans.size() != p) puts ("NO");
    else {
        puts ("YES");
        for (int i = 0 ; i < ans.size() ; i ++)
            printf ("%d %d\n" , ans[i].first  , ans[i].second);
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
int  N,M,P,Q;
struct node
{
    long long cost;
    int id;
    node(){}
    node(int a,long long b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
int p[maxn];
long long val[maxn];
int find(int x)
{
    return x==p[x]? x:p[x]=find(p[x]);
}

int A,B;
int main()
{
   // freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    for(i=1;i<=N;i++)
    {
        p[i]=i;
    }
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        A=a,B=b;
        a=find(a);
        b=find(b);
        val[a]+=c;
        if(a!=b)
        {
            val[a]+=val[b];
            p[b]=a;
        }
    }
    for(i=1;i<=N;i++)
    {
        if(p[i]==i)
        {
            q.push(node(i,val[i]));
        }
    }

    int num=q.size()-Q;
    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0&&P)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();

            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            q.push(node(t1.id,t2.cost+min((long long)1000000000,t1.cost+t2.cost+1)));
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
struct Edge
{
    int from,to,cost,next;
    Edge(){}
    Edge(int from_,int to_,int cost_,int next_)
    {
        from=from_,to=to_,cost=cost_,next=next_;
    }
}edges[maxn*2];
int cnt;
int head[maxn];
int vis[maxn];
void addedge(int x,int y,int c)
{
    edges[cnt]=Edge(x,y,c,head[x]);
    head[x]=cnt++;
}
int  N,M,P,Q;
struct node
{
    int cost;
    int id;
    node(){}
    node(int a,int b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
struct ANS
{
    int a,b;
    ANS(){}
    ANS(int x,int y)
    {
        a=x,b=y;
    }
};
vector<int> ans;

void dfs(int cur,int& sum)
{
    int i,j;
    vis[cur]=1;
    for(i=head[cur];i!=-1;i=edges[i].next)
    {
        int v=edges[i].to;
        if(vis[v]) continue;
        sum+=edges[i].cost;
        dfs(v,sum);
    }
}
int A,B;
int main()
{
    //freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    cnt=0;
    memset(head,-1,sizeof(head));
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
        A=a,B=b;
    }
    for(i=1;i<=N;i++)
    {
        if(!vis[i])
        {
            int temp=0;
            dfs(i,temp);
            q.push(node(i,temp));
        }
    }
    int num=q.size()-Q;

    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0&&P)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();
            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            q.push(node(t1.id,t1.cost+t2.cost));
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
struct Edge
{
    int from,to,cost,next;
    Edge(){}
    Edge(int from_,int to_,int cost_,int next_)
    {
        from=from_,to=to_,cost=cost_,next=next_;
    }
}edges[maxn*2];
int cnt;
int head[maxn];
int vis[maxn];
void addedge(int x,int y,int c)
{
    edges[cnt]=Edge(x,y,c,head[x]);
    head[x]=cnt++;
}
int  N,M,P,Q;
struct node
{
    int cost;
    int id;
    node(){}
    node(int a,int b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
struct ANS
{
    int a,b;
    ANS(){}
    ANS(int x,int y)
    {
        a=x,b=y;
    }
};
vector<int> ans;

void dfs(int cur,int& sum)
{
    int i,j;
    vis[cur]=1;
    for(i=head[cur];i!=-1;i=edges[i].next)
    {
        int v=edges[i].to;
        if(vis[v]) continue;
        sum+=edges[i].cost;
        dfs(v,sum);
    }
}
int A,B;
int main()
{
   // freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    cnt=0;
    memset(head,-1,sizeof(head));
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
        A=a,B=b;
    }
    for(i=1;i<=N;i++)
    {
        if(!vis[i])
        {
            int temp=0;
            dfs(i,temp);
            q.push(node(i,temp));
        }
    }
    int num=q.size()-Q;

    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0&&P)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();
            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            q.push(node(t1.id,min(1000000000,t1.cost+t2.cost)));
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <cstdio>
#define maxn 100010
#define inf 10000000
using namespace std;
struct Edge
{
    int from,to,cost,next;
    Edge(){}
    Edge(int from_,int to_,int cost_,int next_)
    {
        from=from_,to=to_,cost=cost_,next=next_;
    }
}edges[maxn*2];
int cnt;
int head[maxn];
int vis[maxn];
void addedge(int x,int y,int c)
{
    edges[cnt]=Edge(x,y,c,head[x]);
    head[x]=cnt++;
}
int  N,M,P,Q;
struct node
{
    int cost;
    int id;
    node(){}
    node(int a,int b)
    {
        id=a,cost=b;
    }
    bool operator<(const node& rhs)const
    {
        return cost>rhs.cost;
    }
};
priority_queue<node> q;
struct ANS
{
    int a,b;
    ANS(){}
    ANS(int x,int y)
    {
        a=x,b=y;
    }
};
vector<int> ans;

void dfs(int cur,int& sum)
{
    int i,j;
    vis[cur]=1;
    for(i=head[cur];i!=-1;i=edges[i].next)
    {
        int v=edges[i].to;
        if(vis[v]) continue;
        sum+=edges[i].cost;
        dfs(v,sum);
    }
}
int A,B;
int main()
{
  //  freopen("input.txt","r",stdin);
    int i,j;
    scanf("%d %d %d %d",&N,&M,&P,&Q);
    cnt=0;
    memset(head,-1,sizeof(head));
    for(i=0;i<M;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
        A=a,B=b;
    }
    for(i=1;i<=N;i++)
    {
        if(!vis[i])
        {
            int temp=0;
            dfs(i,temp);
            q.push(node(i,temp));
        }
    }
    int num=q.size()-Q;

    if(num<0||num>P)
    {
        puts("NO");
    }
    else
    {
        if(num==0&&M==0)
        {
            puts("NO");
            return 0;
        }

        puts("YES");
        int a,b;
        P-=num;
        a=b=-1;
        while(num)
        {
            node t1,t2;
            t1=q.top();
            q.pop();
            t2=q.top();
            q.pop();
            printf("%d %d\n",t1.id,t2.id);
            a=t1.id,b=t2.id;
            num--;
        }

        if(a==-1)
        {
            a=A,b=B;
        }
        while(P)
        {
            printf("%d %d\n",a,b);
            P--;
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#define inf 1000000007

using namespace std;

int cc;
vector <pair<int,int> > adj[111111];
int vis[111111], r[111111], o[1111111];
int len[111111];

void dfs(int u)
{
    vis[u] = 1;
    for(int i=0;i<adj[u].size();i++)
    {
        len[cc] = min(1000000000,len[cc]+adj[u][i].second);
        int v = adj[u][i].first;
        o[cc] = v;
        if(!vis[v]) dfs(v);
    }
}

int main()
{
    int n, m, p, q;
    cc = 0;
    cin >> n >> m >> p >> q;
    for(int i=0;i<m;i++)
    {
        int a, b, l;
        cin >> a >> b >> l;
        adj[a].push_back(make_pair(b,l));
        adj[b].push_back(make_pair(a,l));
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            dfs(i);
            r[cc] = i;
            len[cc++] /= 2;
        }
    }
    priority_queue <pair<int,int> >  pq;
    vector <pair<int,int> > v;
    for(int i=0;i<cc;i++) pq.push(make_pair(-len[i],i));
    while(q < pq.size())
    {
        if(p == 0) break;
        pair <int,int> x, y, z;
        x = pq.top(); pq.pop();
        y = pq.top(); pq.pop();
        r[cc] = r[x.second];
        o[cc] = r[y.second];
        z.first = max(-1000000000, x.first + y.first - 1);
        z.second = cc++;
        pq.push(z);
        v.push_back(make_pair(r[x.second],r[y.second]));
        p--;
    }
    if(pq.size() != q) cout << "NO" << endl;
    else
    {
        if(p)
        {
            pair <int,int> x;
            while(!pq.empty() && o[pq.top().second] == 0) pq.pop();
            if(!pq.empty())
            {
                x = pq.top(); pq.pop();
                while(p)
                {
                    v.push_back(make_pair(r[x.second],o[x.second]));
                    p--;
                }
            }
        }
        if(p) cout << "NO" << endl;
        else
        {
            cout << "YES" << endl;
            for(int i=0;i<v.size();i++) cout << v[i].first << " " << v[i].second << endl;
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#define inf 1000000007

using namespace std;

int cc;
vector <pair<int,int> > adj[111111];
int vis[111111], r[111111], o[1111111];
int len[111111];
long long cost = 0;

void dfs(int u)
{
    vis[u] = 1;
    for(int i=0;i<adj[u].size();i++)
    {
        len[cc] = min(1000000000,len[cc]+adj[u][i].second);
        int v = adj[u][i].first;
        if(!vis[v])
        {
            o[cc] = v;
            dfs(v);
        }
    }
}

int main()
{
    int n, m, p, q;
    cc = 0;
    cin >> n >> m >> p >> q;
    for(int i=0;i<m;i++)
    {
        int a, b, l;
        cin >> a >> b >> l;
        adj[a].push_back(make_pair(b,l));
        adj[b].push_back(make_pair(a,l));
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            dfs(i);
            r[cc] = i;
            len[cc++] /= 2;
        }
    }
    priority_queue <pair<long long,int> >  pq;
    vector <pair<int,int> > v;
    for(int i=0;i<cc;i++) pq.push(make_pair(-len[i],i));
    while(q < pq.size())
    {
        if(p == 0) break;
        pair <long long,int> x, y, z;
        x = pq.top(); pq.pop();
        y = pq.top(); pq.pop();
        r[cc] = r[x.second];
        o[cc] = r[y.second];
        if(1 - x.first - y.first > 1000000000) z.first = x.first + y.first - 1000000000;
        else z.first = 2*(x.first+y.first)-1;
        z.second = cc++;
        pq.push(z);
        v.push_back(make_pair(r[x.second],r[y.second]));
        p--;
    }
    if(pq.size() != q) cout << "NO" << endl;
    else
    {
        if(p)
        {
            pair <int,int> x;
            while(!pq.empty() && o[pq.top().second] == 0) pq.pop();
            if(!pq.empty())
            {
                x = pq.top(); pq.pop();
                while(p)
                {
                    v.push_back(make_pair(r[x.second],o[x.second]));
                    p--;
                }
            }
        }
        if(p) cout << "NO" << endl;
        else
        {
            cout << "YES" << endl;
            for(int i=0;i<v.size();i++) cout << v[i].first << " " << v[i].second << endl;
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#define inf 1000000007

using namespace std;

int cc;
vector <pair<int,int> > adj[111111];
int vis[111111], r[111111], o[1111111];
int len[111111];

void dfs(int u)
{
    vis[u] = 1;
    o[cc] = u;
    for(int i=0;i<adj[u].size();i++)
    {
        len[cc] = min(1000000000,len[cc]+adj[u][i].second);
        int v = adj[u][i].first;
        if(!vis[v]) dfs(v);
    }
}

int main()
{
    int n, m, p, q;
    cc = 0;
    cin >> n >> m >> p >> q;
    for(int i=0;i<m;i++)
    {
        int a, b, l;
        cin >> a >> b >> l;
        adj[a].push_back(make_pair(b,l));
        adj[b].push_back(make_pair(a,l));
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            dfs(i);
            r[cc] = i;
            len[cc++] /= 2;
        }
    }
    priority_queue <pair<int,int> >  pq;
    vector <pair<int,int> > v;
    for(int i=0;i<cc;i++) pq.push(make_pair(-len[i],i));
    while(q < pq.size())
    {
        if(p == 0) break;
        pair <int,int> x, y, z;
        x = pq.top(); pq.pop();
        y = pq.top(); pq.pop();
        r[cc] = r[x.second];
        o[cc] = r[y.second];
        z.first = max(-1000000000, x.first + y.first - 1);
        z.second = cc++;
        pq.push(z);
        v.push_back(make_pair(r[x.second],r[y.second]));
        p--;
    }
    if(pq.size() != q) cout << "NO" << endl;
    else
    {
        if(p)
        {
            pair <int,int> x;
            while(!pq.empty() && o[pq.top().second] == 0) pq.pop();
            if(!pq.empty())
            {
                x = pq.top(); pq.pop();
                while(p)
                {
                    v.push_back(make_pair(r[x.second],o[x.second]));
                    p--;
                }
            }
        }
        if(p) cout << "NO" << endl;
        else
        {
            cout << "YES" << endl;
            for(int i=0;i<v.size();i++) cout << v[i].first << " " << v[i].second << endl;
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

int cc;
vector <pair<int,int> > adj[111111];
int vis[111111], r[111111], o[1111111];
long long len[111111];
long long cost = 0;

void dfs(int u)
{
    vis[u] = 1;
    for(int i=0;i<adj[u].size();i++)
    {
        len[cc] += adj[u][i].second;
        int v = adj[u][i].first;
        if(!vis[v])
        {
            o[cc] = v;
            dfs(v);
        }
    }
}

int main()
{
    int n, m, p, q;
    cc = 0;
    cin >> n >> m >> p >> q;
    for(int i=0;i<m;i++)
    {
        int a, b, l;
        cin >> a >> b >> l;
        adj[a].push_back(make_pair(b,l));
        adj[b].push_back(make_pair(a,l));
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            dfs(i);
            r[cc] = i;
            len[cc++] /= 2;
        }
    }
    priority_queue <pair<long long,int> >  pq;
    vector <pair<int,int> > v;
    for(int i=0;i<cc;i++) pq.push(make_pair(-len[i],i));
    while(q < pq.size())
    {
        if(p == 0) break;
        pair <long long,int> x, y, z;
        x = pq.top(); pq.pop();
        y = pq.top(); pq.pop();
        r[cc] = r[x.second];
        o[cc] = r[y.second];
        if(1 - x.first - y.first > 1000000000)
        {
            z.first = x.first + y.first - 1000000000;
            cost += 1000000000;
        }
        else
        {
            z.first = 2*(x.first+y.first)-1;
            cost -= (x.first+y.first-1);
        }
        z.second = cc++;
        pq.push(z);
        v.push_back(make_pair(r[x.second],r[y.second]));
        p--;
    }
    if(pq.size() != q) cout << "NO" << endl;
    else
    {
        if(p)
        {
            pair <int,int> x;
            while(!pq.empty() && o[pq.top().second] == 0) pq.pop();
            if(!pq.empty())
            {
                x = pq.top(); pq.pop();
                while(p)
                {
                    v.push_back(make_pair(r[x.second],o[x.second]));
                    p--;
                }
            }
        }
        if(p) cout << "NO" << endl;
        else
        {
            cout << "YES" << endl;
            for(int i=0;i<v.size();i++) cout << v[i].first << " " << v[i].second << endl;
        }
    }
    return 0;
}