#include "bits/stdc++.h"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 4e5 + 5;

int n, m, s, t, ds, dt;
int root[N], cs[N], ct[N];
ii ed[N];
vector < ii > ans;

int f(int x) {
    return root[x] = x == root[x] ? x : f(root[x]);
}

void merge(int x, int y) {
    ans.push_back({x, y});
    x = f(x);
    y = f(y);
    root[y] = x;
    if(cs[y]) cs[x] = cs[y];
    if(ct[y]) ct[x] = ct[y];
}

int main() {

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

    for(int i = 1; i <= n; i++)
        root[i] = i;

    for(int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        ed[i] = {x, y};
    }

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

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        if(x == s) cs[y] = y;
        if(x == t) ct[y] = y;
        if(y == s) cs[x] = x;
        if(y == t) ct[x] = x;
    }

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        if(x != s and x != t and y != s and y != t and f(y) != f(x)) {
            merge(x, y);
        }
    }

    vector < int > both;

    for(int i = 1; i <= n; i++) {
        if(i == s or i == t or i != f(i))
            continue;
        if(!cs[i] and !ct[i]) {
            puts("No");
            return 0;
        }
        if(cs[i] and ct[i]) {
            both.push_back(i);
        }
        else if(cs[i]) {
            ans.push_back({cs[i], s});
            ds--;
        }
        else {
            ans.push_back({ct[i], t});
            dt--;
        }
    }

    if(both.empty()) {
        if(ct[s]) {
            ans.push_back({s, t});
            ds--;
            dt--;
        }
        else {
            puts("No");
            return 0;
        }
    }
    else {
        ans.push_back({s, cs[both.back()]});
        ans.push_back({t, ct[both.back()]});
        ds--;
        dt--;
        both.pop_back();
    }

    for(auto x : both) {
        if(ds > 0) {
            ans.push_back({cs[x], s});
            ds--;
        }
        else {
            ans.push_back({ct[x], t});
            dt--;
        }
    }

    if(ds < 0 or dt < 0) {
        puts("No");
        return 0;
    }

    puts("Yes");

    for(auto x : ans) {
        printf("%d %d\n", x.first, x.second);
    }

    return 0;

}


#include "bits/stdc++.h"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 2e5 + 5;

int n, m, s, t, ds, dt;
int root[N], cs[N], ct[N];
ii ed[N];
vector < ii > ans;

int f(int x) {
    return root[x] = x == root[x] ? x : f(root[x]);
}

void merge(int x, int y) {
    ans.push_back({x, y});
    root[y] = x;
    if(cs[y]) cs[x] = cs[y];
    if(ct[y]) ct[x] = ct[y];
}

int main() {

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

    for(int i = 1; i <= n; i++)
        root[i] = i;

    for(int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        ed[i] = {x, y};
    }

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

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        if(x == s) cs[y] = y;
        if(x == t) ct[y] = y;
        if(y == s) cs[x] = x;
        if(y == t) ct[x] = x;
    }

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        if(x != s and x != t and y != s and y != t and f(y) != f(x)) {
            merge(f(y), f(x));
        }
    }

    vector < int > both;

    for(int i = 1; i <= n; i++) {
        if(i == s or i == t or i != f(i))
            continue;
        if(!cs[i] and !ct[i]) {
            puts("No");
            return 0;
        }
        if(cs[i] and ct[i]) {
            both.push_back(i);
        }
        else if(cs[i]) {
            ans.push_back({cs[i], s});
            ds--;
        }
        else {
            ans.push_back({ct[i], t});
            dt--;
        }
    }

    if(both.empty()) {
        if(ct[s]) {
            ans.push_back({s, t});
            ds--;
            dt--;
        }
        else {
            puts("No");
            return 0;
        }
    }
    else {
        ans.push_back({s, cs[both.back()]});
        ans.push_back({t, ct[both.back()]});
        ds--;
        dt--;
        both.pop_back();
    }

    for(auto x : both) {
        if(ds > 0) {
            ans.push_back({cs[x], s});
            ds--;
        }
        ans.push_back({ct[x], t});
        dt--;
    }

    if(ds < 0 or dt < 0) {
        puts("No");
        return 0;
    }

    puts("Yes");

    for(auto x : ans) {
        printf("%d %d\n", x.first, x.second);
    }

    return 0;

}


#include "bits/stdc++.h"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 2e5 + 5;

int n, m, s, t, ds, dt;
int root[N], cs[N], ct[N];
ii ed[N];
vector < ii > ans;

int f(int x) {
    return root[x] = x == root[x] ? x : f(root[x]);
}

void merge(int x, int y) {
    ans.push_back({x, y});
    root[y] = x;
    cs[x] |= cs[y];
    ct[x] |= ct[y];
}

int main() {

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

    for(int i = 1; i <= n; i++)
        root[i] = i;

    for(int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        ed[i] = {x, y};
    }

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

    cs[s] = ct[t] = 1;

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        cs[x] |= y == s;
        ct[x] |= y == t;
        cs[y] |= x == s;
        ct[y] |= x == t;
    }

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        if(x != s and x != t and y != s and y != t and f(y) != f(x)) {
            merge(f(y), f(x));
        }
    }

    vector < int > both;

    for(int i = 1; i <= n; i++) {
        if(i == s or i == t or i != f(i))
            continue;
        if(!cs[i] and !ct[i]) {
            puts("No");
            return 0;
        }
        if(cs[i] and ct[i]) {
            both.push_back(i);
        }
        else if(cs[i]) {
            ans.push_back({i, s});
            ds--;
        }
        else {
            ans.push_back({i, t});
            dt--;
        }
    }

    if(ct[s]) {
        ans.push_back({s, t});
        ds--;
        dt--;
    }
    else {
        if(both.empty()) {
            puts("No");
            return 0;
        }
        ans.push_back({s, both[0]});
        ans.push_back({t, both[0]});
        ds--;
        dt--;
    }

    for(int i = 1; i < both.size(); i++) {
        int x = both[i];
        if(ds > 0) {
            ans.push_back({x, s});
            ds--;
        }
        ans.push_back({x, t});
        dt--;
    }

    if(ds < 0 or dt < 0) {
        puts("No");
        return 0;
    }

    puts("Yes");

    for(auto x : ans) {
        printf("%d %d\n", x.first, x.second);
    }

    return 0;

}


#include "bits/stdc++.h"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 2e5 + 5;

int n, m, s, t, ds, dt;
int root[N], cs[N], ct[N];
ii ed[N];
vector < ii > ans;

int f(int x) {
    return root[x] = x == root[x] ? x : f(root[x]);
}

void merge(int x, int y) {
    ans.push_back({x, y});
    root[y] = x;
    cs[x] |= cs[y];
    ct[x] |= ct[y];
}

int main() {

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

    for(int i = 1; i <= n; i++)
        root[i] = i;

    for(int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        ed[i] = {x, y};
    }

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

    cs[s] = ct[t] = 1;

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        cs[x] |= y == s;
        ct[x] |= y == t;
        cs[y] |= x == s;
        ct[y] |= x == t;
    }

    for(int i = 1; i <= m; i++) {
        int x, y;
        tie(x, y) = ed[i];
        if(x != s and x != t and y != s and y != t and f(y) != f(x)) {
            merge(f(y), f(x));
        }
    }

    vector < int > both;

    for(int i = 1; i <= n; i++) {
        if(i == s or i == t or i != f(i))
            continue;
        if(!cs[i] and !ct[i]) {
            puts("No");
            return 0;
        }
        if(cs[i] and ct[i]) {
            both.push_back(i);
        }
        else if(cs[i]) {
            ans.push_back({i, s});
            ds--;
        }
        else {
            ans.push_back({i, t});
            dt--;
        }
    }

    if(both.empty()) {
        if(ct[s]) {
            ans.push_back({s, t});
            ds--;
            dt--;
        }
        else {
            puts("No");
            return 0;
        }
    }
    else {
        ans.push_back({s, both.back()});
        ans.push_back({t, both.back()});
        ds--;
        dt--;
        both.pop_back();
    }

    for(auto x : both) {
        if(ds > 0) {
            ans.push_back({x, s});
            ds--;
        }
        ans.push_back({x, t});
        dt--;
    }

    if(ds < 0 or dt < 0) {
        puts("No");
        return 0;
    }

    puts("Yes");

    for(auto x : ans) {
        printf("%d %d\n", x.first, x.second);
    }

    return 0;

}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;
	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	if (isedge & tempvec2.size() != 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}
	else if (isedge & tempvec2.size() == 0) {
		if (dss < ds & dtt < dt) { tempvec.push_back(ii(s, t)); print(); return; }
		else { cout << "No"; exit(0); }
	}
	else if (!isedge & tempvec2.size() > 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}

	while (dss < ds & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() != 0) { cout << "No"; return; }
	else print();

	/*
	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;
	*/
}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;

	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	while (dss < ds & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;

}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;

	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	while (dss < ds & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;

}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;

	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	while (dss < ds & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;

}

