#include <bits/stdc++.h>
using namespace std;
bool solve(vector<int> &Com, vector<int> &v1, vector<int> &v2, int h, int t,
           int node1, int node2) {
  set<int> com;
  for (auto node : Com) com.insert(node);
  vector<int> solmn, solmx;
  if ((int)v1.size() < (int)v2.size()) swap(v1, v2), swap(node1, node2);
  for (auto node : v2)
    if (!com.count(node) && node != node1 && node != node2 &&
        (int)solmn.size() < min(h, t))
      solmn.push_back(node);
  for (auto node : v1)
    if (!com.count(node) && node != node1 && node != node2 &&
        (int)solmx.size() < max(t, h))
      solmx.push_back(node);
  while ((int)solmn.size() < min(t, h) && (int)com.size()) {
    auto beg = com.begin();
    solmn.push_back(*beg);
    com.erase(beg);
  }
  for (auto node : com)
    if ((int)solmx.size() < max(t, h)) solmx.push_back(node);
  if ((int)solmn.size() == h && (int)solmx.size() == t) {
    puts("YES");
    printf("%d %d\n", node2 + 1, node1 + 1);
    for (auto sol : solmn) printf("%d ", sol + 1);
    puts("");
    for (auto sol : solmx) printf("%d ", sol + 1);
    return true;
  } else if ((int)solmn.size() == t && (int)solmx.size() == h) {
    puts("YES");
    printf("%d %d\n", node1 + 1, node2 + 1);
    for (auto sol : solmx) printf("%d ", sol + 1);
    puts("");
    for (auto sol : solmn) printf("%d ", sol + 1);
    return true;
  }
  return false;
}
bool solve2(vector<int> &v1, vector<int> &v2, int node1, int node2, int h,
            int t) {
  vector<int> sol1, sol2;
  if (h < t) {
    for (auto node : v1) {
      if ((int)sol1.size() == h) break;
      if (node != node1 && node != node2) sol1.push_back(node);
    }
    for (auto node : v2) {
      if ((int)sol2.size() == t) break;
      if (node == node1 || node == node2) continue;
      auto lower = lower_bound(sol1.begin(), sol1.end(), node);
      if (lower == sol1.end() || *lower != node) sol2.push_back(node);
    }
    if ((int)sol1.size() == h && (int)sol2.size() == t) {
      printf("%d %d\n", node1 + 1, node2 + 1);
      for (auto node : sol1) printf("%d ", node + 1);
      puts("");
      for (auto node : sol2) printf("%d ", node + 1);
      return true;
    }
  } else if (h >= t) {
    for (auto node : v1) {
      if ((int)sol1.size() == t) break;
      if (node != node1 && node != node2) sol1.push_back(node);
    }
    for (auto node : v2) {
      if ((int)sol2.size() == h) break;
      if (node == node1 || node == node2) continue;
      auto lower = lower_bound(sol1.begin(), sol1.end(), node);
      if (lower == sol1.end() || *lower != node) sol2.push_back(node);
    }
    if ((int)sol1.size() == t && (int)sol2.size() == h) {
      printf("%d %d\n", node2 + 1, node1 + 1);
      for (auto node : sol2) printf("%d ", node + 1);
      puts("");
      for (auto node : sol1) printf("%d ", node + 1);
      return true;
    }
  }
  return false;
}
int main() {
  int n, m, h, t;
  scanf("%d %d %d %d", &n, &m, &h, &t);
  vector<pair<int, int> > roads(m);
  vector<int> adj[n];
  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    x--, y--;
    roads[i] = {x, y};
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
  for (int i = 0; i < n; i++) sort(adj[i].begin(), adj[i].end());
  for (auto road : roads) {
    if ((int)adj[road.first].size() + (int)adj[road.second].size() - 2 <
            t + h ||
        min((int)adj[road.first].size(), (int)adj[road.second].size()) - 1 <
            min(t, h) ||
        max((int)adj[road.first].size(), (int)adj[road.second].size()) - 1 <
            max(t, h))
      continue;
    if (max((int)adj[road.first].size(), (int)adj[road.second].size()) - 1 >=
            h + t &&
        min((int)adj[road.first].size(), (int)adj[road.second].size()) - 1 >=
            min(h, t)) {
      puts("YES");
      if (!solve2(adj[road.first], adj[road.second], road.first, road.second, h,
                  t))
        solve2(adj[road.second], adj[road.first], road.second, road.first, h,
               t);
      return 0;
    } else {
      vector<int> com;
      if ((int)adj[road.first].size() < (int)adj[road.second].size())
        for (auto node : adj[road.first]) {
          auto tmp = lower_bound(adj[road.second].begin(),
                                 adj[road.second].end(), node);
          if (tmp != adj[road.second].end() && *tmp == node)
            com.push_back(node);
        }
      else
        for (auto node : adj[road.second]) {
          auto tmp =
              lower_bound(adj[road.first].begin(), adj[road.first].end(), node);
          if (tmp != adj[road.first].end() && *tmp == node) com.push_back(node);
        }
      if ((int)adj[road.first].size() - (int)com.size() +
              (int)adj[road.second].size() - 2 >=
          t + h) {
        solve(com, adj[road.first], adj[road.second], h, t, road.first,
              road.second);
        return 0;
      }
    }
  }
  puts("NO");
  return 0;
}
