#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
std::istream &operator>>(std::istream &i, pair<T, U> &p) {
  i >> p.first >> p.second;
  return i;
}
template <typename T>
std::istream &operator>>(std::istream &i, vector<T> &t) {
  for (auto &v : t) {
    i >> v;
  }
  return i;
}
template <typename T, typename U>
std::ostream &operator<<(std::ostream &o, const pair<T, U> &p) {
  o << p.first << ' ' << p.second;
  return o;
}
template <typename T>
std::ostream &operator<<(std::ostream &o, const vector<T> &t) {
  if (t.empty()) o << '\n';
  for (size_t i = 0; i < t.size(); ++i) {
    o << t[i] << " \n"[i == t.size() - 1];
  }
  return o;
}
template <typename T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using maxheap = priority_queue<T, vector<T>, less<T>>;
template <typename T>
bool in(T a, T b, T c) {
  return a <= b && b < c;
}
unsigned int logceil(int first) {
  return 8 * sizeof(int) - __builtin_clz(first);
}
namespace std {
template <typename T, typename U>
struct hash<pair<T, U>> {
  hash<T> t;
  hash<U> u;
  size_t operator()(const pair<T, U> &p) const {
    return t(p.first) ^ (u(p.second) << 7);
  }
};
}  // namespace std
template <typename T, typename F>
T bsh(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      l = m + 1;
      r = m;
    } else {
      h = m - 1;
    }
  }
  return r;
}
template <typename F>
double bshd(double l, double h, const F &f, double p = 1e-9) {
  unsigned int r = 3 + (unsigned int)log2((h - l) / p);
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      l = m;
    } else {
      h = m;
    }
  }
  return (l + h) / 2;
}
template <typename T, typename F>
T bsl(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      h = m - 1;
      r = m;
    } else {
      l = m + 1;
    }
  }
  return r;
}
template <typename F>
double bsld(double l, double h, const F &f, double p = 1e-9) {
  unsigned int r = 3 + (unsigned int)log2((h - l) / p);
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      h = m;
    } else {
      l = m;
    }
  }
  return (l + h) / 2;
}
template <typename T>
T gcd(T a, T b) {
  if (a < b) swap(a, b);
  return b ? gcd(b, a % b) : a;
}
template <typename T>
class vector2 : public vector<vector<T>> {
 public:
  vector2() {}
  vector2(size_t a, size_t b, T t = T())
      : vector<vector<T>>(a, vector<T>(b, t)) {}
};
template <typename T>
class vector3 : public vector<vector2<T>> {
 public:
  vector3() {}
  vector3(size_t a, size_t b, size_t c, T t = T())
      : vector<vector2<T>>(a, vector2<T>(b, c, t)) {}
};
template <typename T>
class vector4 : public vector<vector3<T>> {
 public:
  vector4() {}
  vector4(size_t a, size_t b, size_t c, size_t d, T t = T())
      : vector<vector3<T>>(a, vector3<T>(b, c, d, t)) {}
};
template <typename T>
class vector5 : public vector<vector4<T>> {
 public:
  vector5() {}
  vector5(size_t a, size_t b, size_t c, size_t d, size_t e, T t = T())
      : vector<vector4<T>>(a, vector4<T>(b, c, d, e, t)) {}
};
template <typename T>
struct bounded_priority_queue {
  inline bounded_priority_queue(unsigned int X) : A(X), B(0), s(0) {}
  inline void push(unsigned int L, T V) {
    B = max(B, L);
    A[L].push(V);
    ++s;
  }
  inline const T &top() const { return A[B].front(); }
  inline void pop() {
    --s;
    A[B].pop();
    while (B > 0 && A[B].empty()) --B;
  }
  inline bool empty() const { return A[B].empty(); }
  inline void clear() {
    s = B = 0;
    for (auto &a : A) a = queue<T>();
  }
  inline unsigned int size() const { return s; }

