#include <bits/stdc++.h>
using namespace std;
const int maxn = 200000;
vector<int> g[maxn];
vector<pair<int, int> > edges;
vector<pair<int, int> > last_edges;
struct dsu {
  vector<int> parent;
  void init(int n) {
    parent.resize(n);
    iota(parent.begin(), parent.end(), 0);
  }
  void link(int a, int b) { parent[get(a)] = get(b); }
  int get(int a) { return a == parent[a] ? a : parent[a] = get(parent[a]); }
  int same(int a, int b) { return get(a) == get(b); }
};
set<int> reach_x;
set<int> reach_y;
set<int> only_x;
set<int> only_y;
set<int> both;
void no() {
  printf("No\n");
  exit(0);
}
bool visite[maxn];
void dfs(int x, bool s = false) {
  visite[x] = true;
  for (int y : g[x]) {
    if (!visite[y]) {
      if (s) printf("%d %d\n", x + 1, y + 1);
      dfs(y, s);
    }
  }
}
void yes() {
  memset(visite, 0, sizeof(visite));
  printf("Yes\n");
  dfs(0, true);
}
int main() {
  int n, m, x, d1, y, d2;
  scanf("%d%d", &n, &m);
  for (int i = 0, a, b; i < m; i++) {
    scanf("%d%d", &a, &b);
    edges.push_back({a - 1, b - 1});
  }
  scanf("%d%d%d%d", &x, &y, &d1, &d2);
  --x;
  --y;
  dsu ds;
  ds.init(n);
  bool between = false;
  for (auto p : edges) {
    if (p.first == x || p.first == y) swap(p.first, p.second);
    if (p.second == x || p.second == y) {
      if (p.first == x || p.first == y) {
        between = true;
      } else {
        last_edges.push_back(p);
      }
    } else {
      if (ds.same(p.first, p.second)) continue;
      g[p.first].push_back(p.second);
      g[p.second].push_back(p.first);
      ds.link(p.first, p.second);
    }
  }
  for (auto p : last_edges) {
    if (p.second == x)
      reach_x.insert(ds.get(p.first));
    else
      reach_y.insert(ds.get(p.first));
  }
  for (int i : reach_x)
    if (reach_y.count(i))
      both.insert(i);
    else
      only_x.insert(i);
  for (int i : reach_y)
    if (!reach_x.count(i)) only_y.insert(i);
  for (auto p : last_edges) {
    int u = ds.get(p.first);
    if (p.second == x) {
      if (only_x.count(u)) {
        g[x].push_back(p.first);
        g[p.first].push_back(x);
        only_x.erase(u);
      }
    } else {
      if (only_y.count(u)) {
        g[y].push_back(p.first);
        g[p.first].push_back(y);
        only_y.erase(u);
      }
    }
  }
  int rem1 = d1 - (int)g[x].size();
  int rem2 = d2 - (int)g[y].size();
  bool connected = false;
  bool need_x = true, need_y = true;
  int need_u = -1;
  if (!both.size() && !between) {
    no();
  }
  for (auto p : last_edges) {
    int u = ds.get(p.first);
    if (both.count(u)) {
      if (!connected && (need_u == -1 || u == need_u)) {
        if (need_x && need_y) {
          g[p.first].push_back(p.second);
          g[p.second].push_back(p.first);
          if (p.second == x)
            need_x = false, --rem1;
          else
            need_y = false, --rem2;
          need_u = u;
        } else {
          if (need_x) {
            if (p.second != x) continue;
            g[p.first].push_back(x);
            g[x].push_back(p.first);
            --rem1;
            connected = true;
            both.erase(u);
          } else {
            if (p.second != y) continue;
            g[p.first].push_back(y);
            g[y].push_back(p.first);
            --rem2;
            connected = true;
            both.erase(u);
          }
        }
      } else {
        if (rem1 > rem2) {
          g[x].push_back(p.first);
          g[p.first].push_back(x);
          --rem1;
          both.erase(u);
        } else {
          g[y].push_back(p.first);
          g[p.first].push_back(y);
          --rem2;
          both.erase(u);
        }
      }
    }
  }
  if (!connected && between) {
    g[x].push_back(y);
    g[y].push_back(x);
  } else if (!connected)
    no();
  if ((int)g[x].size() <= d1 && g[y].size() <= d2)
    yes();
  else
    no();
  return 0;
}