int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;
	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	if (isedge & tempvec2.size() != 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}
	else if (isedge & tempvec2.size() == 0) {
		if (dss < ds & dtt < dt) { tempvec.push_back(ii(s, t)); print(); return; }
		else { cout << "No"; exit(0); }
	}

	while (dss < ds & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() != 0) { cout << "No"; return; }
	else print();

	/*
	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;
	*/
}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;
	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	if (isedge & tempvec2.size() != 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			ds++; dt++;
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}
	else if (isedge & tempvec2.size() == 0) {
		if (dss < ds & dtt < dt) { tempvec.push_back(ii(s, t)); print(); return; }
		else { cout << "No"; exit(0); }
	}
	else if (!isedge & tempvec2.size() > 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			ds++; dt++;
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}

	while (dss < ds & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() != 0) { cout << "No"; return; }
	else print();

	/*
	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;
	*/
}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "YES\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;

	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	while (dss < ds & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		tempvec.push_back(ii(s, t));
		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}

	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;

}

int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "YES\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;

	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	while (dss < ds & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;

}

int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		printf("No");;
		exit(0);
	}
}
void print() {
	printf("Yes\n");
	for (int i = 0; i < tempvec.size(); i++) {
		printf("%d %d\n", tempvec[i].first + 1, tempvec[i].second + 1);
	}
}

void process2() {
	bool isedge = false;
	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	if (isedge & tempvec2.size() != 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			dss++; dtt++;
			tempvec2.pop_back();
		}
		else { printf("No");; exit(0); }
	}
	else if (isedge & tempvec2.size() == 0) {
		if (dss < ds & dtt < dt) { tempvec.push_back(ii(s, t)); print(); return; }
		else { printf("No");; exit(0); }
	}
	else if (!isedge & tempvec2.size() > 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			dss++; dtt++;
			tempvec2.pop_back();
		}
		else { printf("No");; exit(0); }
	}

	while (dss < ds & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() != 0) { printf("No"); return; }
	else print();

}
void process3() {
	if (n == 1) {
		printf("Yes"); return;
	}
	if (n == 2) {
		if (m == 0) { printf("No"); return; }
		if (ds >= 1 & dt >= 1) { printf("Yes\n1 2"); return; }
		else printf("No");
		return;
	}
}
int main()
{
	//fio;
	scanf("%d%d",&n,&m);
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		scanf("%d%d",&u,&v);  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	scanf("%d%d%d%d", &s, &t, &ds, &dt); s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;
	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	while (dss < ds & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>1) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (isedge & tempvec2.size() != 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			print();
		}
		else { cout << "No"; exit(0); }
	}
	else if (isedge & tempvec2.size() == 0) {
		if (dss < ds & dtt < dt) { tempvec.push_back(ii(s, t)); print(); return; }
		else { cout << "No"; exit(0); }
	}
	else {
		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds & dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else { cout << "No"; exit(0); }
	}
	/*
	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;
	*/
}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#define fi freopen("../../../../../Desktop/input.txt", "r", stdin);
#define fo freopen("../../../../../Desktop/output.txt", "w", stdout)
#define fio fi fo
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<time.h>
#include<iomanip>
#include<list>
using namespace std;
#define pnl          printf("\n")
#define si(a)        scanf("%d",&a)
#define pi(a)        printf("%d ",a)
#define sii(a,b)     scanf("%d%d",&a,&b)
#define siii(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define fr(i,a,n)    for(int i = (int)(a); i < (int)(n); i++)
#define pb(x)        push_back(x)
#define max(a,b)     (a>b?a:b)
#define min(a,b)     (a>b?b:a)
#define INF_32       100199959
#define ii(a,b)      pair<int,int>(a,b)
typedef long long int ll;

vector<vector<int> >vvi;
vector<bool>visited;
vector< pair<int, int> >tempvec;
vector< pair< pair<int, int>, pair<int, int> > > tempvec2;
int n, m, s, t, ds, dt, dss = 0, dtt = 0;
bool flag1, flag2;
pair<int, int> p1, p2;

void dfs(int u) {
	visited[u] = true;  int v;
	for (int i = 0; i < vvi[u].size(); i++) {
		v = vvi[u][i];
		if (v == s) {
			if (!flag1) { p1 = ii(u, v); flag1 = true; }
		}
		if (v == t) {
			if (!flag2) { p2 = ii(u, v); flag2 = true; }
		}
		if (!visited[v]) {
			tempvec.push_back(ii(u, v));
			dfs(v);
		}
	}
}

void process() {
	if (flag1 & flag2) {
		tempvec2.push_back(pair< pair<int, int>, pair<int, int> >(p1, p2));
		return;
	}
	if (flag1 & dss<ds) {
		tempvec.push_back(p1);
		dss++;
		return;
	}
	if (flag2 & dtt<dt) {
		tempvec.push_back(p2);
		dtt++;
	}
	else {
		cout << "No";
		exit(0);
	}
}
void print() {
	cout << "Yes\n";
	for (int i = 0; i < tempvec.size(); i++) {
		cout << tempvec[i].first + 1 << ' ' << tempvec[i].second + 1<< endl;
	}
}

