#include <bits/stdc++.h>
using namespace std;
vector<int> Edge[100011];
int check(int I, int J) {
  int sz1 = Edge[I].size();
  int sz2 = Edge[J].size();
  int ptr1 = 0;
  int ptr2 = 0;
  int X = 0;
  while (1) {
    if (ptr1 == sz1 || ptr2 == sz2) return X;
    int v1 = Edge[I][ptr1];
    int v2 = Edge[J][ptr2];
    if (v1 == v2) X++;
    if (v1 < v2)
      ptr1++;
    else
      ptr2++;
  }
}
bool isxtra[100004];
int check2(int I, int J) {
  memset(isxtra, false, sizeof isxtra);
  int sz1 = Edge[I].size();
  int sz2 = Edge[J].size();
  int ptr1 = 0;
  int ptr2 = 0;
  int X = 0;
  while (1) {
    if (ptr1 == sz1 || ptr2 == sz2) return X;
    int v1 = Edge[I][ptr1];
    int v2 = Edge[J][ptr2];
    if (v1 == v2) isxtra[v1] = true;
    if (v1 < v2)
      ptr1++;
    else
      ptr2++;
  }
}
bool comp(int i, int j) { return (i < j); }
int main() {
  int n, m, h, t;
  int x, y;
  cin >> n >> m >> h >> t;
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    Edge[x].push_back(y);
    Edge[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) sort(Edge[i].begin(), Edge[i].end(), comp);
  for (int i = 1; i <= n; i++) {
    int sz = Edge[i].size();
    for (int j = 0; j < sz; j++) {
      int u = Edge[i][j];
      if (sz < t || Edge[u].size() < h) continue;
      int xtra = check(i, u);
      if ((Edge[u].size() >= h + 1 && sz >= t + 1 &&
           (sz + Edge[u].size() - 2 - xtra) >= h + t)) {
        cout << "YES" << endl;
        check2(u, i);
        bool mark[100003];
        memset(mark, false, sizeof mark);
        cout << u << " " << i << endl;
        int cnt = 0;
        for (int k = 0; k < Edge[u].size(); k++) {
          if (cnt == h) break;
          if (Edge[u][k] != i && !isxtra[Edge[u][k]]) {
            cout << Edge[u][k] << " ";
            cnt++;
          }
        }
        for (int k = 0; k < Edge[u].size(); k++) {
          if (cnt == h) break;
          if (Edge[u][k] != i && isxtra[Edge[u][k]]) {
            cout << Edge[u][k] << " ";
            cnt++;
            isxtra[Edge[u][k]] = false;
            mark[Edge[u][k]] = true;
          }
        }
        cout << endl;
        cnt = 0;
        for (int k = 0; k < Edge[i].size(); k++) {
          if (cnt == t) break;
          if (Edge[i][k] != u && !mark[Edge[i][k]]) {
            cout << Edge[i][k] << " ";
            cnt++;
          }
        }
        cout << endl;
        return 0;
      }
    }
  }
  cout << "NO" << endl;
  return 0;
}
