#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> graph;
vector<int> sortedEdge;
vector<pair<int, int>> edge;
int n, m, h, t;
bool comp(int a, int b) {
  return graph[edge[a].first].size() + graph[edge[a].second].size() >
         graph[edge[b].first].size() + graph[edge[b].second].size();
}
void init() {
  cin >> n >> m >> h >> t;
  graph.resize(n + 1);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    graph[x].push_back(y);
    graph[y].push_back(x);
    edge.push_back(make_pair(x, y));
    sortedEdge.push_back(i);
  }
  sort(sortedEdge.begin(), sortedEdge.begin() + m, comp);
  return;
}
int main() {
  init();
  for (int i = 0;
       i < m && graph[edge[sortedEdge[i]].first].size() +
                        graph[edge[sortedEdge[i]].second].size() - 2 >=
                    h + t;
       i++) {
    int x = edge[sortedEdge[i]].first;
    int y = edge[sortedEdge[i]].second;
    if ((graph[x].size() > t && graph[y].size() > h) ||
        (graph[x].size() > h && graph[y].size() > t)) {
      vector<bool> hasFirst(n + 1);
      vector<bool> hasSame(n + 1);
      queue<int> same;
      for (int k = 0; k < graph[x].size(); k++) hasFirst[graph[x][k]] = true;
      for (int k = 0; k < graph[y].size(); k++) {
        if (hasFirst[graph[y][k]]) {
          hasSame[graph[y][k]] = true;
          same.push(graph[y][k]);
        }
      }
      if ((graph[x].size() + graph[y].size() - 2 - same.size()) >= h + t) {
        int u, v;
        if ((h > t && graph[x].size() > graph[y].size()) ||
            (h < t && graph[x].size() < graph[y].size())) {
          u = x;
          v = y;
        } else {
          u = y;
          v = x;
        }
        cout << "YES" << endl << u << " " << v << endl;
        int tmpn = 0;
        for (int k = 0; tmpn < h && k < graph[u].size(); k++) {
          if (!hasSame[graph[u][k]] && graph[u][k] != v) {
            cout << graph[u][k] << " ";
            tmpn++;
          }
        }
        while (tmpn < h && !same.empty()) {
          cout << same.front() << " ";
          same.pop();
          tmpn++;
        }
        cout << endl;
        tmpn = 0;
        for (int k = 0; tmpn < t && k < graph[v].size(); k++) {
          if (!hasSame[graph[v][k]] && graph[v][k] != u) {
            cout << graph[v][k] << " ";
            tmpn++;
          }
        }
        while (tmpn < t && !same.empty()) {
          cout << same.front() << " ";
          same.pop();
          tmpn++;
        }
        cout << endl;
        return 0;
      }
    }
  }
  cout << "NO" << endl;
  return 0;
}