void process2() {
	bool isedge = false;
	for (int i = 0; i < vvi[s].size(); i++) {if (vvi[s][i] == t) {isedge = true;	break;}}

	if (isedge & tempvec2.size() != 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			dss++; dtt++;
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}
	else if (isedge & tempvec2.size() == 0) {
		if (dss < ds & dtt < dt) { tempvec.push_back(ii(s, t)); print(); return; }
		else { cout << "No"; exit(0); }
	}
	else if (!isedge & tempvec2.size() > 0) {
		if (dss < ds & dtt < dt) {
			tempvec.push_back(tempvec2[tempvec2.size() - 1].first);
			tempvec.push_back(tempvec2[tempvec2.size() - 1].second);
			dss++; dtt++;
			tempvec2.pop_back();
		}
		else { cout << "No"; exit(0); }
	}

	while (dss < ds & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec2.pop_back(); dss++; }
	while (dtt < dt & tempvec2.size()>0) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); tempvec2.pop_back(); dtt++; }

	if (tempvec2.size() != 0) { cout << "No"; return; }
	else print();

	/*
	if (tempvec2.size() > 1) { cout << "No"; return; }
	if (isedge) {

		if ((dss < ds & dtt < dt) & (dss + 1 < ds | dtt + 1 < dt)) { tempvec.push_back(ii(s, t)); dss++; dtt++; }
		else goto down;

		if (tempvec2.size() == 0) { print(); return; }
		if (dss < ds) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); print(); }
		else if (dtt < dt) { tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
		else {
			cout << "No"; exit(0);
		}
		return;
	}
	down:
	if (tempvec2.size() == 0) { cout << "No"; return; }

	if (dss < ds & dtt < dt & tempvec2.size()) { tempvec.push_back(tempvec2[tempvec2.size() - 1].first); tempvec.push_back(tempvec2[tempvec2.size() - 1].second); print(); }
	else {
		cout << "No"; exit(0);
	}
	return;
	*/
}
void process3() {
	if (n == 1) {
		cout << "Yes"; return;
	}
	if (n == 2) {
		if (m == 0) { cout << "No"; return; }
		if (ds >= 1 & dt >= 1) { cout << "Yes\n" << 1 << ' ' << 2; return; }
		else cout << "No";
		return;
	}
}
int main()
{
	//fio;
	cin >> n >> m;
	int u, v;  vvi.resize(n);
	for (int i = 0; i < m; i++) {
		cin >> u >> v;  u--;v--;
		vvi[u].push_back(v);
		vvi[v].push_back(u);
	}
	cin >> s >> t >> ds >> dt;  s--; t--;
	if (n < 3) {   process3(); return 0;	}
	visited.assign(n, false);	visited[s] = visited[t] = true;	tempvec.clear();
	for (int i = 0; i < n; i++) {
			if (!visited[i]) {
				flag1 = flag2 = false;
				dfs(i);
				process();
		}
	}
	process2();

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
#define mp make_pair
#define pb push_back
#define sz(v) (int)v.size()
#define pii pair<ll, ll>

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<pii> v;
    for(int j = 0; j < n; j++){
        int t, w;
        cin >> t >> w;
        v.pb(mp(w, t));
    }
    sort(v.begin(), v.end());
    //reverse(v.begin(), v.end());

    int ans = 0, wid = 0;
    for(int j = 1; j <= n*2; j++){
        int wid = 0, t = 0;
        for(int k = 0; k < n; k++)
            if(v[k].first+wid <= j){
                wid += v[k].first;
            }else t += v[k].second;
        //cout << j << " " << wid << " " << t << endl;
        if(t == j){
            cout << j << endl;
            return 0;
        }
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
#define mp make_pair
#define pb push_back
#define sz(v) (int)v.size()
#define pii pair<int, int>

vector<pii> v;

int dp[101][201];

int foo(int pos, int thick){
    if(pos < 0 && thick == 0) return 0;
    if(pos < 0) return 1e9;
    int &ans = dp[pos][thick];
    if(ans == -1){
        ans = 1e9;
        if(thick >= v[pos].second) ans = foo(pos-1, thick - v[pos].second);
        ans = min(ans, v[pos].first + foo(pos-1, thick));
    }
    return ans;
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    for(int j = 0; j < n; j++){
        int t, w;
        cin >> t >> w;
        v.pb(mp(w, t));
    }

    int ans = 0, wid = 0;
    for(int j = 1; j <= n*2; j++){
        for(int i = 0; i < 101; i++)
            for(int k = 0; k < 201; k++)
                dp[i][k] = -1;

        int cur = foo(n-1, j);
        if(cur <= j){
            cout << j << endl;
            return 0;
        }
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
#include <string.h>
#include <math.h>
#define lld long long int
#define ld long int
#define mod 1000000007
#define pb push_back
#define ump unordered_map
#define fast1 ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
#define fors(i,n) for(int i=0;i<n;i++)
#define forse(i,a,b) for(lld i=a;i<b;i++)
#define forsei(i,a,b) for(lld i=a;i>=b;i--)
#define gogprnt cout<<"Case #"<<x<<": ";
#define Sortdes(ar,n) sort(ar,n,greater<lld>());
using namespace std;
//lld mypower(lld x, lld n){	if (n == 0)	return 1;	if (n & 1) 	return (((x * mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod)%mod);return (((mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod))%mod;}
//int gcd(int a,int b){ if(b==1 || a==1)   return 1;    if(b%a==0)    return a;    return(gcd(b%a,a));}
//lld modinv(lld a) { lld g = gcd(a, mod); if (g != 1) return -1;else{  return mypower(a, mod-2)%mod; } }
//(a/b)%m==((a%m)*(modinv(b)%m));
//a%m=(a+m)%m in order to avoid -ve no
// bool cmp(const pair<lld,lld> &a,const pair<lld,lld> &b)
// {
//     if(a.second==b.second) return a.first>=b.first;
//     else return (a.second<b.second);
// }
// vector<vector<lld>> adj(1e6+1);
// ump<lld,lld> vis,mp;lld od=3,ev=2;
// void dfs(lld j)
// {vis[j]=1;
// for (auto i : adj[j])
// {
//   if(!vis[i])
//   {
//     if(mp[j]==1) { mp[i]=2;}
//     else {mp[i]=1;}
//     dfs(i);
//   }

// }}
void solve()
{vector<int>d[3];int t[10000],w[10000];
 int i,j,k,n,an=10000000;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>t[i]>>w[i];
        d[t[i]].pb(w[i]);
    }
    for(i=1;i<=2;i++)sort(d[i].begin(),d[i].end());
    for(i=0;i<=(int)d[1].size();i++)
        for(j=0;j<=(int)d[2].size();j++){
            int len=0;
            for(k=0;k<i;k++)len+=d[1][k];
            for(k=0;k<j;k++)len+=d[2][k];
            if(len<=d[1].size()-i+2*(d[2].size()-j))an=min(an,(int)d[1].size()-i+2*((int)d[2].size()-j));
        }
    cout<<an<<endl;
   //cout<<thk<<endl;

}
int main() {fast1;
//int x=1,t;cin>>t;while(t--)
	 solve();//x++;}
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
#include <string.h>
#include <math.h>
#define lld long long int
#define ld long int
#define mod 1000000007
#define pb push_back
#define ump unordered_map
#define fast1 ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
#define fors(i,n) for(int i=0;i<n;i++)
#define forse(i,a,b) for(lld i=a;i<b;i++)
#define forsei(i,a,b) for(lld i=a;i>=b;i--)
#define gogprnt cout<<"Case #"<<x<<": ";
#define Sortdes(ar,n) sort(ar,n,greater<lld>());
using namespace std;
//lld mypower(lld x, lld n){	if (n == 0)	return 1;	if (n & 1) 	return (((x * mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod)%mod);return (((mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod))%mod;}
//int gcd(int a,int b){ if(b==1 || a==1)   return 1;    if(b%a==0)    return a;    return(gcd(b%a,a));}
//lld modinv(lld a) { lld g = gcd(a, mod); if (g != 1) return -1;else{  return mypower(a, mod-2)%mod; } }
//(a/b)%m==((a%m)*(modinv(b)%m));
//a%m=(a+m)%m in order to avoid -ve no
bool cmp(const pair<lld,lld> &a,const pair<lld,lld> &b)
{
    if(a.second==b.second) return a.first>=b.first;
    else return (a.second<b.second);
}
// vector<vector<lld>> adj(1e6+1);
// ump<lld,lld> vis,mp;lld od=3,ev=2;
// void dfs(lld j)
// {vis[j]=1;
// for (auto i : adj[j])
// {
//   if(!vis[i])
//   {
//     if(mp[j]==1) { mp[i]=2;}
//     else {mp[i]=1;}
//     dfs(i);
//   }

// }}
void solve()
{
    lld n,wd=0,thk=0;//string s,s1;
     cin>>n;
     vector<pair<lld,lld>> vt;
     fors(i,n) {int a,b; cin>>a>>b; vt.pb(make_pair(a,b));}
     sort(vt.begin(),vt.end(),cmp);int i=1,j=n-1;wd+=vt[0].second;
     //fors(i,n) cout<<vt[i].first<<" "<<vt[i].second<<endl;
    while(i<=j && i<n && j>=0)
    {
        while(i<n && i<=j && thk>=wd)
        {
            wd+=vt[i].second;
            i++;
        }
        while(j>=0 && i<=j && wd>=thk)
        {
           thk+=vt[j].first;
            j--;
        }
    }
   cout<<thk<<endl;

}
int main() {fast1;
//int x=1,t;cin>>t;while(t--)
	 solve();//x++;}
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
#include <string.h>
#include <math.h>
#define lld long long int
#define ld long int
#define mod 1000000007
#define pb push_back
#define ump unordered_map
#define fast1 ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
#define fors(i,n) for(int i=0;i<n;i++)
#define forse(i,a,b) for(lld i=a;i<b;i++)
#define forsei(i,a,b) for(lld i=a;i>=b;i--)
#define gogprnt cout<<"Case #"<<x<<": ";
#define Sortdes(ar,n) sort(ar,n,greater<lld>());
using namespace std;
//lld mypower(lld x, lld n){	if (n == 0)	return 1;	if (n & 1) 	return (((x * mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod)%mod);return (((mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod))%mod;}
//int gcd(int a,int b){ if(b==1 || a==1)   return 1;    if(b%a==0)    return a;    return(gcd(b%a,a));}
//lld modinv(lld a) { lld g = gcd(a, mod); if (g != 1) return -1;else{  return mypower(a, mod-2)%mod; } }
//(a/b)%m==((a%m)*(modinv(b)%m));
//a%m=(a+m)%m in order to avoid -ve no
bool cmp(const pair<lld,lld> &a,const pair<lld,lld> &b)
{
    if(a.second==b.second) return a.first>=b.first;
    else return (a.second<b.second);
}
// vector<vector<lld>> adj(1e6+1);
// ump<lld,lld> vis,mp;lld od=3,ev=2;
// void dfs(lld j)
// {vis[j]=1;
// for (auto i : adj[j])
// {
//   if(!vis[i])
//   {
//     if(mp[j]==1) { mp[i]=2;}
//     else {mp[i]=1;}
//     dfs(i);
//   }

// }}
void solve()
{
    lld n,wd=0,thk=0,t;//string s,s1;
     cin>>n;
     vector<pair<lld,lld>> vt;
     fors(i,n) {int a,b; cin>>a>>b; vt.pb(make_pair(a,b));}
     sort(vt.begin(),vt.end(),cmp);int i=0,j=n-1;
    //fors(i,n) cout<<vt[i].first<<" "<<vt[i].second<<endl;
    while(i<=j && i<n && j>=0)
    {
        while(i<n && i<=j && thk>=wd)
        {
            wd+=vt[i].second;
            i++;t=i-1;

        }
        while(j>=0 && i<=j && wd>=thk)
        {
           thk+=vt[j].first;
            j--;
        }
    }
    if(thk<wd)
    {lld p=vt[t].first;
        while(t>=0 && thk<wd)
        { if(vt[t].first<p)
          {  p=vt[t].first;break;}
            t--;
        }
        thk+=p;
    }

   cout<<thk<<endl;

}
int main() {fast1;
//int x=1,t;cin>>t;while(t--)
	 solve();//x++;}
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
#include <string.h>
#include <math.h>
#define lld long long int
#define ld long int
#define mod 1000000007
#define pb push_back
#define ump unordered_map
#define fast1 ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
#define fors(i,n) for(int i=0;i<n;i++)
#define forse(i,a,b) for(lld i=a;i<b;i++)
#define forsei(i,a,b) for(lld i=a;i>=b;i--)
#define gogprnt cout<<"Case #"<<x<<": ";
#define Sortdes(ar,n) sort(ar,n,greater<lld>());
using namespace std;
//lld mypower(lld x, lld n){	if (n == 0)	return 1;	if (n & 1) 	return (((x * mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod)%mod);return (((mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod))%mod;}
//int gcd(int a,int b){ if(b==1 || a==1)   return 1;    if(b%a==0)    return a;    return(gcd(b%a,a));}
//lld modinv(lld a) { lld g = gcd(a, mod); if (g != 1) return -1;else{  return mypower(a, mod-2)%mod; } }
//(a/b)%m==((a%m)*(modinv(b)%m));
//a%m=(a+m)%m in order to avoid -ve no
bool cmp(const pair<lld,lld> &a,const pair<lld,lld> &b)
{
    if(a.second==b.second) return a.first>=b.first;
    else return (a.second<b.second);
}
// vector<vector<lld>> adj(1e6+1);
// ump<lld,lld> vis,mp;lld od=3,ev=2;
// void dfs(lld j)
// {vis[j]=1;
// for (auto i : adj[j])
// {
//   if(!vis[i])
//   {
//     if(mp[j]==1) { mp[i]=2;}
//     else {mp[i]=1;}
//     dfs(i);
//   }

// }}
void solve()
{
    lld n,wd=0,thk=0,t;//string s,s1;
     cin>>n;
     vector<pair<lld,lld>> vt;
     fors(i,n) {int a,b; cin>>a>>b; vt.pb(make_pair(a,b));}
     sort(vt.begin(),vt.end(),cmp);int i=0,j=n-1;
    //fors(i,n) cout<<vt[i].first<<" "<<vt[i].second<<endl;
    while(i<=j && i<n && j>=0)
    {
        while(i<n && i<=j && thk>=wd)
        {
            wd+=vt[i].second;
            i++;t=i-1;

        }
        while(j>=0 && i<=j && wd>=thk)
        {
           thk+=vt[j].first;
            j--;
        }
    }
    if(thk<wd)
    {lld p=vt[t].first;
        while(t>=0 && thk<wd)
        { if(vt[t].first<p && (wd-thk)<=vt[t].second)
          {  p=vt[t].first;break;}
            t--;
        }
        thk+=p;
    }

   cout<<thk<<endl;

}
int main() {fast1;
//int x=1,t;cin>>t;while(t--)
	 solve();//x++;}
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
#include <string.h>
#include <math.h>
#define lld long long int
#define ld long int
#define mod 1000000007
#define pb push_back
#define ump unordered_map
#define fast1 ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
#define fors(i,n) for(int i=0;i<n;i++)
#define forse(i,a,b) for(lld i=a;i<b;i++)
#define forsei(i,a,b) for(lld i=a;i>=b;i--)
#define gogprnt cout<<"Case #"<<x<<": ";
#define Sortdes(ar,n) sort(ar,n,greater<lld>());
using namespace std;
//lld mypower(lld x, lld n){	if (n == 0)	return 1;	if (n & 1) 	return (((x * mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod)%mod);return (((mypower(x, n / 2))%mod) * (mypower(x, n / 2)%mod))%mod;}
//int gcd(int a,int b){ if(b==1 || a==1)   return 1;    if(b%a==0)    return a;    return(gcd(b%a,a));}
//lld modinv(lld a) { lld g = gcd(a, mod); if (g != 1) return -1;else{  return mypower(a, mod-2)%mod; } }
//(a/b)%m==((a%m)*(modinv(b)%m));
//a%m=(a+m)%m in order to avoid -ve no
bool cmp(const pair<lld,lld> &a,const pair<lld,lld> &b)
{
    if(a.second==b.second) return a.first>=b.first;
    else return (a.second<b.second);
}
// vector<vector<lld>> adj(1e6+1);
// ump<lld,lld> vis,mp;lld od=3,ev=2;
// void dfs(lld j)
// {vis[j]=1;
// for (auto i : adj[j])
// {
//   if(!vis[i])
//   {
//     if(mp[j]==1) { mp[i]=2;}
//     else {mp[i]=1;}
//     dfs(i);
//   }

// }}
void solve()
{
    lld n,wd=0,thk=0,t;//string s,s1;
     cin>>n;
     vector<pair<lld,lld>> vt;
     fors(i,n) {int a,b; cin>>a>>b; vt.pb(make_pair(a,b));}
     sort(vt.begin(),vt.end(),cmp);int i=0,j=n-1;
    //fors(i,n) cout<<vt[i].first<<" "<<vt[i].second<<endl;
    while(i<=j && i<n && j>=0)
    {
        while(i<n && i<=j && thk>=wd)
        {
            wd+=vt[i].second;
            i++;t=i-1;
        }
        while(j>=0 && i<=j && wd>=thk)
        {
           thk+=vt[j].first;
            j--;
        }//cout<<thk<<endl;
    }
    if(thk<wd)
    {
        while(t>=0 && thk<wd)
        {
            thk+=vt[t].first;
            wd-=vt[t].second;
            t--;
        }
    }

   cout<<thk<<endl;

}
int main() {fast1;
//int x=1,t;cin>>t;while(t--)
	 solve();//x++;}
	return 0;
}


import java.util.*;
import java.lang.Math;
import java.io.*;
import java.math.*;

public class bookshelf{
	public static long mod = 1000000007;
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		List<Integer> one = new ArrayList<Integer>();
		List<Integer> two = new ArrayList<Integer>();
		int temp;
		int n = input.nextInt();
		for (int i=0;i<n;i++){
			temp = input.nextInt();
			if (temp == 1)
				one.add(input.nextInt());
			else
				two.add(input.nextInt());
		}
		one.add(0);
		two.add(0);
		Collections.sort(one);
		Collections.sort(two);
		for (int i=1;i<one.size();i++)
			one.set(i,one.get(i)+ one.get(i-1));
		for (int i=1;i<two.size();i++)
			two.set(i,two.get(i)+ two.get(i-1));
		int min = 100000;
		for (int i=0;i<one.size();i++)
			for(int j=0;j<two.size();j++)
				if ((one.get(i) + two.get(j)) <= (one.size()-i-1 + 2*(two.size()-j-1)))
					if ((one.size()-i-1 + 2*(two.size()-j-1))<min)
						min = one.size()-i-1 + 2*(two.size()-j-1);
		System.out.println(min);
	}
}


import java.util.*;
import java.lang.Math;
import java.io.*;
import java.math.*;

public class bookshelf{
	public static long mod = 1000000007;
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		List<Integer> one = new ArrayList<Integer>();
		List<Integer> two = new ArrayList<Integer>();
		int temp;
		int n = input.nextInt();
		for (int i=0;i<n;i++){
			temp = input.nextInt();
			if (temp == 1)
				one.add(input.nextInt());
			else
				two.add(input.nextInt());
		}
		one.add(0);
		two.add(0);
		Collections.sort(one);
		Collections.sort(two);
		for (int i=1;i<one.size();i++)
			one.set(i,one.get(i)+ one.get(i-1));
		for (int i=1;i<two.size();i++)
			two.set(i,two.get(i)+ two.get(i-1));
		int min = 100000;
		for (int i=0;i<one.size();i++)
			for(int j=0;j<two.size();j++)
				if ((one.get(i) + two.get(j)) < (one.size()-i-1 + 2*(two.size()-j-1)))
					if ((one.size()-i-1 + 2*(two.size()-j-1))<min)
						min = one.size()-i-1 + 2*(two.size()-j-1);
		System.out.println(min);
	}
}


import java.util.Scanner;
import java.util.List;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Petru
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskB solver = new TaskB();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskB {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n=in.nextInt();
        ArrayList<Integer> v1=new ArrayList();
        ArrayList<Integer> v2=new ArrayList();
        for(int i=0; i<n; ++i) {
            int t=in.nextInt(),w=in.nextInt();
            if(t==1) v1.add(w);
            else v2.add(w);
        }
        Collections.sort(v1);
        Collections.sort(v2);
        Collections.reverse(v1);
        Collections.reverse(v2);
        int rez=(1<<30);
        for(int i=0; i<=v1.size(); ++i)
            for(int j=0; j<=v2.size(); ++j) {
                int st=i+j*2,sw=0;
                for(int k=i; k<v1.size(); ++k) sw+=v1.get(k);
                for(int k=j; k<v2.size(); ++k) sw+=v2.get(k);
                if(st>=sw)  rez=Math.min(rez,st);
            }
        for(int j=0; j<=v2.size(); ++j)
            for(int i=0; i<=v1.size(); ++i) {
                int st=i+j*2,sw=0;
                for(int k=i; k<v1.size(); ++k) sw+=v1.get(k);
                for(int k=j; k<v2.size(); ++k) sw+=v2.get(k);
                if(st>=sw)  rez=Math.min(rez,st);
            }
        out.print(rez);
    }
}


import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author ocelopilli
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskB solver = new TaskB();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskB {
    List< Integer >[] book = (List<Integer>[])new List<?>[2];
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        book[0] = new ArrayList<Integer>();
        book[1] = new ArrayList<Integer>();

        int ans = 0;
        for (int i=0; i<n; i++)
        {
            int t = in.nextInt();
            int w = in.nextInt();
            book[ t-1 ].add( w );
            ans += w;
        }

        book[0].add( 0 );
        book[1].add( 0 );

        Collections.sort( book[0] );
        Collections.sort( book[1] );

        for (int i=0, sa = 0; i<book[0].size(); i++)
        {
            sa += book[0].get( i );
            for (int j=0, sb = 0; j<book[1].size(); j++)
            {
                sb += book[1].get( j );
                int above = (book[0].size()-1 - i) + 2*(book[1].size()-1 - j);
                if ( sa + sb <= above )
                {
                    ans = Math.min( ans, book[0].size()-1 - i + 2*(book[1].size()-1 - j) );
                }
            }
        }

        out.println( ans );
    }
}

class InputReader {
    BufferedReader br;
    StringTokenizer st;

    public InputReader(InputStream in)
    {
        br = new BufferedReader(new InputStreamReader(in));
        st = null;
    }

    public String next()
    {
        while (st==null || !st.hasMoreTokens())
        {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return st.nextToken();
    }

    public int nextInt() { return Integer.parseInt(next()); }
    }


import java.util.*;
public class ShaassBookshelf {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		ArrayList<Integer> one = new ArrayList<Integer>();
		ArrayList<Integer> two = new ArrayList<Integer>();
		for (int i = 0; i < n; i ++) {
			int x = in.nextInt();
			int y = in.nextInt();
			if (x == 1) one.add(y);
			else two.add(y);
		}
		Collections.sort(one);
		Collections.sort(two);
		int min = Integer.MAX_VALUE;
		for (int i = 0; i <= one.size(); i++) {
            for (int j = 0; j <= two.size(); j++) {
                int size = one.size() - i + (two.size() - j) * 2;
                int count = 0;
                for (int k = 0; k < i; k++)
                    count += one.get(k);
                for (int k = 0; k < j; k++)
                    count += two.get(k);
                if (size >= count)
                    min = Math.min(size, min);
            }
		}
		System.out.println(min);
	}
}


import java.util.*;
public class ShaassBookshelf {
	public class Shelf {
		int[] widths;
		int[] thicks;
		State init;
		public Shelf(int[] w, int[] t) {
			widths = w;
			thicks = t;
			int total = 0;
			ArrayList<Integer> initBot = new ArrayList<Integer>();
			for (int i = 0; i < t.length; i ++) {
				total += t[i];
				initBot.add(i);
			}
			init = new State(new ArrayList<Integer>(), initBot, 0, total);
		}
		public class State {
			ArrayList<Integer> lay, stand;
			int top, bot;
			public State(ArrayList<Integer> l, ArrayList<Integer> s, int t, int b) {
				top = t;
				bot = b;
				lay = l;
				stand = s;
			}
			public void printString() {
				System.out.println("bot " + bot);
				System.out.println("top " + top);
				System.out.println("lay " + lay.toString());
				System.out.println("stand " + stand.toString());			}
		}
		public ArrayList<State> nextStates(State s) {
			ArrayList<State> next = new ArrayList<State>();
			for (int i = 0; i < s.stand.size(); i ++) {
				int temp = s.stand.get(i);
				s.lay.add(temp);
				s.stand.remove(i);
				ArrayList<Integer> newLay = new ArrayList<Integer>();
				newLay.addAll(s.lay);
				ArrayList<Integer> newStand = new ArrayList<Integer>();
				newStand.addAll(s.stand);
				State poss = new State(newLay, newStand, s.top + widths[i], s.bot - thicks[i]);
				s.stand.add(temp);
				s.lay.remove((Integer) temp);
				next.add(poss);
			}
//			System.out.println("current state: ");
//			s.printString();
//			for (State state : next) state.printString();
			return next;
		}
		public int bfs(State start) {
			Queue<State> q = new LinkedList<State>();
			ArrayList<State> visited = new ArrayList<State>();
			q.add(start);
			int ans = q.peek().bot;
			while (!q.isEmpty()) {
				State s = q.poll();
				if (!visited.contains(s)) {
					if (s.top <= s.bot) {
						if (s.bot < ans) ans = s.bot;
						q.addAll(nextStates(s));
					}
					visited.add(s);
				}
			}
			return ans;
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] t = new int[n];
		int[] w	 = new int[n];
		for (int i = 0; i < n; i ++) {
			t[i] = in.nextInt();
			w[i] = in.nextInt();
		}
		ShaassBookshelf sb = new ShaassBookshelf();
		Shelf shelf = sb.new Shelf(w, t);
		System.out.println(shelf.bfs(shelf.init));
	}

}


import java.util.*;
public class ShaassBookshelf {
	public class Shelf {
		int[] widths;
		int[] thicks;
		State init;
		public Shelf(int[] w, int[] t) {
			widths = w;
			thicks = t;
			int total = 0;
			ArrayList<Integer> initBot = new ArrayList<Integer>();
			for (int i = 0; i < t.length; i ++) {
				total += t[i];
				initBot.add(i);
			}
			init = new State(new ArrayList<Integer>(), initBot, 0, total);
		}
		public class State {
			ArrayList<Integer> lay, stand;
			int top, bot;
			public State(ArrayList<Integer> l, ArrayList<Integer> s, int t, int b) {
				top = t;
				bot = b;
				lay = l;
				stand = s;
			}
			public void printString() {
				System.out.println("bot " + bot);
				System.out.println("top " + top);
				System.out.println("lay " + lay.toString());
				System.out.println("stand " + stand.toString());			}
		}
		public ArrayList<State> nextStates(State s) {
			ArrayList<State> next = new ArrayList<State>();
			for (int i = 0; i < s.stand.size(); i ++) {
				int temp = s.stand.get(i);
				s.lay.add(temp);
				s.stand.remove(i);
				ArrayList<Integer> newLay = new ArrayList<Integer>();
				newLay.addAll(s.lay);
				ArrayList<Integer> newStand = new ArrayList<Integer>();
				newStand.addAll(s.stand);
				State poss = new State(newLay, newStand, s.top + widths[i], s.bot - thicks[i]);
				s.stand.add(temp);
				s.lay.remove((Integer) temp);
				next.add(poss);
			}
//			System.out.println("current state: ");
//			s.printString();
//			for (State state : next) state.printString();
			return next;
		}
		public int bfs(State start) {
			System.out.println("widths " + Arrays.toString(widths));
			System.out.println("thicks " + Arrays.toString(thicks));
			Queue<State> q = new LinkedList<State>();
			ArrayList<State> visited = new ArrayList<State>();
			q.add(start);
			int ans = q.peek().bot;
			while (!q.isEmpty()) {
				State s = q.poll();
				if (!visited.contains(s)) {
					if (s.top <= s.bot) {
						if (s.bot < ans) ans = s.bot;
						q.addAll(nextStates(s));
					}
					visited.add(s);
				}
			}
			return ans;
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] t = new int[n];
		int[] w	 = new int[n];
		for (int i = 0; i < n; i ++) {
			t[i] = in.nextInt();
			w[i] = in.nextInt();
		}
		ShaassBookshelf sb = new ShaassBookshelf();
		Shelf shelf = sb.new Shelf(w, t);
		System.out.println(shelf.bfs(shelf.init));
	}

}


//package com.congli.codeforces;

import java.io.*;
import java.util.*;

public class C178Div2B_ShaassAndBookshelf {

	BufferedReader in;
	PrintWriter out;
	StringTokenizer tok = new StringTokenizer("");

	public static void main(String[] args) {
		C178Div2B_ShaassAndBookshelf test = new C178Div2B_ShaassAndBookshelf();
		test.start();
	}

	public void solve() throws IOException
	{
		int n = readInt();
		int[] thick = new int[n];
		int[] width = new int[n];
		for(int i = 0; i < n; ++i)
		{
			thick[i] = readInt();
			width[i] = readInt();
		}

		int[][] dp = new int[n][2*n + 1];
		for(int i = 0; i < n; ++i)
			Arrays.fill(dp[i], -1);

		dp[0][0] = width[0];
		dp[0][thick[0]] = 0;
		for(int i = 1; i < n; ++i)
		{
			for(int total_t = 0; total_t <= 2*n; ++total_t)
			{
				if(total_t < thick[i])
				{
					if(dp[i-1][total_t] < 0) continue;
					dp[i][total_t] = dp[i-1][total_t] + width[i];
				}
				else
				{
					if(dp[i-1][total_t - thick[i]] < 0 && dp[i-1][total_t] < 0) continue;
					if(dp[i-1][total_t - thick[i]] < 0)
						dp[i][total_t] = dp[i-1][total_t] + width[i];
					else if(dp[i-1][total_t] < 0)
						dp[i][total_t] = dp[i-1][total_t - thick[i]];
					else
						dp[i][total_t] = Math.min(dp[i-1][total_t - thick[i]], dp[i-1][total_t] + width[i]);
				}
			}
		}

		int result = 0;
		while(dp[n-1][result] == -1 || result < dp[n-1][result])
			++result;
		System.out.println(result);
	}

	public void start()
	{
		try {
			long t1 = System.currentTimeMillis();
			if (System.getProperty("ONLINE_JUDGE") != null) {
				in = new BufferedReader(new InputStreamReader(System.in));
				out = new PrintWriter(System.out);
			} else {
				in = new BufferedReader(new FileReader("..\\codeforces\\src\\com\\congli\\codeforces\\input.txt"));
				out = new PrintWriter(System.out);
			}
			Locale.setDefault(Locale.US);
			solve();
			in.close();
			out.close();
			long t2 = System.currentTimeMillis();
			//System.err.println("Time = " + (t2 - t1));
		} catch (Throwable t) {
			t.printStackTrace(System.err);
			System.exit(-1);
		}
	}

	public String readString() throws IOException {
		while (!tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	public int readInt() throws IOException {
		return Integer.parseInt(readString());
	}

	public long readLong() throws IOException {
		return Long.parseLong(readString());
	}

	public double readDouble() throws IOException {
		return Double.parseDouble(readString());
	}
}


import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Vector;

public class Test {
	public static void main(String[] argv){
		Scanner scan = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = scan.nextInt();
		ArrayList<Vector<Integer>> t = new ArrayList<Vector<Integer> >();
		int tsum = 0;
		for(int i = 0; i < n; ++i){
			Vector<Integer> temp = new Vector<Integer>();
			int p = scan.nextInt();
			int q = scan.nextInt();
			tsum += p;
			temp.add(q);
			temp.add(p);
			t.add(temp);
		}
		Collections.sort(t, new Comparator<Vector<Integer> >(){

			@Override
			public int compare(Vector<Integer> a, Vector<Integer> b) {
				if(a.get(0) < b.get(0)) return -1;
				else if(a.get(0) == b.get(0)){
					if(a.get(1) < b.get(1)) return -1;
					else if(a.get(1) == b.get(1)) return 0;
					else return 1;
				} else return 1;
			}

		});
		int sum = 0;
		for(int i = n - 1; i >= 0; --i){
			if(sum >= tsum){
				break;
			}
			sum += t.get(i).get(1);
			tsum -= t.get(i).get(1);
		}
		out.println(sum);
		out.close();
	}
}


import java.io.PrintWriter;
import java.util.Scanner;

public class Test {
	public static int MAX = 100001;
	public static int a[][];
	public static int dp[][];
	public static int n;

	public static int rec(int i, int left) {
		if (i >= n) {
			if (left < 0)
				return MAX;
			else
				return 0;
		}
		if (dp[i][left + 10000] != -1)
			return dp[i][left + 10000];

		int up = rec(i + 1, left - a[i][1]);
		int down = rec(i + 1, left + a[i][0]) + a[i][0];
		return dp[i][left + 10000] = Math.min(up, down);
	}

	public static void main(String[] argv) {
		Scanner scan = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		n = scan.nextInt();
		a = new int[n + 1][2];
		dp = new int[n + 2][20001];
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < 20001; ++j)
				dp[i][j] = -1;
		}
		for (int i = 0; i < n; ++i) {
			a[i][0] = scan.nextInt();
			a[i][1] = scan.nextInt();
		}
		out.println(rec(0, 0));
		out.close();
	}
}


import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Vector;

public class Test {
	public static void main(String[] argv){
		Scanner scan = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = scan.nextInt();
		ArrayList<Vector<Integer>> t = new ArrayList<Vector<Integer> >();
		int tsum = 0, wsum = 0;;
		for(int i = 0; i < n; ++i){
			Vector<Integer> temp = new Vector<Integer>();
			int p = scan.nextInt();
			int q = scan.nextInt();
			tsum += p;
			wsum += q;
			temp.add(q);
			temp.add(p);
			t.add(temp);
		}
		Collections.sort(t, new Comparator<Vector<Integer> >(){

			@Override
			public int compare(Vector<Integer> a, Vector<Integer> b) {
				if(a.get(0) < b.get(0)) return -1;
				else if(a.get(0) == b.get(0)){
					if(a.get(1) < b.get(1)) return -1;
					else if(a.get(1) == b.get(1)) return 0;
					else return 1;
				} else return 1;
			}

		});
		int sum = 0, ret = 0;
		int tt = 0, ww = 0;
		for(int i = n - 1; i >= 0; --i){
			if(tt >= wsum){
				break;
			}
			tt += t.get(i).get(1);
			wsum -= t.get(i).get(0);
		}
		out.println(tt);
		out.close();
	}
}


import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Vector;

public class Test {
	public static void main(String[] argv){
		Scanner scan = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = scan.nextInt();
		ArrayList<Vector<Integer>> t = new ArrayList<Vector<Integer> >();
		int tsum = 0;
		for(int i = 0; i < n; ++i){
			Vector<Integer> temp = new Vector<Integer>();
			int p = scan.nextInt();
			int q = scan.nextInt();
			tsum += p;
			temp.add(q);
			temp.add(p);
			t.add(temp);
		}
		Collections.sort(t, new Comparator<Vector<Integer> >(){

			@Override
			public int compare(Vector<Integer> a, Vector<Integer> b) {
				if(a.get(0) < b.get(0)) return -1;
				else if(a.get(0) == b.get(0)){
					if(a.get(1) < b.get(1)) return -1;
					else if(a.get(1) == b.get(1)) return 0;
					else return 1;
				} else return 1;
			}

		});
		int width = 0, ret = 0;;
		for(int i = 0; i < n; ++i){
			ret = tsum;
			width = t.get(i).get(0);
			tsum -= t.get(i).get(1);
			if(width > tsum){
				break;
			};
		}
		out.println(ret);
		out.close();
	}
}


import java.util.*;

public class B {
	public static void main(String [] args){
		try (Scanner s = new Scanner(System.in)){
			final int n = s.nextInt();
			List<Integer> t1 = new ArrayList<Integer>();
			List<Integer> t2 = new ArrayList<Integer>();
			for (int i = 0; i < n; ++i){
				final int t = s.nextInt();
				final int w = s.nextInt();
				if (t == 1){
					t1.add(w);
				}else{
					t2.add(w);
				}
			}

			Collections.sort(t1, Collections.reverseOrder());
			int [] s1 = new int[t1.size() + 1];
			for (int i = 1; i <= t1.size(); ++i){
				s1[i] = s1[i - 1] + t1.get(i - 1);
			}

			Collections.sort(t2, Collections.reverseOrder());
			int [] s2 = new int[t2.size() + 1];
			for (int i = 1; i <= t2.size(); ++i){
				s2[i] = s2[i - 1] + t2.get(i - 1);
			}

			int res = Integer.MAX_VALUE;
			for (int k = 0; k <= t1.size(); ++k){
				for (int l = 0; l <= t2.size(); ++l){
					final int w1 = s1[t1.size()] - s1[k];
					final int w2 = s2[t2.size()] - s2[l];
					final int total = k + l*2;
					if (total >= w1 + w2){
						res = Math.min(res, total);
					}
				}
			}
			System.out.println(res);
		}
	}
}


import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] arg)
	{
		Scanner scanner=new Scanner(new BufferedInputStream(System.in));
		int n=scanner.nextInt();
		int[] t=new int[n],w=new int[n];
		int sumw=0;
		for (int i=0;i<n;i++)
		{
			t[i]=scanner.nextInt();
			w[i]=scanner.nextInt();
			sumw+=w[i];
			w[i]+=t[i];
		}
		int[] dp=new int[20000+1];
		Arrays.fill(dp,19930309);
		dp[0]=0;
		for (int i=0;i<n;i++)
			for (int j=20000;j>=w[i];j--)
				dp[j]=Math.min(dp[j],dp[j-w[i]]+t[i]);
		int ans=19930309;
		for (int i=20000;i>=sumw;i--) ans=Math.min(ans,dp[i]);
		System.out.println(ans);
		scanner.close();
	}
}


