#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100005;
vector<int> tree[N];
struct node {
  int l, r;
} mem[N * 2];
int ansl[N], L, ansr[N], R;
int vt[N], V;
int main() {
  int n, m, h, t;
  while (cin >> n >> m >> h >> t) {
    for (int i = 1; i <= n; ++i) tree[i].clear();
    for (int i = 0; i < m; ++i) {
      scanf("%d %d", &mem[i].l, &mem[i].r);
      mem[i + m].l = mem[i].r;
      mem[i + m].r = mem[i].l;
    }
    for (int i = 0; i < 2 * m; ++i) {
      tree[mem[i].l].push_back(mem[i].r);
    }
    for (int i = 1; i <= n; ++i) sort(tree[i].begin(), tree[i].end());
    int l = -1, r = -1;
    bool flag = false;
    for (int i = 0; i < 2 * m; ++i) {
      l = mem[i].l;
      r = mem[i].r;
      int ln = tree[l].size();
      int rn = tree[r].size();
      if (ln > h && rn > t) {
        L = 0;
        R = 0;
        V = 0;
        for (int i = 0, j = 0; i < ln || j < rn;) {
          if (i < ln && j < rn && tree[l][i] == tree[r][j]) {
            vt[V++] = tree[l][i];
            ++i;
            ++j;
            continue;
          }
          if (j >= rn || (i < ln && tree[l][i] < tree[r][j])) {
            if (tree[l][i] != r) ansl[L++] = tree[l][i];
            ++i;
          } else {
            if (tree[r][j] != l) ansr[R++] = tree[r][j];
            ++j;
          }
        }
        while (L < h && V) ansl[L++] = vt[--V];
        while (R < t && V) ansr[R++] = vt[--V];
        if (L >= h && R >= t) {
          flag = true;
          break;
        }
      }
    }
    if (!flag) {
      printf("NO\n");
      continue;
    } else {
      printf("YES\n");
      printf("%d %d\n", l, r);
      for (int i = 0; i < h; ++i) {
        if (i) printf(" ");
        printf("%d", ansl[i]);
      }
      printf("\n");
      for (int i = 0; i < t; ++i) {
        if (i) printf(" ");
        printf("%d", ansr[i]);
      }
      printf("\n");
    }
  }
  return 0;
}
