#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& _p) {
  return os << "(" << _p.first << "," << _p.second << ")";
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& _V) {
  bool f = true;
  os << "[";
  for (auto v : _V) {
    os << (f ? "" : ",") << v;
    f = false;
  }
  return os << "]";
}
template <typename T>
ostream& operator<<(ostream& os, const set<T>& _S) {
  bool f = true;
  os << "(";
  for (auto s : _S) {
    os << (f ? "" : ",") << s;
    f = false;
  }
  return os << ")";
}
template <typename T, typename U>
ostream& operator<<(ostream& os, const map<T, U>& _M) {
  return os << set<pair<T, U>>(_M.begin(), _M.end());
}
const signed long long INF = 1000000100;
const long double EPS = 1e-9;
const int MAXN = 100100;
vector<int> G[MAXN];
int N, M;
int first, second;
void read_data() {
  scanf("%d %d %d %d", &N, &M, &first, &second);
  for (int(i) = (1); (i) <= (M); (i)++) {
    int a, b;
    scanf("%d %d", &a, &b);
    G[a].push_back(b);
    G[b].push_back(a);
  }
}
void solve() {
  vector<int> RX, RY, RZ;
  const int LIMIT = first + second + 10;
  for (int(i) = (1); (i) <= (N); (i)++) sort(G[i].begin(), G[i].end());
  for (int(x) = (1); (x) <= (N); (x)++)
    for (int y : G[x]) {
      if (int(G[x].size()) <= first or int(G[y].size()) <= second) continue;
      RX.clear();
      RY.clear();
      RZ.clear();
      const vector<int>& L = G[x];
      const vector<int>& R = G[y];
      int SIZEL = min(int(L.size()), LIMIT);
      int SIZER = min(int(R.size()), LIMIT);
      int i = 0;
      int j = 0;
      while (i != SIZEL or j != SIZER) {
        if (i == SIZEL or (i != SIZEL and j != SIZER and L[i] > R[j])) {
          RY.push_back(R[j]);
          ++j;
          if (RY.back() == x) RY.pop_back();
        } else if (j == SIZER or (i != SIZEL and j != SIZER and L[i] < R[j])) {
          RX.push_back(L[i]);
          ++i;
          if (RX.back() == y) RX.pop_back();
        } else if (L[i] == R[j]) {
          RZ.push_back(L[i]);
          ++i;
          ++j;
        }
      }
      if (int(RX.size()) > first) RX.resize(first);
      if (int(RY.size()) > second) RY.resize(second);
      int needed = (first - int(RX.size())) + (second - int(RY.size()));
      if (int(RZ.size()) >= needed) {
        RZ.resize(needed);
        printf("YES\n%d %d\n", x, y);
        for (int r : RZ) {
          if (int(RX.size()) < first)
            RX.push_back(r);
          else
            RY.push_back(r);
        }
        for (int rx : RX) printf("%d ", rx);
        printf("\n");
        for (int ry : RY) printf("%d ", ry);
        printf("\n");
        return;
      }
    }
  printf("NO\n");
}
int main() {
  read_data();
  solve();
}