import java.io.*;
import java.util.*;

public class B
{
	public static void main(String [] args) throws IOException
	{
		Scanner in = new Scanner(System.in);

		int n = in.nextInt();
		Book [] books = new Book[n];
		for(int i = 0 ; i < n ; i++)
		{
			int thickness = in.nextInt();
			int width = in.nextInt();

			books[i] = new Book(thickness, width);
		}

		int [][] dp = new int[n+1][250];
		for(int [] fill : dp)
			Arrays.fill(fill, Integer.MAX_VALUE/2);

		dp[0][0] = 0;

		for(int i = 0 ; i < n ; i++)
			for(int j = 0 ; j < 220 ; j++)
				if(dp[i][j] != Integer.MAX_VALUE/2)
				{
					dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j] + books[i].width);
					dp[i+1][j+books[i].thickness] = Math.min(dp[i+1][j+books[i].thickness], dp[i][j]);
				}

		int res = Integer.MAX_VALUE/2;
		for(int i = 0 ; i < 250 ; i++)
			if(dp[n][i] <= i)
			{
				res = i;
				break;
			}
		System.out.println(res);

	}

	static class Book
	{
		int thickness, width;

		public Book(int thickness, int width)
		{
			this.thickness = thickness;
			this.width = width;
		}
	}
}