 private:
  vector<queue<T>> A;
  unsigned int B;
  int s;
};
class TaskD {
 public:
  struct State {
    int guysShot;
    int loadingTimeDone;
    int backLoaded, backLane;
  };
  vector3<State> DP;
  void put(int first, int isLoaded, int lane, State state) {
    auto &d = DP[first][isLoaded][lane];
    if (state.guysShot > d.guysShot ||
        (state.guysShot == d.guysShot &&
         state.loadingTimeDone > d.loadingTimeDone)) {
      d = state;
    }
  }
  void solve(istream &cin, ostream &cout) {
    int N, M1, M2, T;
    cin >> N >> M1 >> M2 >> T;
    map<int, pair<bool, bool>> S;
    S[0] = S[N + 1] = {false, false};
    vector<vector<int>> OBST(2);
    {
      OBST[0].resize(M1);
      OBST[1].resize(M2);
      cin >> OBST;
      for (int q : OBST[0]) S[q].first = true;
      for (int r : OBST[1]) S[r].second = true;
    }
    vector<int> X(S.size());
    vector2<bool> C(S.size(), 2);
    int i = 0;
    for (auto s : S) {
      X[i] = s.first;
      C[i][0] = s.second.first;
      C[i][1] = s.second.second;
      ++i;
    }
    S.clear();
    int Z = X.size();
    DP = vector3<State>(Z, 2, 2, {-1, -1, -1, -1});
    DP[0][0][0] = {0, 0, -1, -1};
    for (int first = 1; first < X.size(); ++first) {
      for (int wasLoaded = 0; wasLoaded <= 1; ++wasLoaded) {
        for (int wasLane = 0; wasLane <= 1; ++wasLane) {
          bool meHasObst = C[first][wasLane];
          bool otherHasObst = C[first][!wasLane];
          bool hadObst = C[first - 1][wasLane];
          bool otherHadObst = C[first - 1][!wasLane];
          auto &d = DP[first - 1][wasLoaded][wasLane];
          if (d.guysShot == -1) continue;
          {
            int time = d.loadingTimeDone + (X[first] - X[first - 1]);
            int g = d.guysShot + time / T - meHasObst;
            if (g > 0 && time >= T)
              put(first, 1, wasLane, {g - 1, T, wasLoaded, wasLane});
            if (g >= 0 && time % T + g >= meHasObst)
              put(first, 0, wasLane, {g, time % T, wasLoaded, wasLane});
          }
          if (X[first] - X[first - 1] == 1 && (otherHasObst || meHasObst) &&
              otherHadObst) {
            continue;
          }
          {
            int time = d.loadingTimeDone + (X[first] - X[first - 1]);
            if (otherHadObst && d.loadingTimeDone == T) --time;
            int g = time / T - otherHasObst;
            if (g > 0 && time >= T)
              put(first, 1, 1 - wasLane, {g - 1, T, wasLoaded, wasLane});
            if (g >= 0 && time % T + g >= otherHasObst)
              put(first, 0, 1 - wasLane, {g, time % T, wasLoaded, wasLane});
          }
        }
      }
    }
    for (int loaded = 0; loaded <= 1; ++loaded) {
      for (int lane = 0; lane <= 1; ++lane) {
        if (DP[Z - 1][loaded][lane].guysShot != -1) {
          cout << "Yes\n";
          vector<int> SW;
          vector<vector<int>> S(2);
          for (int first = Z - 1; first >= 1; --first) {
            bool laneSwitch = lane != DP[first][loaded][lane].backLane;
            bool canShootImmediately = true;
            if (laneSwitch) {
              bool meHadObst = C[first - 1][lane];
              canShootImmediately = !meHadObst;
              SW.push_back(X[first - 1] + meHadObst);
            }
            int r = DP[first][loaded][lane].backLane;
            int s = DP[first][loaded][lane].backLoaded;
            auto &d = DP[first - 1][s][r];
            int time = d.loadingTimeDone;
            if (!canShootImmediately && time == T) --time;
            for (int pos = X[first - 1] - time + T;
                 pos <= X[first] - DP[first][loaded][lane].loadingTimeDone;
                 pos += T) {
              if (OBST[lane].empty() ||
                  OBST[lane].back() <= X[first - 1] - time + T)
                break;
              S[lane].push_back(pos);
              OBST[lane].pop_back();
            }
            loaded = s;
            lane = r;
          }
          vector<std::pair<int, int>> SH;
          for (int s : S[0]) SH.push_back({s, 1});
          for (int s : S[1]) SH.push_back({s, 2});
          sort(SH.begin(), SH.end());
          reverse(SW.begin(), SW.end());
          cout << SW.size() << endl;
          cout << SW;
          cout << SH.size() << endl;
          for (std::pair<int, int> sh : SH) cout << sh << '\n';
          return;
        }
      }
    }
    cout << "No\n";
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  TaskD solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}
