#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <functional>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <iostream>
#include <ctime>
#include <complex>

#define enp 	printf("**Entry Point**\n")
#define A		first
#define B		second
#define MP		make_pair

using namespace std;

typedef long long ll;

const int INF = 0x6fffffff;
const int MINF = 0x80000000;
const ll mod = 100003;
const int cons = 100001;
const double pi = 3.141592653589793;

int parent[200002];
int deg[200002];
int f[200002];
int cnt[200002];

int fn(int u)
{
	if (f[u] == u)return u;
	return f[u] = fn(f[u]);
}

void unite(int u, int v)
{
	cnt[fn(u)] += cnt[fn(v)];
	f[fn(v)] = fn(u);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

	int n, m;
	scanf("%d%d", &n, &m);

	vector < pair <int, int> > es;
	for (int i = 0; i < m; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);

		es.push_back(MP(u, v));
	}

	int s, t, ds, dt;
	scanf("%d%d%d%d", &s, &t, &ds, &dt);

	for (int i = 1; i <= n; i++)
	{
		f[i] = i;
		cnt[i] = 1;
	}

	vector <pair <int, int> > ans;

	for (auto e : es)
	{
		if (e.A == s || e.A == t || e.B == s || e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		deg[e.A]++;
		deg[e.B]++;
		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (e.A != s && e.A != t && e.B != s && e.B != t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		bool is = false;
		bool it = false;
		if (e.A == s || e.B == s)
		{
			if (deg[s] + 1 > ds)continue;
			is = true;
		}

		if (e.A == t || e.B == t)
		{
			if (deg[t] + 1 > dt)continue;
			it = true;
		}

		if (is && it)continue;

		deg[e.A]++;
		deg[e.B]++;

		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		bool is = false;
		bool it = false;
		if (e.A == s || e.B == s)
		{
			if (deg[s] + 1 > ds)continue;
			is = true;
		}

		if (e.A == t || e.B == t)
		{
			if (deg[t] + 1 > dt)continue;
			it = true;
		}
		if (!(is && it))continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		deg[e.A]++;
		deg[e.B]++;

		ans.push_back(e);
		unite(u, v);
		break;
	}

	if (cnt[fn(1)] != n)puts("No");
	else
	{
		puts("Yes");
		for (auto e : ans)
		{
			printf("%d %d\n", e.A, e.B);
		}
	}

	return 0;
}


#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <functional>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <iostream>
#include <ctime>
#include <complex>

#define enp 	printf("**Entry Point**\n")
#define A		first
#define B		second
#define MP		make_pair

using namespace std;

typedef long long ll;

const int INF = 0x6fffffff;
const int MINF = 0x80000000;
const ll mod = 100003;
const int cons = 100001;
const double pi = 3.141592653589793;

int parent[200002];
int deg[200002];
int f[200002];
int cnt[200002];
vector < vector <int> > adj;

int fn(int u)
{
	if (f[u] == u)return u;
	return f[u] = fn(f[u]);
}

void unite(int u, int v)
{
	cnt[fn(u)] += cnt[fn(v)];
	f[fn(v)] = fn(u);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

	int n, m;
	scanf("%d%d", &n, &m);
	adj.resize(n + 1);

	vector < pair <int, int> > es;
	for (int i = 0; i < m; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		adj[u].push_back(v);
		adj[v].push_back(u);

		if (u > v)swap(u, v);
		es.push_back(MP(u, v));
	}

	int s, t, ds, dt;
	scanf("%d%d%d%d", &s, &t, &ds, &dt);

	if (s > t)swap(s, t), swap(ds, dt);

	for (int i = 1; i <= n; i++)
	{
		f[i] = i;
		cnt[i] = 1;
	}

	vector <pair <int, int> > ans;

	for (auto e : es)
	{
		if (e.A == s || e.A == t || e.B == s || e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		deg[e.A]++;
		deg[e.B]++;
		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (e.A != s && e.A != t && e.B != s && e.B != t)continue;
		if (e.A == s && e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		if (e.A == s || e.B == s)
		{
			if (deg[s] + 1 > ds)continue;
			if (e.A == s)
			{
				if (adj[e.B].size() > 1)continue;
			}
			else
			{
				if (adj[e.A].size() > 1)continue;
			}
		}
		else if (e.A == t || e.B == t)
		{
			if (deg[t] + 1 > dt)continue;
			if (e.A == t)
			{
				if (adj[e.B].size() > 1)continue;
			}
			else
			{
				if (adj[e.A].size() > 1)continue;
			}
		}

		deg[e.A]++;
		deg[e.B]++;
		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (e.A != s && e.A != t && e.B != s && e.B != t)continue;
		if (e.A == s && e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		if (e.A == s || e.B == s)
		{
			if (deg[s] + 1 > ds)continue;
		}
		else if (e.A == t || e.B == t)
		{
			if (deg[t] + 1 > dt)continue;
		}

		deg[e.A]++;
		deg[e.B]++;

		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (!(e.A == s && e.B == t))continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		deg[e.A]++;
		deg[e.B]++;

		ans.push_back(e);
		unite(u, v);
		break;
	}

	if (cnt[fn(1)] != n)puts("No");
	else
	{
		puts("Yes");
		for (auto e : ans)
		{
			printf("%d %d\n", e.A, e.B);
		}
	}

	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <functional>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <iostream>
#include <sstream>
#include <complex>
#include <cassert>

#define enp     puts("**chkchkchkchkchk**")
#define A       first
#define B       second
#define MP      make_pair

using namespace std;

typedef long long ll;
typedef unsigned int uint;

const int INF = 0x60000000;
const int MINF = -1000000000;
const int mod = 99999997;
const ll cons = 100000;
const double pi = 3.141592653589793;

vector < vector <int> > adj;
bool chk[200002];
int parent[200002];
int deg[200002];
int f[200002];

int fn(int u)
{
	if (f[u] == u)return u;
	return f[u] = fn(f[u]);
}

void unite(int u, int v)
{
	f[fn(u)] = fn(v);
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	adj.resize(n + 1);

	bool isAdj = false;

	vector < pair <int, int> > dat;

	for (int i = 1; i <= n; i++)
	{
		f[i] = i;
	}

	for (int i = 0; i < m; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		adj[u].push_back(v);
		adj[v].push_back(u);

		dat.push_back(MP(u, v));
	}

	int s, t, ds, dt;
	scanf("%d%d%d%d", &s, &t, &ds, &dt);

	for (int i = 0; i < dat.size(); i++)
	{
		int u = dat[i].A;
		int v = dat[i].B;

		if ((u == s && v == t) || (u == t && v == s))
		{
			isAdj = true;
			break;
		}
	}

	int tmp = ds + dt - 1;

	if (isAdj)
	{
		if (adj[t].size() == 1)
		{
			deg[s]++;
			deg[t]++;
			parent[t] = s;
			tmp--;
		}
	}

	queue <int> qu;
	qu.push(s);
	chk[s] = true;
	chk[t] = true;

	while (!qu.empty())
	{
		int u = qu.front();
		qu.pop();

		for (auto v : adj[u])
		{
			if (chk[v])continue;
			if (u == s && tmp == 0)continue;
			if (u == s)tmp--;

			unite(u, v);

			deg[u]++;
			deg[v]++;

			parent[v] = u;
			chk[v] = true;
			qu.push(v);
		}
	}

	if (parent[t] == 0)
	{
		for(auto v : adj[t])
		{
			if (v == s)continue;
			if (fn(s) != fn(v))continue;
			deg[v]++;
			deg[t]++;
			parent[t] = v;
			break;
		}
	}

	if (parent[t] == 0)
	{
		puts("No");
		return 0;
	}

	tmp = deg[s] - ds;

	for (auto v : adj[t])
	{
		if (parent[v] != s)continue;
		if (tmp <= 0)break;

		deg[s]--;
		deg[t]++;
		parent[v] = t;
		tmp--;
	}

	vector <int> S;
	if (tmp > 0)
	{
		for (auto v : adj[s])
		{
			if (parent[v] != s)continue;
			if (v == t)continue;
			if (adj[v].size() == 1)continue;

			deg[s]--;
			deg[v]--;
			parent[v] = 0;
			S.push_back(v);
			tmp--;
			if (tmp == 0)break;
		}
	}

	if (tmp > 0)
	{
		puts("No");
		return 0;
	}

	for (auto u : S)
	{
		for (auto v : adj[u])
		{
			if (v == s)continue;
			parent[u] = v;
			deg[u]++;
			deg[v]++;
			break;
		}
	}

	tmp = dt - deg[t];

	for (auto u : adj[t])
	{
		if (parent[u] == t)continue;
		if (parent[t] == u)continue;

		deg[parent[u]]--;
		parent[u] = t;

		deg[t]++;
		tmp--;

		if (tmp == 0)break;
	}

	puts("Yes");

	for (int i = 1; i <= n; i++)
	{
		if (i == s)continue;
		printf("%d %d\n", i, parent[i]);
	}

	return 0;
}


#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <functional>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <iostream>
#include <ctime>
#include <complex>

#define enp 	printf("**Entry Point**\n")
#define A		first
#define B		second
#define MP		make_pair

using namespace std;

typedef long long ll;

const int INF = 0x6fffffff;
const int MINF = 0x80000000;
const ll mod = 100003;
const int cons = 100001;
const double pi = 3.141592653589793;

int parent[200002];
int deg[200002];
int f[200002];
int cnt[200002];
vector < vector <int> > adj;

int fn(int u)
{
	if (f[u] == u)return u;
	return f[u] = fn(f[u]);
}

void unite(int u, int v)
{
	cnt[fn(u)] += cnt[fn(v)];
	f[fn(v)] = fn(u);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

	int n, m;
	scanf("%d%d", &n, &m);
	adj.resize(n + 1);

	vector < pair <int, int> > es;
	for (int i = 0; i < m; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		adj[u].push_back(v);
		adj[v].push_back(u);

		if (u > v)swap(u, v);
		es.push_back(MP(u, v));
	}

	int s, t, ds, dt;
	scanf("%d%d%d%d", &s, &t, &ds, &dt);

	if (s > t)swap(s, t), swap(ds, dt);

	for (int i = 1; i <= n; i++)
	{
		f[i] = i;
		cnt[i] = 1;
	}

	vector <pair <int, int> > ans;

	for (auto e : es)
	{
		if (e.A == s || e.A == t || e.B == s || e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		deg[e.A]++;
		deg[e.B]++;
		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (e.A != s && e.A != t && e.B != s && e.B != t)continue;
		if (e.A == s && e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		if (e.A == s || e.B == s)
		{
			if (deg[s] + 1 > ds)continue;
			if (e.A == s)
			{
				if (adj[e.B].size() > 1)continue;
			}
			else
			{
				if (adj[e.A].size() > 1)continue;
			}
		}
		else if (e.A == t || e.B == t)
		{
			if (deg[t] + 1 > dt)continue;
			if (e.A == t)
			{
				if (adj[e.B].size() > 1)continue;
			}
			else
			{
				if (adj[e.A].size() > 1)continue;
			}
		}

		deg[e.A]++;
		deg[e.B]++;
		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (e.A != s && e.A != t && e.B != s && e.B != t)continue;
		if (e.A == s && e.B == t)continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		if (e.A == s || e.B == s)
		{
			if (deg[s] + 1 > ds)continue;
		}
		else if (e.A == t || e.B == t)
		{
			if (deg[t] + 1 > dt)continue;
		}

		deg[e.A]++;
		deg[e.B]++;

		ans.push_back(e);
		unite(u, v);
	}

	for (auto e : es)
	{
		if (!(e.A == s && e.B == t))continue;

		int u = fn(e.A);
		int v = fn(e.B);
		if (u == v)continue;

		if (deg[s] + 1 > ds || deg[t] + 1 > dt)continue;

		deg[e.A]++;
		deg[e.B]++;

		ans.push_back(e);
		unite(u, v);
		break;
	}

	if (cnt[fn(1)] != n)puts("No");
	else
	{
		puts("Yes");
		for (auto e : ans)
		{
			printf("%d %d\n", e.A, e.B);
		}
	}

	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t, int tot)
{
	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
			continue;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
			tot--;
		}
	}
	if (tot == 0) return;
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	uf.init();
	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(s, t, ds);
	check(t, s, dt);
	if (uf.treesize(1) != n) cout << "No" << endl;
	else
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t)
{
	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
		}
	}
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	uf.init();
	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(s, t);
	check(t, s);
	if (uf.treesize(1) == n) cout << "No" << endl;
	else
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t, int &tot1, int &tot2)
{
	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
			continue;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			if (tot1 == 0) break;
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
			tot1--;
		}
	}
	if (tot1 == 0 || tot2 == 0) return;
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
		ans.push_back({ s,t });
		tot1--;
		tot2--;
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	uf.init();
	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(t, s, dt, ds);
	check(s, t, ds, dt);
	if (uf.treesize(1) != n) cout << "No" << endl;
	else
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t, int &tot1, int &tot2)
{
	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
			continue;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			if (tot1 == 0) break;
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
			tot1--;
		}
	}
	if (tot1 == 0 || tot2 == 0) return;
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
		ans.push_back({ s,t });
		tot1--;
		tot2--;
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	uf.init();
	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(s, t, ds, dt);
	check(t, s, dt, ds);
	if (uf.treesize(1) != n) cout << "No" << endl;
	else
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t, int tot)
{
	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
			continue;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
			tot--;
			if (tot == 0) break;
		}
	}
	if (tot == 0) return;
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
		ans.push_back({ s,t });
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	uf.init();
	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(s, t, ds);
	check(t, s, dt);
	if (uf.treesize(1) != n) cout << "No" << endl;
	else
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
int n, m;
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t, int &tot1, int &tot2)
{

	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
			continue;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			if (tot1 == 0) break;
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
			tot1--;
		}
	}
	if (tot1 == 0 || tot2 == 0) return;
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
		ans.push_back({ s,t });
		tot1--;
		tot2--;
	}
}
bool solve(int s, int t, int ds, int dt)
{
	uf.init();
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(t, s, dt, ds);
	check(s, t, ds, dt);
	return uf.treesize(1) == n;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}

	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}

	if (solve(s,t,ds,dt) || solve(t,s,dt,ds))
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	else
	{
		cout << "No" << endl;
	}
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e5 + 10;
vector<int> v[N];
int low[N], dfn[N], cnt;
int son[N];
void tarjan(int x, int p = -1)
{
	son[x] = 0;
	low[x] = dfn[x] = cnt++;
	if (p != -1) son[x] ++;
	for (auto &y : v[x])
	{
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else
		{
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if (dfn[x] <= low[y])
			{
				son[x]++;
			}
		}
	}
}
class UnionSet
{
public:
	int fa[N];
	void init()
	{
		MEM(fa, -1);
	}
	int treesize(int x)
	{
		return -fa[Find(x)];
	}
	int Find(int x)
	{
		int root = x;
		while (fa[root] >= 0) root = fa[root];
		while (x != root)
		{
			int tmp = fa[x];
			fa[x] = root;
			x = tmp;
		}
		return root;
	}
	void Union(int x, int y)
	{
		int px = Find(x);
		int py = Find(y);
		if (fa[px] > fa[py]) swap(px, py);
		int sz = fa[px] + fa[py];
		fa[py] = px;
		fa[px] = sz;
	}
} uf;
vector<pair<int, int>> ans;
void check(int s, int t, int tot)
{
	int flag = 0;
	int key = 0;
	for (auto x : v[s])
	{
		if (x == t)
		{
			key = 1;
			continue;
		}
		if (uf.Find(x) != uf.Find(s))
		{
			uf.Union(x, s);
			ans.push_back({ x,s });
			flag = 1;
			tot--;
			if (tot == 0) break;
		}
	}
	if (tot == 0) return;
	if (uf.Find(s) == uf.Find(t)) return;
	if (key == 1)
	{
		uf.Union(s, t);
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(son, 0);
	cnt = 1;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	uf.init();
	int s, t, ds, dt;
	cin >> s >> t >> ds >> dt;
	if (son[s] > ds || son[t] > dt)
	{
		cout << "No" << endl;
		return 0;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i == t || i == s) continue;
		for (auto &j : v[i])
		{
			if (j == t || j == s) continue;
			if (uf.Find(i) != uf.Find(j))
			{
				uf.Union(i, j);
				ans.push_back({ i,j });
			}
		}
	}
	check(s, t, ds);
	check(t, s, dt);
	if (uf.treesize(1) != n) cout << "No" << endl;
	else
	{
		cout << "Yes" << endl;
		for (auto &p : ans)
		{
			cout << p.first << ' ' << p.second << '\n';
		}
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;

const int N = 2e5 + 100;
vector<int> v[N];
int col[N], d[N], b[N];
bool used[N];
int s, t, dt, ds, z = 0;

void dfs(int node, int c) {
	col[node] = c;
	for (int to : v[node]) {
		if (to == t || to == s) {
			if (d[c] == 0) {
				d[c] = 1;
				b[c] = to;
			}
			else if (b[c] != to) {
				b[c] = to;
				d[c] = 2;
			}
		}
		else if (!col[to])
			dfs(to, c);
	}
}

void walk(int node) {
	used[node] = 1;
	for (int to : v[node]) {
		if (!used[to]) {
			printf("%d %d\n", node + 1, to + 1);
			walk(to);
		}
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m;
	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	s--, t--;

	for (int i = 0; i < n; i++) {
		if (!col[i] && i != s && i != t) {
			z++;
			dfs(i, z);
		}
	}

	int com = 0;
	for (int to : v[s]) {
		if (d[col[to]] == 1)
			ds--;
		else if (d[col[to]] == 2)
			com++;
	}
	for (int to : v[t]) {
		if (d[col[to]] == 1)
			dt--;
	}

	if (ds < 1 || dt < 1 || ds + dt - 1 < com) {
		printf("No");
		return 0;
	}

	printf("Yes\n");
	used[s] = used[t] = 1;

	int br = -1;
	for (int to : v[s]) {
		if (d[col[to]] == 2) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
			br = col[to];
			ds--;
			break;
		}
	}

	if (br == -1)
		printf("%d %d\n", s + 1, t + 1);
	else {
		for (int to : v[t]) {
			if (col[to] == br) {
				dt--;
				printf("%d %d\n", t + 1, to + 1);
				break;
			}
		}
	}

	for (int to : v[s]) {
		if (!used[to] && (ds > 0 || d[col[to]] == 1)) {
			if (d[col[to]] == 2)
				ds--;
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
	}

	for (int to : v[t]) {
		if (!used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
	}

	return 0;
}


#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;

const int N = 2e5 + 100;
vector<int> v[N];
int col[N], d[N], b[N];
bool used[N];
int s, t, dt, ds, z = 0;

void dfs(int node, int c) {
	col[node] = c;
	for (int to : v[node]) {
		if (to == t || to == s) {
			if (d[c] == 0) {
				d[c] = 1;
				b[c] = to;
			}
			else if (b[c] != to)
				d[c] = 2;
		}
		else if (!col[to])
			dfs(to, c);
	}
}

void walk(int node) {
	used[node] = 1;
	for (int to : v[node]) {
		if (!used[to]) {
			printf("%d %d\n", node + 1, to + 1);
			walk(to);
		}
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m;
	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	s--, t--;

	for (int i = 0; i < n; i++) {
		if (!col[i] && i != s && i != t) {
			z++;
			dfs(i, z);
		}
	}

	int com = 0;
	for (int to : v[s]) {
		if (d[col[to]] == 1)
			ds--;
		else if (d[col[to]] == 2)
			com++;
	}
	for (int to : v[t]) {
		if (d[col[to]] == 1)
			dt--;
	}

	ds--;
	dt--;
	if (com)
		com--;

	if (ds < 0 || dt < 0 || ds + dt < com) {
		printf("No");
		return 0;
	}

	printf("Yes\n");
	used[s] = used[t] = 1;

	int br = -1;
	for (int to : v[s]) {
		if (d[col[to]] == 2) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
			br = col[to];
			ds--;
			break;
		}
	}

	if (br == -1)
		printf("%d %d\n", s + 1, t + 1);
	else {
		for (int to : v[t]) {
			if (col[to] == br) {
				dt--;
				printf("%d %d\n", t + 1, to + 1);
				break;
			}
		}
	}

	for (int to : v[s]) {
		if (!used[to] && (ds > 0 || d[col[to]] == 1)) {
			if (d[col[to]] == 2)
				ds--;
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
	}

	for (int to : v[t]) {
		if (!used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
	}

	return 0;
}


#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;

const int N = 2e5 + 100;
vector<int> v[N];
int col[N], d[N], b[N];
bool used[N];
int s, t, dt, ds, z = 0;

void dfs(int node, int c) {
	col[node] = c;
	for (int to : v[node]) {
		if (to == t || to == s) {
			if (d[c] == 0) {
				d[c] = 1;
				b[c] = to;
			}
			else if (b[c] != to) {
				b[c] = to;
				d[c] = 2;
			}
		}
		else if (!col[to])
			dfs(to, c);
	}
}

void walk(int node) {
	used[node] = 1;
	for (int to : v[node]) {
		if (!used[to]) {
			printf("%d %d\n", node + 1, to + 1);
			walk(to);
		}
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m;
	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	s--, t--;

	for (int i = 0; i < n; i++) {
		if (!col[i] && i != s && i != t) {
			z++;
			dfs(i, z);
		}
	}

	int com = 0;
	for (int to : v[s]) {
		if (d[col[to]] == 1)
			ds--;
		else if (d[col[to]] == 2)
			com++;
	}
	for (int to : v[t]) {
		if (d[col[to]] == 1)
			dt--;
	}

	if (ds <= 0 || dt <= 0 || ds + dt - 1 < com) {
		printf("No");
		return 0;
	}

	printf("Yes\n");
	used[s] = used[t] = 1;

	int br = -1;
	for (int to : v[s]) {
		if (d[col[to]] == 2) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
			br = col[to];
			ds--;
			break;
		}
	}

	if (br == -1)
		printf("%d %d\n", s + 1, t + 1);

	for (int to : v[s]) {
		if (d[col[to]] == 1 && !used[to]) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
		else if (!used[to] && ds > 0) {
			ds--;
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
	}

	for (int to : v[t]) {
		if (d[col[to]] == 1 && !used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
		else if (!used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
		else if (col[to] == br) {
			dt--;
			printf("%d %d\n", t + 1, to + 1);
		}
	}

	return 0;
}


#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;

const int N = 2e5 + 100;
vector<int> v[N];
int col[N], d[N], b[N];
bool used[N];
int s, t, dt, ds, z = 0;

void dfs(int node, int c) {
	col[node] = c;
	for (int to : v[node]) {
		if (to == t || to == s) {
			if (d[c] == 0) {
				d[c] = 1;
				b[c] = to;
			}
			else if (b[c] != to)
				d[c] = 2;
		}
		else if (!col[to])
			dfs(to, c);
	}
}

void walk(int node) {
	used[node] = 1;
	for (int to : v[node]) {
		if (!used[to]) {
			printf("%d %d\n", node + 1, to + 1);
			walk(to);
		}
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m;
	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	s--, t--;

	for (int i = 0; i < n; i++) {
		if (!col[i] && i != s && i != t) {
			z++;
			dfs(i, z);
		}
	}

	int com = 0;
	for (int i = 1; i <= z; i++) {
		if (d[i] == 2)
			com++;
		else if (b[i] == s)
			ds--;
		else
			dt--;
	}

	ds--;
	dt--;
	if (com)
		com--;

	if (ds < 0 || dt < 0 || ds + dt < com) {
		printf("No");
		return 0;
	}

	printf("Yes\n");
	used[s] = used[t] = 1;

	int br = -1;
	for (int to : v[s]) {
		if (d[col[to]] == 2) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
			br = col[to];
			break;
		}
	}

	if (br == -1)
		printf("%d %d\n", s + 1, t + 1);
	else {
		for (int to : v[t]) {
			if (col[to] == br) {
				printf("%d %d\n", t + 1, to + 1);
				break;
			}
		}
	}

	for (int to : v[s]) {
		if (!used[to] && (ds > 0 || d[col[to]] == 1)) {
			if (d[col[to]] == 2)
				ds--;
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
	}

	for (int to : v[t]) {
		if (!used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
	}

	return 0;
}


#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;

const int N = 2e5 + 100;
vector<int> v[N];
int col[N], d[N], b[N];
bool used[N];
int s, t, dt, ds, z = 0;

void dfs(int node, int c) {
	col[node] = c;
	for (int to : v[node]) {
		if (to == t || to == s) {
			if (d[c] == 0) {
				d[c] = 1;
				b[c] = to;
			}
			else if (b[c] != to)
				d[c] = 2;
		}
		else if (!col[to])
			dfs(to, c);
	}
}

void walk(int node) {
	used[node] = 1;
	for (int to : v[node]) {
		if (!used[to]) {
			printf("%d %d\n", node + 1, to + 1);
			walk(to);
		}
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m;
	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	s--, t--;

	for (int i = 0; i < n; i++) {
		if (!col[i] && i != s && i != t) {
			z++;
			dfs(i, z);
		}
	}

	int com = 0;
	for (int to : v[s]) {
		if (d[col[to]] == 1)
			ds--;
		else if (d[col[to]] == 2)
			com++;
	}
	for (int to : v[t]) {
		if (d[col[to]] == 1)
			dt--;
	}

	ds--;
	dt--;
	if (com)
		com--;
	if (ds < 0 || dt < 0 || ds + dt < com) {
		printf("No");
		return 0;
	}

	printf("Yes\n");
	used[s] = used[t] = 1;

	int br = -1;
	for (int to : v[s]) {
		if (d[col[to]] == 2) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
			br = col[to];
			break;
		}
	}

	if (br == -1)
		printf("%d %d\n", s + 1, t + 1);
	else {
		for (int to : v[t]) {
			if (col[to] == br) {
				printf("%d %d\n", t + 1, to + 1);
				break;
			}
		}
	}

	for (int to : v[s]) {
		if (!used[to] && (ds > 0 || d[col[to]] == 1)) {
			if (d[col[to]] == 2)
				ds--;
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
	}

	for (int to : v[t]) {
		if (!used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
	}

	return 0;
}


#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<stack>
#include<bitset>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;

const int N = 2e5 + 100;
vector<int> v[N];
int col[N], d[N], b[N];
bool used[N];
int s, t, dt, ds, z = 0;

void dfs(int node, int c) {
	col[node] = c;
	for (int to : v[node]) {
		if (to == t || to == s) {
			if (d[c] == 0) {
				d[c] = 1;
				b[c] = to;
			}
			else if (b[c] != to) {
				b[c] = to;
				d[c] = 2;
			}
		}
		else if (!col[to])
			dfs(to, c);
	}
}

void walk(int node) {
	used[node] = 1;
	for (int to : v[node]) {
		if (!used[to]) {
			printf("%d %d\n", node + 1, to + 1);
			walk(to);
		}
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m;
	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	s--, t--;

	for (int i = 0; i < n; i++) {
		if (!col[i] && i != s && i != t) {
			z++;
			dfs(i, z);
		}
	}

	int com = 0;
	for (int to : v[s]) {
		if (d[col[to]] == 1)
			ds--;
		else if (d[col[to]] == 2)
			com++;
	}
	for (int to : v[t]) {
		if (d[col[to]] == 1)
			dt--;
	}

	if (ds < 1 || dt < 1 || ds + dt - 2 < com) {
		printf("No");
		return 0;
	}

	printf("Yes\n");
	used[s] = used[t] = 1;

	int br = -1;
	for (int to : v[s]) {
		if (d[col[to]] == 2) {
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
			br = col[to];
			ds--;
			break;
		}
	}

	if (br == -1)
		printf("%d %d\n", s + 1, t + 1);
	else {
		for (int to : v[t]) {
			if (col[to] == br) {
				dt--;
				printf("%d %d\n", t + 1, to + 1);
				break;
			}
		}
	}

	for (int to : v[s]) {
		if (!used[to] && (ds > 0 || d[col[to]] == 1)) {
			if (d[col[to]] == 2)
				ds--;
			printf("%d %d\n", s + 1, to + 1);
			walk(to);
		}
	}

	for (int to : v[t]) {
		if (!used[to]) {
			printf("%d %d\n", t + 1, to + 1);
			walk(to);
		}
	}

	return 0;
}


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

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FORD(i, b, a) for (int i = b; i >= a; --i)
#define FORE(i, v) for (__typeof (v.begin()) i = v.begin(); i != v.end(); ++i)
#define FORR(i, v) for (__typpeof (v.rbegin()) i = v.rbegin(); i != v.rend(); ++i)
#define sz(v) (int) v.size()
#define all(v) v.begin(), v.end()
#define uni(v) v.erase(unique(all(v)), v.end())
#define sqr(x) 1ll * (x) * (x)
#define EPS 1e-9

template <class T> int getBit(T x, int k) { return x >> k & 1; }
template <class T> T onBit(T x, int k) { return x  (T(1) << k); }
template <class T> T offBit(T x, int k) { return x & (~(T(1) << k)); }
template <class T> bool read(T &x) {
    x = 0; char c; bool nega = 0;
    while (!isdigit(c = getchar()) && c != '-' && c != EOF);
    if (c == EOF) return 0;
    if (c == '-') nega = 1, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (nega) x = -x;
    return 1;
}
template <class T> void wri(T x) { if (x / 10) wri(x / 10); putchar(x % 10 + '0'); }
template <class T> void write(T x) { if (x < 0) putchar('-'), x = -x; wri(x); }
template <class T> void writeln(T x) { write(x); putchar('\n'); }

const int maxn = 2e5 + 10;

int n, m, s, t, ds, dt, st;
int par[maxn], compS[maxn], compT[maxn];
bool mark[maxn << 1];
vector < pair <int, int> > edges;

void load() {
    read(n); read(m);
    REP(i, m) {
        int u, v; read(u); read(v);
        edges.push_back(make_pair(u, v));
    }
    read(s); read(t); read(ds); read(dt);
}

int anc(int p) { return par[p] == p ? p : par[p] = anc(par[p]); }
void join(int u, int v) { par[anc(u)] = anc(v); }

void process() {
    memset(compS, -1, sizeof compS);
    memset(compT, -1, sizeof compT);
    FOR(i, 1, n) par[i] = i;
    int ncomp = n; st = -1;
    REP(i, m) {
        int u = edges[i].first, v = edges[i].second;
        if ((u == s && v == t) || (u == t && v == s)) st = i;
        if (u == s | u == t || v == s || v == t) continue;
        if (anc(u) != anc(v)) {
            join(u, v);
            ncomp--;
            mark[i] = 1;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (minmax(s, t) == minmax(u, v)) continue;
        if (u == s || v == s) {
            if (u != s) swap(u, v);
            compS[anc(v)] = i;
        }
        if (u == t || v == t) {
            if (v != t) swap(u, v);
            compT[anc(u)] = i;
        }
    }
    int id = -1;
    FOR(i, 1, n) if (compS[i] != -1 && compT[i] != -1) {
        mark[compS[i]] = 1; mark[compT[i]] = 1;
        ds--; dt--; id = i; ncomp -= 2;
        break;
    }
    if (id == -1) {
        if (st == -1) {
            puts("No");
            return;
        }
        mark[st] = 1; ds--; dt--; ncomp--;
    }
    FOR(u, 1, n) if (compS[u] != -1 || compT[u] != -1) {
        if (compS[u] != -1 && compT[u] != -1) continue;
        if (compS[u] != -1) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    FOR(u, 1, n) if (compS[u] != -1 && compT[u] != -1 && u != id) {
        if (ds > dt) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    if (ncomp > 1 || ds < 0 || dt < 0) {
        puts("No");
        return;
    }
    puts("Yes");
    REP(i, m) if (mark[i])
        write(edges[i].first), putchar(' '), writeln(edges[i].second);
}

int main() {
   // freopen("input.in", "r", stdin);
 //   freopen("output.out", "w", stdout);

    load();
    process();

    return 0;
}


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

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FORD(i, b, a) for (int i = b; i >= a; --i)
#define FORE(i, v) for (__typeof (v.begin()) i = v.begin(); i != v.end(); ++i)
#define FORR(i, v) for (__typpeof (v.rbegin()) i = v.rbegin(); i != v.rend(); ++i)
#define sz(v) (int) v.size()
#define all(v) v.begin(), v.end()
#define uni(v) v.erase(unique(all(v)), v.end())
#define sqr(x) 1ll * (x) * (x)
#define EPS 1e-9

template <class T> int getBit(T x, int k) { return x >> k & 1; }
template <class T> T onBit(T x, int k) { return x  (T(1) << k); }
template <class T> T offBit(T x, int k) { return x & (~(T(1) << k)); }
template <class T> bool read(T &x) {
    x = 0; char c; bool nega = 0;
    while (!isdigit(c = getchar()) && c != '-' && c != EOF);
    if (c == EOF) return 0;
    if (c == '-') nega = 1, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (nega) x = -x;
    return 1;
}
template <class T> void wri(T x) { if (x / 10) wri(x / 10); putchar(x % 10 + '0'); }
template <class T> void write(T x) { if (x < 0) putchar('-'), x = -x; wri(x); }
template <class T> void writeln(T x) { write(x); putchar('\n'); }

const int maxn = 2e5 + 10;

int n, m, s, t, ds, dt, st;
int par[maxn], compS[maxn], compT[maxn];
bool mark[maxn << 1];
vector < pair <int, int> > edges;

void load() {
    read(n); read(m);
    REP(i, m) {
        int u, v; read(u); read(v);
        edges.push_back(make_pair(u, v));
    }
    read(s); read(t); read(ds); read(dt);
}

int anc(int p) { return par[p] == p ? p : par[p] = anc(par[p]); }
void join(int u, int v) { par[anc(u)] = anc(v); }

void process() {
    FOR(i, 1, n) par[i] = i;
    int ncomp = n; st = -1;
    REP(i, m) {
        int u = edges[i].first, v = edges[i].second;
        if ((u == s && v == t) || (u == t && v == s)) st = i;
        if (u == s | u == t || v == s || v == t) continue;
        if (anc(u) != anc(v)) {
            join(u, v);
            ncomp--;
            mark[i] = 1;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (u == s || v == s) {
            if (u != s) swap(u, v);
            compS[anc(v)] = i;
        }
        if (u == t || v == t) {
            if (v != t) swap(u, v);
            compT[anc(u)] = i;
        }
    }
    int id = -1;
    FOR(i, 1, n) if (compS[i] != 0 && compT[i] != 0) {
        mark[compS[i]] = 1; mark[compT[i]] = 1;
        ds--; dt--; id = i; ncomp -= 2;
        break;
    }
    if (id == -1) {
        if (st == -1) {
            puts("No");
            return;
        }
        mark[st] = 1; ds--; dt--; ncomp--;
    }
    FOR(u, 1, n) if ((!!compS[u]) ^ (!!compT[u])) {
        if (compS[u]) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    FOR(u, 1, n) if (compS[u] && compT[u] && u != id) {
        if (ds > dt) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    if (ncomp > 1 || ds < 0 || dt < 0) {
        puts("No");
        return;
    }
    puts("Yes");
    REP(i, m) if (mark[i])
        write(edges[i].first), putchar(' '), writeln(edges[i].second);
}

int main() {
 //   freopen("input.in", "r", stdin);
 //   freopen("output.out", "w", stdout);

    load();
    process();

    return 0;
}


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

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FORD(i, b, a) for (int i = b; i >= a; --i)
#define FORE(i, v) for (__typeof (v.begin()) i = v.begin(); i != v.end(); ++i)
#define FORR(i, v) for (__typpeof (v.rbegin()) i = v.rbegin(); i != v.rend(); ++i)
#define sz(v) (int) v.size()
#define all(v) v.begin(), v.end()
#define uni(v) v.erase(unique(all(v)), v.end())
#define sqr(x) 1ll * (x) * (x)
#define EPS 1e-9

template <class T> int getBit(T x, int k) { return x >> k & 1; }
template <class T> T onBit(T x, int k) { return x  (T(1) << k); }
template <class T> T offBit(T x, int k) { return x & (~(T(1) << k)); }
template <class T> bool read(T &x) {
    x = 0; char c; bool nega = 0;
    while (!isdigit(c = getchar()) && c != '-' && c != EOF);
    if (c == EOF) return 0;
    if (c == '-') nega = 1, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (nega) x = -x;
    return 1;
}
template <class T> void wri(T x) { if (x / 10) wri(x / 10); putchar(x % 10 + '0'); }
template <class T> void write(T x) { if (x < 0) putchar('-'), x = -x; wri(x); }
template <class T> void writeln(T x) { write(x); putchar('\n'); }

const int maxn = 2e5 + 10;

int n, m, s, t, ds, dt, st;
int par[maxn], compS[maxn], compT[maxn];
bool mark[maxn << 1];
vector < pair <int, int> > edges;

void load() {
    read(n); read(m);
    REP(i, m) {
        int u, v; read(u); read(v);
        edges.push_back(make_pair(u, v));
    }
    read(s); read(t); read(ds); read(dt);
}

int anc(int p) { return par[p] == p ? p : par[p] = anc(par[p]); }
void join(int u, int v) { par[anc(u)] = anc(v); }

void process() {
    FOR(i, 1, n) par[i] = i;
    int ncomp = n; st = -1;
    REP(i, m) {
        int u = edges[i].first, v = edges[i].second;
        if ((u == s && v == t) || (u == t && v == s)) st = i;
        if (u == s | u == t || v == s || v == t) continue;
        if (anc(u) != anc(v)) {
            join(u, v);
            ncomp--;
            mark[i] = 1;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (minmax(s, t) == minmax(u, v)) continue;
        if (u == s || v == s) {
            if (u != s) swap(u, v);
            compS[anc(v)] = i;
        }
        if (u == t || v == t) {
            if (v != t) swap(u, v);
            compT[anc(u)] = i;
        }
    }
    int id = -1;
    FOR(i, 1, n) if (compS[i] != 0 && compT[i] != 0) {
        mark[compS[i]] = 1; mark[compT[i]] = 1;
        ds--; dt--; id = i; ncomp -= 2;
        break;
    }
    if (id == -1) {
        if (st == -1) {
            puts("No");
            return;
        }
        mark[st] = 1; ds--; dt--; ncomp--;
    }
    FOR(u, 1, n) if ((!!compS[u]) ^ (!!compT[u])) {
        if (compS[u]) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    FOR(u, 1, n) if (compS[u] && compT[u] && u != id) {
        if (ds > dt) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    if (ncomp > 1 || ds < 0 || dt < 0) {
        puts("No");
        return;
    }
    puts("Yes");
    REP(i, m) if (mark[i])
        write(edges[i].first), putchar(' '), writeln(edges[i].second);
}

int main() {
   // freopen("input.in", "r", stdin);
 //   freopen("output.out", "w", stdout);

    load();
    process();

    return 0;
}


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

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FORD(i, b, a) for (int i = b; i >= a; --i)
#define FORE(i, v) for (__typeof (v.begin()) i = v.begin(); i != v.end(); ++i)
#define FORR(i, v) for (__typpeof (v.rbegin()) i = v.rbegin(); i != v.rend(); ++i)
#define sz(v) (int) v.size()
#define all(v) v.begin(), v.end()
#define uni(v) v.erase(unique(all(v)), v.end())
#define sqr(x) 1ll * (x) * (x)
#define EPS 1e-9

template <class T> int getBit(T x, int k) { return x >> k & 1; }
template <class T> T onBit(T x, int k) { return x  (T(1) << k); }
template <class T> T offBit(T x, int k) { return x & (~(T(1) << k)); }
template <class T> bool read(T &x) {
    x = 0; char c; bool nega = 0;
    while (!isdigit(c = getchar()) && c != '-' && c != EOF);
    if (c == EOF) return 0;
    if (c == '-') nega = 1, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (nega) x = -x;
    return 1;
}
template <class T> void wri(T x) { if (x / 10) wri(x / 10); putchar(x % 10 + '0'); }
template <class T> void write(T x) { if (x < 0) putchar('-'), x = -x; wri(x); }
template <class T> void writeln(T x) { write(x); putchar('\n'); }

const int maxn = 2e5 + 10;

int n, m, s, t, ds, dt, st;
int par[maxn], compS[maxn], compT[maxn];
bool mark[maxn << 1];
vector < pair <int, int> > edges;

void load() {
    read(n); read(m);
    REP(i, m) {
        int u, v; read(u); read(v);
        edges.push_back(make_pair(u, v));
    }
    read(s); read(t); read(ds); read(dt);
}

int anc(int p) { return par[p] == p ? p : par[p] = anc(par[p]); }
void join(int u, int v) { par[anc(u)] = anc(v); }

void process() {
    memset(compS, -1, sizeof compS);
    memset(compT, -1, sizeof compT);
    FOR(i, 1, n) par[i] = i;
    int ncomp = n; st = -1;
    REP(i, m) {
        int u = edges[i].first, v = edges[i].second;
        if ((u == s && v == t) || (u == t && v == s)) st = i;
        if (u == s | u == t || v == s || v == t) continue;
        if (anc(u) != anc(v)) {
            join(u, v);
            ncomp--;
            mark[i] = 1;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (minmax(s, t) == minmax(u, v)) continue;
        if (u == s || v == s) {
            if (u != s) swap(u, v);
            compS[anc(v)] = i;
        }
        if (u == t || v == t) {
            if (v != t) swap(u, v);
            compT[anc(u)] = i;
        }
    }
    int id = -1;
    FOR(i, 1, n) if (compS[i] != -1 && compT[i] != -1) {
        mark[compS[i]] = 1; mark[compT[i]] = 1;
        ds--; dt--; id = i; ncomp -= 2;
        break;
    }
    if (id == -1) {
        if (st == -1) {
            puts("No");
            return;
        }
        mark[st] = 1; ds--; dt--; ncomp--;
    }
    FOR(u, 1, n) if (compS[u] != -1 || compT[u] != -1) {
        if (compS[u] != -1 && compT[u] != -1) continue;
        if (compS[u]) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    FOR(u, 1, n) if (compS[u] != -1 && compT[u] != -1 && u != id) {
        if (ds > dt) mark[compS[u]] = 1, ds--;
        else mark[compT[u]] = 1, dt--;
        ncomp--;
    }
    if (ncomp > 1 || ds < 0 || dt < 0) {
        puts("No");
        return;
    }
    puts("Yes");
    REP(i, m) if (mark[i])
        write(edges[i].first), putchar(' '), writeln(edges[i].second);
}

int main() {
   // freopen("input.in", "r", stdin);
//    freopen("output.out", "w", stdout);

    load();
    process();

    return 0;
}


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

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FORD(i, b, a) for (int i = b; i >= a; --i)
#define FORE(i, v) for (__typeof (v.begin()) i = v.begin(); i != v.end(); ++i)
#define FORR(i, v) for (__typpeof (v.rbegin()) i = v.rbegin(); i != v.rend(); ++i)
#define sz(v) (int) v.size()
#define all(v) v.begin(), v.end()
#define uni(v) v.erase(unique(all(v)), v.end())
#define sqr(x) 1ll * (x) * (x)
#define EPS 1e-9

template <class T> int getBit(T x, int k) { return x >> k & 1; }
template <class T> T onBit(T x, int k) { return x  (T(1) << k); }
template <class T> T offBit(T x, int k) { return x & (~(T(1) << k)); }
template <class T> void read(T &x) {
    x = 0; char c; bool nega = 0;
    while (!isdigit(c = getchar()) && c != '-');
    if (c == '-') nega = 1, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (nega) x = -x;
}
template <class T> void wri(T x) { if (x / 10) wri(x / 10); putchar(x % 10 + '0'); }
template <class T> void write(T x) { if (x < 0) putchar('-'); wri(abs(x)); }
template <class T> void writeln(T x) { write(x); putchar('\n'); }

const int N = 4e5 + 10;

int n, m, s, t, ds, dt;
int par[N];
bool mark[N];
vector < pair <int, int> > edges;

void load() {
    read(n); read(m);
    REP(i, m) {
        int u, v; read(u); read(v);
        edges.push_back({u, v});
    }
    read(s); read(t); read(ds); read(dt);
}

int anc(int p) { return par[p] == p ? p : par[p] = anc(par[p]); }
void join(int p, int q) { par[anc(p)] = anc(q); }

void process() {
    FOR(i, 1, n) par[i]= i;
    int comp = n;
    REP(i, m) if (edges[i].first == s || edges[i].second == s) {
        int u = edges[i].first, v = edges[i].second;
        if (anc(u) != anc(v)) {
            ds--; if (u == t || v == t) dt--;
            join(u, v);
            mark[i] = 1;
            comp--;
        }
        if (!ds) break;
    }
    REP(i, m) if (!mark[i] && edges[i].first == t || edges[i].second == t) {
        int u = edges[i].first, v = edges[i].second;
        if (!dt) break;
        if (anc(u) != anc(v)) {
            join(u, v);
            dt--;
            mark[i] = 1; comp--;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (anc(u) != anc(v)) {
            join(u, v);
            comp--; mark[i] = 1;
        }
    }
    if (comp != 1) puts("No"); else {
        puts("Yes");
        REP(i, m) if (mark[i]) {
            write(edges[i].first); putchar(' '); writeln(edges[i].second);
        }
    }
}

int main() {
  //  freopen("input.in", "r", stdin);
 //   freopen("output.out", "w", stdout);

    load();
    process();

    return 0;
}


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

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define FORD(i, b, a) for (int i = b; i >= a; --i)
#define FORE(i, v) for (__typeof (v.begin()) i = v.begin(); i != v.end(); ++i)
#define FORR(i, v) for (__typpeof (v.rbegin()) i = v.rbegin(); i != v.rend(); ++i)
#define sz(v) (int) v.size()
#define all(v) v.begin(), v.end()
#define uni(v) v.erase(unique(all(v)), v.end())
#define sqr(x) 1ll * (x) * (x)
#define EPS 1e-9

template <class T> int getBit(T x, int k) { return x >> k & 1; }
template <class T> T onBit(T x, int k) { return x  (T(1) << k); }
template <class T> T offBit(T x, int k) { return x & (~(T(1) << k)); }
template <class T> bool read(T &x) {
    x = 0; char c; bool nega = 0;
    while (!isdigit(c = getchar()) && c != '-' && c != EOF);
    if (c == EOF) return 0;
    if (c == '-') nega = 1, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (nega) x = -x;
    return 1;
}
template <class T> void wri(T x) { if (x / 10) wri(x / 10); putchar(x % 10 + '0'); }
template <class T> void write(T x) { if (x < 0) putchar('-'), x = -x; wri(x); }
template <class T> void writeln(T x) { write(x); putchar('\n'); }

const int maxn = 2e5 + 10;

int n, m, s, t, ds, dt;
bool edge_st;
int par[maxn];
bool mark[maxn << 1];
vector < pair <int, int> > edges;

void load() {
    read(n); read(m);
    REP(i, m) {
        int u, v; read(u); read(v);
        edges.push_back(make_pair(u, v));
    }
    read(s); read(t); read(ds); read(dt);
}

int anc(int p) { return par[p] == p ? p : par[p] = anc(par[p]); }
void join(int u, int v) { par[anc(u)] = anc(v); }

void process() {
    FOR(i, 1, n) par[i] = i;
    int ncomp = n;
    REP(i, m) {
        int u = edges[i].first, v = edges[i].second;
        edge_st |= (u == s && v == t) || (u == t && v == s);
        if (u == s | u == t || v == s || v == t) continue;
        if (anc(u) != anc(v)) {
            join(u, v);
            ncomp--;
            mark[i] = 1;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (u != s && v != s) continue;
        if (v == t || u == t) continue;
        if (!ds) break;
        if (anc(u) != anc(v)) {
            join(u, v);
            ds--; ncomp--;
            mark[i] = 1;
        }
    }
    REP(i, m) if (!mark[i]) {
        int u = edges[i].first, v = edges[i].second;
        if (u != t && v != t) continue;
        if (u == s || v == s) continue;
        if (!dt) break;
        if (anc(u) != anc(v)) {
            join(u, v);
            dt--; ncomp--;
            mark[i] = 1;
        }
    }
    if (ncomp > 1) {
        if (!ds || !dt) {
            puts("No");
            return;
        }
        if (!edge_st) {
            puts("No");
            return;
        }
        puts("Yes");
        write(s); putchar(' '); writeln(t);
    } else puts("Yes");
    REP(i, m) if (mark[i])
        write(edges[i].first), putchar(' '), writeln(edges[i].second);
}

int main() {
    //freopen("input.in", "r", stdin);
  //  freopen("output.out", "w", stdout);

    load();
    process();

    return 0;
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <tuple>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, w, s, t, ds, dt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (int &u : ns)
	if (u == t)
	{
		std::swap(u, ns.back());
		break;
	}
	for (int &u : nt)
	if (u == s)
	{
		std::swap(u, nt.back());
		break;
	}
	for (i = 1; i <= n; ++i)
	for (auto p = neighbors[i].begin(); p != neighbors[i].end(); )
	{
		if (*p == s || *p == t)
			std::swap(*p, neighbors[i].back()), neighbors[i].pop_back();
		else
			++p;
	}
	for (int w : ns)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		++g;
		if (!reachable)
		{
			neighbors[s].push_back(w);
			neighbors[w].push_back(s);
			if (neighbors[s].size() == ds)
				break;
		}
	}
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	for (int u : neighbors[t])
		visited[u] = g;
	++g;
	for (int w : nt)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		++g;
		if (!reachable)
		{
			neighbors[t].push_back(w);
			neighbors[w].push_back(t);
			if (neighbors[t].size() > dt)
				goto fail;
		}
	}
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1;
	}
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::vector<std::pair<int, int>> st;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, s, t, ds, dt, rs, rt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (i = 1; i <= n; ++i)
	{
		if (i == s || i == t || visited[i])
			continue;
		rs = rt = 0;
		q.push(i), visited[i] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (v == s)
					rs = u;
				else if (v == t)
					rt = u;
				else if (!visited[v])
					q.push(v), visited[v] = g;
			}
		}
		++g;
		if (!rt)
			neighbors[s].push_back(rs);
		else if (!rs)
			neighbors[t].push_back(rt);
		else
			st.emplace_back(rs, rt);
	}
	if (st.empty())
	{
		neighbors[s].push_back(t);
		neighbors[t].push_back(s);
	}
	else
	{
		neighbors[s].push_back(st.back().first);
		neighbors[t].push_back(st.back().second);
		st.pop_back();
	}
	for (auto rst : st)
		if (neighbors[s].size() < ds)
			neighbors[s].push_back(rst.first);
		else
			neighbors[t].push_back(rst.second);
	if (neighbors[s].size() > ds || neighbors[t].size() > dt)
		goto fail;
	for (i = 1; i <= n; ++i)
	if (i != s && i != t)
	for (auto p = neighbors[i].begin(); p != neighbors[i].end(); )
	{
		if (*p == s || *p == t)
			*p = neighbors[i].back(), neighbors[i].pop_back();
		else
			++p;
	}
	for (int u : neighbors[s])
		neighbors[u].push_back(s);
	for (int u : neighbors[t])
		if (u != s)
			neighbors[u].push_back(t);
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1;
	}
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <tuple>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, w, s, t, ds, dt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		if (u == s || u == t || v != s && v != t) neighbors[u].push_back(v);
		if (v == s || v == t || u != s && u != t) neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (int &u : ns)
	if (u == t)
	{
		std::swap(u, ns.back());
		break;
	}
	for (int w : ns)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		if (!reachable)
		{
			neighbors[s].push_back(w);
			neighbors[w].push_back(s);
		}
		++g;
	}
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	for (int u : neighbors[t])
		visited[u] = g;
	++g;
	for (int &u : nt)
	if (u == s)
	{
		std::swap(u, nt.back());
		break;
	}
	for (int w : nt)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		if (!reachable)
		{
			neighbors[t].push_back(w);
			neighbors[w].push_back(t);
		}
		++g;
	}
	if (neighbors[s].size() > ds || neighbors[t].size() > dt)
	{
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <tuple>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, w, s, t, ds, dt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (int &u : ns)
	if (u == t)
	{
		std::swap(u, ns.back());
		break;
	}
	for (int &u : nt)
	if (u == s)
	{
		std::swap(u, nt.back());
		break;
	}
	for (i = 1; i <= n; ++i)
	for (auto p = neighbors[i].begin(); p != neighbors[i].end(); )
	{
		if (*p == s || *p == t)
			std::swap(*p, neighbors[i].back()), neighbors[i].pop_back();
		else
			++p;
	}
	for (int w : ns)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		++g;
		if (!reachable)
		{
			neighbors[s].push_back(w);
			neighbors[w].push_back(s);
			if (neighbors[s].size() == ds)
				break;
		}
	}
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	for (int u : neighbors[t])
		visited[u] = g;
	++g;
	for (int w : nt)
	{
		if (w == s && neighbors[s].size() == ds)
			continue;
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		++g;
		if (!reachable)
		{
			neighbors[t].push_back(w);
			neighbors[w].push_back(t);
			if (neighbors[t].size() > dt)
				goto fail;
		}
	}
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1;
	}
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::vector<std::pair<int, int>> st;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, s, t, ds, dt, rs, rt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (i = 1; i <= n; ++i)
	{
		if (i == s || i == t || visited[i])
			continue;
		rs = rt = 0;
		q.push(i), visited[i] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (v == s)
					rs = u;
				else if (v == t)
					rt = u;
				else if (!visited[v])
					q.push(v), visited[v] = g;
			}
		}
		++g;
		if (!rt)
			neighbors[s].push_back(rs);
		else if (!rs)
			neighbors[t].push_back(rt);
		else
			st.emplace_back(rs, rt);
	}
	if (st.empty())
	{
		neighbors[s].push_back(t);
		neighbors[t].push_back(s);
	}
	else
	{
		neighbors[s].push_back(st.back().first);
		neighbors[t].push_back(st.back().second);
		st.pop_back();
	}
	for (auto rst : st)
		if (neighbors[s].size() < ds)
			neighbors[s].push_back(rst.first);
		else
			neighbors[t].push_back(rst.second);
	if (neighbors[s].size() > ds || neighbors[t].size() > dt)
		goto fail;
	for (i = 1; i <= n; ++i)
	if (i != s && i != t)
	for (auto p = neighbors[i].begin(); p != neighbors[i].end(); )
	{
		if (*p == s || *p == t)
			*p = neighbors.back(), neighbors.pop_back();
		else
			++p;
	}
	for (int u : neighbors[s])
		neighbors[u].push_back(s);
	for (int u : neighbors[t])
		if (u != s)
			neighbors[u].push_back(t);
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1;
	}
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::vector<std::pair<int, int>> st;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, s, t, ds, dt, rs, rt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (i = 1; i <= n; ++i)
	{
		if (i == s || i == t || visited[i])
			continue;
		rs = rt = 0;
		q.push(i), visited[i] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (v == s)
					rs = u;
				else if (v == t)
					rt = u;
				else if (!visited[v])
					q.push(v), visited[v] = g;
			}
		}
		++g;
		if (!rt)
			neighbors[s].push_back(rs);
		else if (!rs)
			neighbors[t].push_back(rt);
		else
			st.emplace_back(rs, rt);
	}
	if (st.empty())
	{
		neighbors[s].push_back(t);
		neighbors[t].push_back(s);
	}
	else
	{
		neighbors[s].push_back(st.back().first);
		neighbors[t].push_back(st.back().second);
		st.pop_back();
	}
	for (auto rst : st)
		if (neighbors[s].size() < ds)
			neighbors[s].push_back(rst.first);
		else
			neighbors[t].push_back(rst.second);
	if (neighbors[s].size() > ds || neighbors[t].size() > dt)
		goto fail;
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1;
	}
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <tuple>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, w, s, t, ds, dt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		if (u == s || u == t || v != s && v != t) neighbors[u].push_back(v);
		if (v == s || v == t || u != s && u != t) neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (int &u : ns)
	if (u == t)
	{
		std::swap(u, ns.back());
		break;
	}
	for (int w : ns)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		if (!reachable)
		{
			neighbors[s].push_back(w);
			neighbors[w].push_back(s);
		}
		++g;
	}
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	for (int &u : nt)
	if (u == s)
	{
		std::swap(u, nt.back());
		break;
	}
	for (int w : nt)
	{
		if (visited[w])
			continue;
		bool reachable = false;
		q.push(w), visited[w] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (!visited[v])
					q.push(v), visited[v] = g;
				else if (visited[v] < g)
					reachable = true;
			}
		}
		if (!reachable)
		{
			neighbors[t].push_back(w);
			neighbors[w].push_back(t);
		}
		++g;
	}
	if (neighbors[s].size() > ds || neighbors[t].size() > dt)
	{
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


#include <stdio.h>
#include <utility>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::vector<std::pair<int, int>> st;
int g = 1, s, t, rs, rt, visited[200001];
static void dfs_rs_rt(int u)
{
	visited[u] = g;
	for (int v : neighbors[u])
	{
		if (v == s)
			rs = u;
		else if (v == t)
			rt = u;
		else if (!visited[v])
			dfs_rs_rt(v);
	}
}
static void dfs_plain(int u)
{
	visited[u] = 1;
	for (int v : neighbors[u])
		if (!visited[v])
			dfs_plain(v);
}
static void dfs_print(int u)
{
	visited[u] = 1;
	for (int v : neighbors[u])
		if (!visited[v])
			printf("%d %d\n", u, v), dfs_print(v);
}
int main()
{
	int i, n, m, u, v, ds, dt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (i = 1; i <= n; ++i)
	{
		if (i == s || i == t || visited[i])
			continue;
		rs = rt = 0;
		dfs_rs_rt(i);
		++g;
		if (!rt)
			neighbors[s].push_back(rs);
		else if (!rs)
			neighbors[t].push_back(rt);
		else
			st.emplace_back(rs, rt);
	}
	if (st.empty())
	{
		neighbors[s].push_back(t);
		neighbors[t].push_back(s);
	}
	else
	{
		neighbors[s].push_back(st.back().first);
		neighbors[t].push_back(st.back().second);
		st.pop_back();
	}
	for (auto rst : st)
		if (neighbors[s].size() < ds)
			neighbors[s].push_back(rst.first);
		else
			neighbors[t].push_back(rst.second);
	if (neighbors[s].size() > ds || neighbors[t].size() > dt)
		goto fail;
	for (i = 1; i <= n; ++i)
	if (i != s && i != t)
	for (auto p = neighbors[i].begin(); p != neighbors[i].end(); )
	{
		if (*p == s || *p == t)
			*p = neighbors[i].back(), neighbors[i].pop_back();
		else
			++p;
	}
	for (int u : neighbors[s])
		neighbors[u].push_back(s);
	for (int u : neighbors[t])
		if (u != s)
			neighbors[u].push_back(t);
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	dfs_plain(1);
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	dfs_print(1);
}


#include <stdio.h>
#include <queue>
#include <utility>
#include <vector>
std::vector<int> neighbors[200001], ns, nt;
std::vector<std::pair<int, int>> st;
std::queue<int> q;
int visited[200001];
int main()
{
	int i, g = 1, n, m, u, v, s, t, ds, dt, rs, rt;
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; ++i)
	{
		scanf("%d%d", &u, &v);
		neighbors[u].push_back(v);
		neighbors[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt);
	ns.swap(neighbors[s]);
	nt.swap(neighbors[t]);
	for (i = 1; i <= n; ++i)
	{
		if (i == s || i == t || visited[i])
			continue;
		rs = rt = 0;
		q.push(i), visited[i] = g;
		while (!q.empty())
		{
			u = q.front(), q.pop();
			for (int v : neighbors[u])
			{
				if (v == s)
					rs = u;
				else if (v == t)
					rt = u;
				else if (!visited[v])
					q.push(v), visited[v] = g;
			}
		}
		++g;
		if (!rt)
			neighbors[s].push_back(rs);
		else if (!rs)
			neighbors[t].push_back(rt);
		else
			st.emplace_back(rs, rt);
	}
	if (st.empty())
	{
		neighbors[s].push_back(t);
		neighbors[t].push_back(s);
	}
	else
	{
		neighbors[s].push_back(st.back().first);
		neighbors[t].push_back(st.back().second);
		st.pop_back();
	}
	for (auto rst : st)
		if (neighbors[s].size() < ds)
			neighbors[s].push_back(rst.first);
		else
			neighbors[t].push_back(rst.second);
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1;
	}
	for (i = 1; i <= n; ++i)
	if (!visited[i])
	{
fail:
		puts("No");
		return 0;
	}
	puts("Yes");
	for (i = 1; i <= n; ++i)
		visited[i] = 0;
	q.push(1), visited[1] = 1;
	while (!q.empty())
	{
		u = q.front(), q.pop();
		for (int v : neighbors[u])
			if (!visited[v])
				q.push(v), visited[v] = 1, printf("%d %d\n", u, v);
	}
}


# include <bits/stdc++.h>
# define ll long long
# define fr first
# define se second
using namespace std;
vector<ll> v[200010];
ll used[200010] , pre[200010] , s , u , us[200010] , user[200010];
map<ll ,  bool> ma[200010];
vector<pair<ll , ll> > ans;
ll dfs(int x , int po){
    pre[x] = po;
    used[x] = 1;
   // cout<<x<< ' '<<po<<'\n';
    for(ll i = 0 ; i < v[x].size() ; i ++){
        ll to = v[x][i];
        if(used[to] == 0 && s != to && u != to)
            dfs(to , po) , ans.push_back({x , to});
    }
}
int main()
{
    ll n , i , x , y , st , ut , m;
    cin>> n>> m;
    for(i = 1 ; i <= m ; i ++){
        cin>> x>> y;
        v[x].push_back(y);
        v[y].push_back(x);
    ma[y][x] = 1;
    ma[x][y] = 1;
    }
    for(i = 1 ; i <= n ; i ++) pre[i] = i;
    cin>> s>> u>> st>> ut;
    for(i = 1 ; i <= n ; i ++){
        if(used[i] == 0 && i != s && i != u){
            dfs(i , i);
        }
    }
    ll tol1 = 0 , tol2 = 0;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        us[to] = v[s][i];
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        if(us[to] != 0){
            tol1 = us[to] , tol2 = v[u][i];
        }
    }
    if(tol1 == 0 && ma[s][u] == 0){cout<<"No";return 0;}
    if(tol1 != 0){
         pre[pre[tol1]] =  s;
        ans.push_back({s , tol1});
        ans.push_back({u , tol2});
    }
        if(ma[s][u] == 1 && tol1 == 0)
        ans.push_back({s , u});
    ll lol1 = 1 , lol2 = 1;
    ///----------------------------------
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        user[to] = 1;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        to = pre[to];
        if(to == s || to == u) continue ;
        if(user[to] == 1) user[to] = 2;
    }
    ///-----------------------------------
    pre[s] = s , pre[u] = u;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
       // cout<<i<<' '<<to<<'\n';
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        if(user[to] != 2) lol1++ , ans.push_back({s , v[s][i]}) , pre[to] = s;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
      //  cout<<u<<' '<<to<<' ';
        to = pre[to];
        to = pre[to];
      //  cout<<to<<' '<<pre[to]<<'\n';
        if(to == s || to == u) continue ;
        if(user[to] != 2) lol2++ , ans.push_back({u , v[u][i]})  , pre[to] = u;
    }
   // for(i = 1 ; i <= n ; i ++) cout<< user[i]<<' ';return 0;
    ll koli  = 0;
    for(i = 1 ; i <= n ; i ++)
        if(user[i] == 2) koli++;
    if(lol1 > st || lol2 > ut){cout<<"No";return 0;}
    if(st + ut < koli + lol1 + lol2){cout<<"No";return 0;}
    cout<<"Yes\n";
    for(i = 1 ; i <= n ; i ++){
        if(user[i] == 2 && lol1 < st) lol1 ++ , cout<<s<<' '<<i<<'\n';
        else
        if(user[i] == 2) lol2 ++ , cout<<u<<' '<<i<<'\n';
    }
    for(i = 0 ; i < ans.size() ; i ++) cout<< ans[i].fr<<' '<<ans[i].se<<'\n';

}


# include<bits/stdc++.h>
# define ll long long
# define pb push_back
using namespace std;
vector<ll> v[1000010] , b[100010] ;
ll x[100010] , used[100010] , skl;
void dfs(int x , int ko){
    used[x] = ko;
    if(skl == 1) return ;
    for(int i = 0 ; i < v[x].size() ; i ++){
        if(used[v[x][i]] == ko){skl = 1;return ;}
        if(used[v[x][i]] != 0)
        dfs(v[x][i] , ko);
    }
}
int main()
{
    ll n , c , i , j;
    cin>> n>> c;
    for(i = 1 ; i <= n ; i ++){
        cin>> x[i];
        ll y;
        for(j = 1 ; j <= x[i] ; j ++)
            cin>> y , b[i].pb(y);
    }
    for(i = 2 ; i <= n ; i ++){
            ll nom = -1;
        for(j = 0 ; j < min(x[i] , x[i -1]) ; j ++){
            if(b[i][j] != b[i - 1][j]) nom = j , j = min(x[i] , x[i -1]);
        }
       // cout<<nom<<' ';
        if(nom != -1){
            v[b[i - 1][nom]].push_back(b[i][nom]);

        }
        else{
            if(x[i] < x[i - 1]){cout<<-1;return 0;}
        }
    }

    ll lol = 0;
    for(i = 1 ; i <= c ; i ++){
        if(used[i] == 0)
           lol++ ,  dfs(i , lol);
        if(skl == 1){cout<<-1;return 0;}
    }
    ll mn = 1e9 , mx = -1e9;
    for(i = 1 ; i <= c ; i ++){
        for(j = 0 ; j < v[i].size() ; j ++){
            if(v[i][j] < i) mx = max(mx , i);
            if(v[i][j] < i) mn = min(mn , i);
        }
    }
  //  cout<<mn<<' '<<mx<<'\n';
    if(mn == 1e9){cout<<0;return 0;}
    cout<<c - mn + 1;
}


# include <bits/stdc++.h>
# define ll long long
# define fr first
# define se second
using namespace std;
vector<ll> v[200010];
ll used[200010] , pre[200010] , s , u , us[200010] , user[200010];
map<ll ,  bool> ma[200010];
vector<pair<ll , ll> > ans;
ll dfs(int x , int po){
    pre[x] = po;
    used[x] = 1;
   // cout<<x<< ' '<<po<<'\n';
    for(ll i = 0 ; i < v[x].size() ; i ++){
        ll to = v[x][i];
        if(used[to] == 0 && s != to && u != to)
            dfs(to , po) , ans.push_back({x , to});
    }
}
int main()
{
    ll n , i , x , y , st , ut , m;
    cin>> n>> m;
    for(i = 1 ; i <= m ; i ++){
        cin>> x>> y;
        v[x].push_back(y);
        v[y].push_back(x);
    ma[y][x] = 1;
    ma[x][y] = 1;
    }
    for(i = 1 ; i <= n ; i ++) pre[i] = i;
    cin>> s>> u>> st>> ut;
    for(i = 1 ; i <= n ; i ++){
        if(used[i] == 0 && i != s && i != u){
            dfs(i , i);
        }
    }

    ll tol1 = 0 , tol2 = 0;
    if(ma[s][u] != 1){
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        us[to] = v[s][i];
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        if(us[to] != 0){
            tol1 = us[to] , tol2 = v[u][i];
        }
    }
    if(tol1 == 0){cout<<"No";return 0;}
     pre[pre[tol1]] =  s;
    ans.push_back({s , tol1});
    ans.push_back({u , tol2});

    }
    else
    {
        ans.push_back({s , u});
    }ll lol1 = 1 , lol2 = 1;
    ///----------------------------------
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        user[to] = 1;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        to = pre[to];
        if(to == s || to == u) continue ;
        if(user[to] == 1) user[to] = 2;
    }
    ///-----------------------------------
    pre[s] = s , pre[u] = u;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
       // cout<<i<<' '<<to<<'\n';
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        if(user[to] != 2) lol1++ , ans.push_back({s , v[s][i]}) , pre[to] = s;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
      //  cout<<u<<' '<<to<<' ';
        to = pre[to];
        to = pre[to];
      //  cout<<to<<' '<<pre[to]<<'\n';
        if(to == s || to == u) continue ;
        if(user[to] != 2) lol2++ , ans.push_back({u , v[u][i]})  , pre[to] = u;
    }
    ll koli  = 0;
    for(i = 1 ; i <= n ; i ++)
        if(user[i] == 2) koli++;
    if(lol1 > st || lol2 > ut){cout<<"No";return 0;}
    if(st + ut < koli + lol1 + lol2){cout<<"No";return 0;}
    cout<<"Yes\n";
    for(i = 1 ; i <= n ; i ++){
        if(user[i] == 2 && lol1 < st) lol1 ++ , cout<<s<<' '<<i<<'\n';
        if(user[i] == 2) lol2 ++ , cout<<u<<' '<<i<<'\n';
    }
    for(i = 0 ; i < ans.size() ; i ++) cout<< ans[i].fr<<' '<<ans[i].se<<'\n';

}


# include <bits/stdc++.h>
# define ll long long
# define fr first
# define se second
using namespace std;
vector<ll> v[200010];
ll used[200010] , pre[200010] , s , u , us[200010] , user[200010];
vector<pair<ll , ll> > ans;
ll dfs(int x , int po){
    pre[x] = po;
    used[x] = 1;
   // cout<<x<< ' '<<po<<'\n';
    for(ll i = 0 ; i < v[x].size() ; i ++){
        ll to = v[x][i];
        if(used[to] == 0 && s != to && u != to)
            dfs(to , po) , ans.push_back({x , to});
    }
}
int main()
{
    ll n , i , x , y , st , ut , m;
    cin>> n>> m;
    for(i = 1 ; i <= m ; i ++){
        cin>> x>> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(i = 1 ; i <= n ; i ++) pre[i] = i;
    cin>> s>> u>> st>> ut;
    for(i = 1 ; i <= n ; i ++){
        if(used[i] == 0 && i != s && i != u){
            dfs(i , i);
        }
    }

    ll tol1 = 0 , tol2 = 0;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        us[to] = v[s][i];
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        if(us[to] != 0){
            tol1 = us[to] , tol2 = v[u][i];
        }
    }
    if(tol1 == 0){cout<<"No";return 0;}
     pre[pre[tol1]] =  s;
    ans.push_back({s , tol1});
    ans.push_back({u , tol2});
    ll lol1 = 1 , lol2 = 1;
    ///----------------------------------
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        user[to] = 1;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        to = pre[to];
        if(to == s || to == u) continue ;
        if(user[to] == 1) user[to] = 2;
    }
    ///-----------------------------------
    pre[s] = s , pre[u] = u;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
       // cout<<i<<' '<<to<<'\n';
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        if(user[to] != 2) lol1++ , ans.push_back({s , v[s][i]}) , pre[to] = s;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
      //  cout<<u<<' '<<to<<' ';
        to = pre[to];
        to = pre[to];
      //  cout<<to<<' '<<pre[to]<<'\n';
        if(to == s || to == u) continue ;
        if(user[to] != 2) lol2++ , ans.push_back({u , v[u][i]})  , pre[to] = u;
    }
    ll koli  = 0;
    for(i = 1 ; i <= n ; i ++)
        if(user[i] == 2) koli++;
    if(lol1 > st || lol2 > ut){cout<<"No";return 0;}
    if(st + ut < koli + lol1 + lol2){cout<<"No";return 0;}
    cout<<"Yes\n";
    for(i = 1 ; i <= n ; i ++){
        if(user[i] == 2 && lol1 < st) lol1 ++ , cout<<s<<' '<<i<<'\n';
        if(user[i] == 2) lol2 ++ , cout<<u<<' '<<i<<'\n';
    }
    for(i = 0 ; i < ans.size() ; i ++) cout<< ans[i].fr<<' '<<ans[i].se<<'\n';

}


# include <bits/stdc++.h>
# define ll long long
# define fr first
# define se second
using namespace std;
vector<ll> v[200010];
ll used[200010] , pre[200010] , s , u , us[200010] , user[200010];
map<ll ,  bool> ma[200010];
vector<pair<ll , ll> > ans;
ll dfs(int x , int po){
    pre[x] = po;
    used[x] = 1;
   // cout<<x<< ' '<<po<<'\n';
    for(ll i = 0 ; i < v[x].size() ; i ++){
        ll to = v[x][i];
        if(used[to] == 0 && s != to && u != to)
            dfs(to , po) , ans.push_back({x , to});
    }
}
int main()
{
    ll n , i , x , y , st , ut , m;
    cin>> n>> m;
    for(i = 1 ; i <= m ; i ++){
        cin>> x>> y;
        v[x].push_back(y);
        v[y].push_back(x);
    ma[y][x] = 1;
    ma[x][y] = 1;
    }
    for(i = 1 ; i <= n ; i ++) pre[i] = i;
    cin>> s>> u>> st>> ut;
    for(i = 1 ; i <= n ; i ++){
        if(used[i] == 0 && i != s && i != u){
            dfs(i , i);
        }
    }

    ll tol1 = 0 , tol2 = 0;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        us[to] = v[s][i];
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        if(us[to] != 0){
            tol1 = us[to] , tol2 = v[u][i];
        }
    }
    if(tol1 == 0 && ma[s][u] == 0){cout<<"No";return 0;}
    if(tol1 != 0){
         pre[pre[tol1]] =  s;
        ans.push_back({s , tol1});
        ans.push_back({u , tol2});
    }
        if(ma[s][u] == 1 && tol1 == 0)
        ans.push_back({s , u});
    ll lol1 = 1 , lol2 = 1;
    ///----------------------------------
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        user[to] = 1;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
        to = pre[to];
        to = pre[to];
        if(to == s || to == u) continue ;
        if(user[to] == 1) user[to] = 2;
    }
    ///-----------------------------------
    pre[s] = s , pre[u] = u;
    for(i = 0 ; i < v[s].size() ; i ++){
        ll to = v[s][i];
       // cout<<i<<' '<<to<<'\n';
        to = pre[to];
        to = pre[to];
        if(to == u || to == s) continue ;
        if(user[to] != 2) lol1++ , ans.push_back({s , v[s][i]}) , pre[to] = s;
    }
    for(i = 0 ; i < v[u].size() ; i ++){
        ll to = v[u][i];
      //  cout<<u<<' '<<to<<' ';
        to = pre[to];
        to = pre[to];
      //  cout<<to<<' '<<pre[to]<<'\n';
        if(to == s || to == u) continue ;
        if(user[to] != 2) lol2++ , ans.push_back({u , v[u][i]})  , pre[to] = u;
    }
    ll koli  = 0;
    for(i = 1 ; i <= n ; i ++)
        if(user[i] == 2) koli++;
    if(lol1 > st || lol2 > ut){cout<<"No";return 0;}
    if(st + ut < koli + lol1 + lol2){cout<<"No";return 0;}
    cout<<"Yes\n";
    for(i = 1 ; i <= n ; i ++){
        if(user[i] == 2 && lol1 < st) lol1 ++ , cout<<s<<' '<<i<<'\n';
        if(user[i] == 2) lol2 ++ , cout<<u<<' '<<i<<'\n';
    }
    for(i = 0 ; i < ans.size() ; i ++) cout<< ans[i].fr<<' '<<ans[i].se<<'\n';

}