import java.util.Arrays;
import java.util.Scanner;

public class B {

	static Scanner in = new Scanner(System.in);

	public static void main(String[] args) {
		int n = in.nextInt();
		Book[] books = new Book[n];
		int width = 0;
		for(int i = 0 ; i < n ; i++) {
			books[i] = new Book();
			books[i].t = in.nextInt();
			books[i].w = in.nextInt();
			width += books[i].t;
		}
		Arrays.sort(books);
		int res = width;
		int sum = 0;
		for(int i = n - 1; i >= 0 ; i--) {
			if(width - books[i].t >= sum + books[i].w) {
				res = width - books[i].t;
				width -= books[i].t;
				sum += books[i].w;
			} else
				break;
		}
		System.out.println(res);
	}

}

class Book implements Comparable<Book> {
	int w;
	int t;

	@Override
	public int compareTo(Book o) {
		if (w == o.w)
			return o.t - t;
		return o.w - w;
	}

}


import java.util.Arrays;
import java.util.Scanner;

public class B {

	static Scanner in = new Scanner(System.in);
	public static void main(String[] args) {
		int n = in.nextInt();
		Book[] books = new Book[n];
		int width = 0;
		for(int i = 0 ; i < n ; i++) {
			books[i] = new Book();
			books[i].t = in.nextInt();
			books[i].w = in.nextInt();
			width += books[i].t;
		}
		int res = width;
		int dp[][] = new int[n + 1][];
		dp[n] = new int[width+1];
		Arrays.fill(dp[n], Integer.MAX_VALUE);
		dp[n][0] = width;
		for(int i = n - 1; i >= 0 ; i--) {
			dp[i] = new int[width + 1];
			Arrays.fill(dp[i], Integer.MAX_VALUE);
			for(int j = 0; j <= width; j++) {
				dp[i][j] = Math.min(dp[i][j], dp[i+1][j]);
				if(dp[i +1][j] != Integer.MAX_VALUE && j + books[i].w <= dp[i+1][j] - books[i].t) {
					dp[i][j+books[i].w] = Math.min(dp[i][j+books[i].w], dp[i+1][j] - books[i].t);
				}
			}
		}
		for(int i=0;i<=width;i++) {
			res = Math.min(res, dp[0][i]);
		}
		System.out.println(res);
	}

}

