#include #include using namespace std; const long long INF = 1000000000000000; int main(){ int N, M, K, P; cin >> N >> M >> K >> P; long long sum = 0; atcoder::mf_graph G(N + M + K + 2); for (int i = 0; i < N; i++){ int E; cin >> E; sum += E; G.add_edge(i, N + M + K + 1, E); } for (int i = 0; i < M; i++){ int F; cin >> F; sum += F; G.add_edge(N + M + K, N + i, F); } for (int i = 0; i < K; i++){ int V; cin >> V; G.add_edge(N + M + K, N + M + i, V); } for (int i = 0; i < N; i++){ int L; cin >> L; for (int j = 0; j < L; j++){ int A; cin >> A; A--; G.add_edge(N + M + A, i, INF); } } for (int i = 0; i < P; i++){ int I, J; cin >> I >> J; I--; J--; G.add_edge(I, N + J, INF); G.add_edge(N + J, I, INF); } long long F = G.flow(N + M + K, N + M + K + 1); long long C = sum - F; assert(C >= 0); vector used = G.min_cut(N + M + K); vector ans; for (int i = N + M; i < N + M + K; i++){ if (!used[i]){ ans.push_back(i); } } for (int i = N; i < N + M; i++){ if (used[i]){ ans.push_back(i); } } for (int i = 0; i < N; i++){ if (!used[i]){ ans.push_back(i); } } int T = ans.size(); cout << C << endl; cout << T << endl; for (int i = 0; i < T; i++){ if (ans[i] < N){ cout << "Goal " << ans[i] + 1 << endl; } else if (ans[i] < N + M){ cout << "Action " << ans[i] - N + 1 << endl; } else { cout << "Preparation " << ans[i] - N - M + 1 << endl; } } }