#include <bits/stdc++.h>
using namespace std;
const int N = 8e5 * 2 + 50;
vector<int> g[N], gt[N];
int used[N], comp[N];
vector<int> order;
vector<int> result;
int nodes;
void add_edge(int v1, int v2) {
  g[v1].push_back(v2);
  gt[v2].push_back(v1);
}
void add_disjunction(int v1, int v2) {
  add_edge(v1 ^ 1, v2);
  add_edge(v2 ^ 1, v1);
}
void dfs1(int v) {
  if (used[v]) return;
  used[v] = 1;
  for (auto u : g[v]) dfs1(u);
  order.push_back(v);
}
void dfs2(int v, int cc) {
  if (comp[v]) return;
  comp[v] = cc;
  for (auto u : gt[v]) dfs2(u, cc);
}
bool solve2SAT() {
  for (int i = 0; i < nodes * 2; i++) dfs1(i);
  reverse(order.begin(), order.end());
  int cc = 0;
  for (auto x : order) {
    if (comp[x] == 0) {
      cc++;
      dfs2(x, cc);
    }
  }
  for (int i = 0; i < nodes; i++) {
    if (comp[i * 2] == comp[i * 2 + 1])
      return false;
    else if (comp[i * 2] > comp[i * 2 + 1])
      result.push_back(i);
  }
  return true;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, p, M, m;
  cin >> n >> p >> M >> m;
  M++;
  nodes = p + M - 1;
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    add_disjunction(x * 2, y * 2);
  }
  for (int i = 0; i < p; i++) {
    int l, r;
    cin >> l >> r;
    --l, r--;
    int u = l + p;
    int v = r + p + 1;
    add_disjunction(u * 2, 2 * i + 1);
    if (r + 1 != M) add_disjunction(2 * v + 1, 2 * i + 1);
  }
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    --u, --v;
    add_disjunction(2 * u + 1, 2 * v + 1);
  }
  for (int i = 0; i + 1 < M; i++) {
    int u = i + p;
    int v = u + 1;
    add_disjunction(u * 2, v * 2 + 1);
  }
  if (!solve2SAT()) {
    cout << "-1";
    return 0;
  }
  int k = 1;
  vector<int> st;
  for (auto u : result) {
    if (u < p)
      st.push_back(u);
    else
      k = max(k, u - p + 1);
  }
  cout << st.size() << " " << k << endl;
  ;
  for (auto u : st) cout << u + 1 << " ";
  return 0;
}