class Book implements Comparable<Book> {
	int w;
	int t;

	@Override
	public int compareTo(Book o) {
		if (w == o.w)
			return o.t - t;
		return o.w - w;
	}

}


import java.util.Arrays;
import java.util.Scanner;

public class B {

    static Scanner in = new Scanner(System.in);
    public static void main(String[] args) {
        int n = in.nextInt();
        Book[] books = new Book[n];
        int width = 0;
        for(int i = 0 ; i < n ; i++) {
            books[i] = new Book();
            books[i].t = in.nextInt();
            books[i].w = in.nextInt();
            width += books[i].t;
        }
        Arrays.sort(books);
        int res = width;
        int dp[][] = new int[n + 1][];
        dp[n] = new int[width+1];
        Arrays.fill(dp[n], Integer.MAX_VALUE);
        dp[n][0] = width;
        for(int i = n - 1; i >= 0 ; i--) {
            dp[i] = new int[width + 1];
            Arrays.fill(dp[i], Integer.MAX_VALUE);
            for(int j = 0; j <= width; j++) {
                dp[i][j] = Math.min(dp[i][j], dp[i+1][j]);
                if(dp[i +1][j] != Integer.MAX_VALUE && j + books[i].w <= dp[i+1][j] - books[i].t) {
                    dp[i][j+books[i].w] = Math.min(dp[i][j+books[i].w], dp[i+1][j] - books[i].t);
                }
            }
        }
        for(int i=0;i<=width;i++) {
            res = Math.min(res, dp[0][i]);
        }
        System.out.println(res);
    }

}

