#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:64000000")
struct edge {
  int from, to;
  edge() {}
  edge(int f, int t) : from(f), to(t) {}
};
int n, m;
int h, t;
vector<int> *v;
edge e[100005];
int main() {
  v = new vector<int>[100005];
  scanf("%d %d %d %d", &n, &m, &h, &t);
  for (int i = 0; i < m; i++) {
    scanf("%d %d", &e[i].from, &e[i].to);
    v[e[i].from].push_back(e[i].to);
    v[e[i].to].push_back(e[i].from);
  }
  for (int i = 1; i <= n; i++) sort(v[i].begin(), v[i].end());
  for (int i = 0; i < m; i++) {
    int gen = 0;
    int l = 0;
    if (v[e[i].from].size() / v[e[i].to].size() > 9 ||
        v[e[i].to].size() / v[e[i].from].size() > 9) {
      int f = e[i].from;
      int s = e[i].to;
      if (v[f].size() < v[s].size())
        ;
      else
        swap(f, s);
      vector<int>::iterator it = v[s].begin();
      for (int j = 0; j < v[f].size(); j++) {
        it = lower_bound(it, v[s].end(), v[f][j]);
        if (it == v[s].end())
          break;
        else if ((*it) == v[f][j])
          gen++;
      }
    } else {
      for (int j = 0; j < v[e[i].from].size(); j++) {
        while (l < v[e[i].to].size() && v[e[i].to][l] < v[e[i].from][j]) l++;
        if (l < v[e[i].to].size() && v[e[i].to][l] == v[e[i].from][j]) {
          gen++;
          l++;
        }
      }
    }
    int free_from = v[e[i].from].size() - 1 - gen;
    int free_to = v[e[i].to].size() - 1 - gen;
    bool ok = true;
    int need_h = free_from - h;
    int gen_h = 0;
    if (need_h < 0) gen_h = -need_h;
    if (gen_h > gen) ok = false;
    int rest_gen = gen - gen_h;
    int need_t = free_to - t;
    int gen_t = 0;
    if (need_t < 0) gen_t = -need_t;
    if (gen_t > rest_gen) ok = false;
    if (!ok) {
      swap(e[i].from, e[i].to);
      ok = true;
      free_from = v[e[i].from].size() - 1 - gen;
      free_to = v[e[i].to].size() - 1 - gen;
      need_h = free_from - h;
      gen_h = 0;
      if (need_h < 0) gen_h = -need_h;
      if (gen_h > gen) ok = false;
      rest_gen = gen - gen_h;
      need_t = free_to - t;
      gen_t = 0;
      if (need_t < 0) gen_t = -need_t;
      if (gen_t > rest_gen) ok = false;
    }
    if (!ok) continue;
    cout << "YES" << endl;
    cout << e[i].from << " " << e[i].to << endl;
    set<int> used;
    used.insert(e[i].from);
    used.insert(e[i].to);
    set<int> general;
    l = 0;
    gen = 0;
    if (v[e[i].from].size() / v[e[i].to].size() > 9 ||
        v[e[i].to].size() / v[e[i].from].size() > 9) {
      int f = e[i].from;
      int s = e[i].to;
      if (v[f].size() < v[s].size())
        ;
      else
        swap(f, s);
      vector<int>::iterator it = v[s].begin();
      for (int j = 0; j < v[f].size(); j++) {
        it = lower_bound(it, v[s].end(), v[f][j]);
        if (it == v[s].end())
          break;
        else if ((*it) == v[f][j])
          general.insert(v[f][j]);
      }
    } else {
      for (int j = 0; j < v[e[i].from].size(); j++) {
        while (l < v[e[i].to].size() && v[e[i].to][l] < v[e[i].from][j]) l++;
        if (l < v[e[i].to].size() && v[e[i].to][l] == v[e[i].from][j]) {
          general.insert(v[e[i].from][j]);
          l++;
        }
      }
    }
    for (int j = 0; j < v[e[i].from].size() && h; j++) {
      int vert = v[e[i].from][j];
      if (vert == e[i].from || vert == e[i].to ||
          general.find(vert) != general.end())
        continue;
      cout << vert << " ";
      h--;
      used.insert(vert);
    }
    for (int j = 0; j < v[e[i].from].size() && h; j++) {
      int vert = v[e[i].from][j];
      if (vert == e[i].from || vert == e[i].to || used.find(vert) != used.end())
        continue;
      cout << vert << " ";
      h--;
      used.insert(vert);
    }
    cout << endl;
    for (int j = 0; j < v[e[i].to].size() && t; j++) {
      int vert = v[e[i].to][j];
      if (used.find(vert) != used.end()) continue;
      t--;
      cout << vert << " ";
    }
    cout << endl;
    return 0;
  }
  cout << "NO" << endl;
  return 0;
}