class Book implements Comparable<Book> {
    int w;
    int t;

    @Override
    public int compareTo(Book o) {
        if (w == o.w)
            return o.t - t;
        return o.w - w;
    }

}


import java.util.Arrays;
import java.util.Scanner;

public class B {

    static Scanner in = new Scanner(System.in);
    final static int max = 1000000;
    public static void main(String[] args) {
        int n = in.nextInt();
        Book[] books = new Book[n];
        int width = 0;
        for(int i = 0 ; i < n ; i++) {
            books[i] = new Book();
            books[i].t = in.nextInt();
            books[i].w = in.nextInt();
            width += books[i].t;
        }
        Arrays.sort(books);
        int res = width;
        int dp[][] = new int[n + 1][];
        dp[n] = new int[width+1];
        Arrays.fill(dp[n], max);
        dp[n][0] = width;
        for(int i = n - 1; i >= 0 ; i--) {
            dp[i] = new int[width + 1];
            Arrays.fill(dp[i], max);
            for(int j = 0; j <= width; j++) {
                dp[i][j] = Math.min(dp[i][j], dp[i+1][j]);
                if(dp[i +1][j] != max && j + books[i].w <= dp[i+1][j] - books[i].t) {
                    dp[i][j+books[i].w] = Math.min(dp[i][j+books[i].w], dp[i+1][j] - books[i].t);
                }
            }
        }
        for(int i=0;i<=width;i++) {
            res = Math.min(res, dp[0][i]);
        }
        System.out.println(res);
    }

}

class Book implements Comparable<Book> {
    int w;
    int t;

    @Override
    public int compareTo(Book o) {
        if (w == o.w)
            return o.t - t;
        return o.w - w;
    }

}


import static java.lang.System.*;
import static java.lang.Math.*;
import java.util.*;

public class B294 {
	public static Scanner sc=new Scanner(in);
	//public static Random sc=new Random();

	public static final String br=System.getProperty("line.separator");
	final int mod=1000000007;

	void run(){
		final int n=sc.nextInt();
		List <Integer>  w1 = new ArrayList <Integer>(),w2 = new ArrayList <Integer>();
		int wtotal = 0;
		for (int i=0; i<n; i++){
			int t = sc.nextInt(), w = sc.nextInt() ;
			wtotal += w;
			if (t==1) w1.add(w);
			else w2.add(w);
		}
		//sort
		Collections.sort(w1, Collections.reverseOrder());
		Collections.sort(w2, Collections.reverseOrder());

		int i1=0,i2 =0;
		int w=0;
		int t=0;
		while(t< wtotal- w){
			if (i1==0)	w+=w1.get(i1++);
			else if (i1==w1.size()) {
				w-=w1.get(--i1);
				w+=w2.get(i2++);
			}
			else if (i2==w2.size()){
				w+=w1.get(i1++);
			}
			else if (w-w1.get(i1-1)+w2.get(i2) > w +w1.get(i1)){
				w-=w1.get(--i1);
				w+=w2.get(i2++);
			} else w+=w1.get(i1++);
			t++; //t will increase in any case
		}
		ln(t);

	}

	public static void main(String[] args) {
		new B294().run();
	}

	//output lib
	public static void ln(){
		out.println();
	}
	public static void pr(Object obj){
		out.print(str(obj));
	}
	public static void ln(Object obj){
		pr(obj);ln();
	}
	public static String str(Object obj){
		return obj.toString();
	}
	public static <E> String str(E[] obj){
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<obj.length;i++){
			sb.append(i==0?"":" ").append(obj[i]);
		}
		return sb.toString();
	}
	public static <E> String str(List<E> obj){
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<obj.size();i++){
			sb.append(i==0?"":" ").append(obj.get(i));
		}
		return sb.toString();
	}
}


import static java.lang.System.*;
import static java.lang.Math.*;
import java.util.*;

public class B294 {
	public static Scanner sc=new Scanner(in);
	//public static Random sc=new Random();

	public static final String br=System.getProperty("line.separator");
	final int mod=1000000007;

	void run(){
		final int n=sc.nextInt();
		List <Integer>  w1 = new ArrayList <Integer>(),w2 = new ArrayList <Integer>();
		int wtotal = 0;
		for (int i=0; i<n; i++){
			int t = sc.nextInt(), w = sc.nextInt() ;
			wtotal += w;
			if (t==1) w1.add(w);
			else w2.add(w);
		}
		//sort
		Collections.sort(w1, Collections.reverseOrder());
		Collections.sort(w2, Collections.reverseOrder());

		int i1=0,i2 =0;
		int w=0;
		int t=0;
		while(t< wtotal- w){
			if (i1==0 && w1.size()>0) w+=w1.get(i1++);
			else if (i1==w1.size()) {
				if (i1>0) w-=w1.get(--i1);
				else t++;
				w+=w2.get(i2++);
			}
			else if (i2==w2.size()){
				w+=w1.get(i1++);
			}
			else if (w-w1.get(i1-1)+w2.get(i2) > w +w1.get(i1)){
				w-=w1.get(--i1);
				w+=w2.get(i2++);
			} else w+=w1.get(i1++);
			t++; //t will increase in any case
		}
		ln(t);

	}

	public static void main(String[] args) {
		new B294().run();
	}

	//output lib
	public static void ln(){
		out.println();
	}
	public static void pr(Object obj){
		out.print(str(obj));
	}
	public static void ln(Object obj){
		pr(obj);ln();
	}
	public static String str(Object obj){
		return obj.toString();
	}
	public static <E> String str(E[] obj){
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<obj.length;i++){
			sb.append(i==0?"":" ").append(obj[i]);
		}
		return sb.toString();
	}
	public static <E> String str(List<E> obj){
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<obj.size();i++){
			sb.append(i==0?"":" ").append(obj.get(i));
		}
		return sb.toString();
	}
}


import java.util.*;
import java.io.*;

public class main_class
{
	static int amount[] = new int[2];
	static int list[][] = new int[2][100];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt();
		int sum0 = 0;
		int prec = 0;
		for (int i = 1; i <= n; i++)
		{
			int t = sc.nextInt();
			amount[t - 1]++;
			list[t - 1][amount[t - 1] - 1] = sc.nextInt();;
			if (t == 1)
				sum0 += list[0][amount[0] - 1];
			else prec += list[1][amount[1] - 1];
		}
	//	for (int j = 0; j < amount[1]; j++)
	//		out.println("!" + list[1][j]);
		for (int j = 0; j <= 1; j++)
			Arrays.sort(list[j], 0, amount[j]);
		/*for (int j : list[0])
			if (j != 0)
				out.print(j + " ");
		out.println("=====");
		for (int j : list[1])
			if (j != 0)
				out.print(j + " ");*/
		//out.println("!" + list[1][1]);
		//for (int j = 0; j < amount[1]; j++)
		//	out.println("!" + list[1][j]);
		int best = 100500;
		for (int choice0 = 0; choice0 <= amount[0]; choice0++)
		{
			int sum1 = prec;
			for (int choice1 = 0; choice1 <= amount[1]; choice1++)
			{
				//out.println(choice0 + " " + choice1 + " " + sum0 + " " + sum1);
				int nnew = choice0 + choice1 * 2;
				if (nnew < best)
				{
					if (nnew >= sum0 + sum1)
						best = nnew;
				}
				//out.println("sum1 -= " + list[1][amount[1] - choice1 - 1] + " " + (amount[1] - choice1 - 1));
				if (choice1 != amount[1])
					sum1 -= list[1][amount[1] - choice1 - 1];
			}
			if (choice0 != amount[0])
				sum0 -= list[0][amount[0] - choice0 - 1];
		}
		out.println(best);
		out.close();
	}
}