#include #include #include #include #include #include using namespace std; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; #define rep(i,n) for(int i=0; i<(int)(n); i++) const i64 INF = 1001001001001001001; using modint = atcoder::static_modint<1000000007>; int main(){ int N; cin >> N; int M; cin >> M; int K; cin >> K; int P; cin >> P; int nodeIdxSrc = 0; int nodeIdxN = nodeIdxSrc + 1; int nodeIdxM = nodeIdxN + N; int nodeIdxK = nodeIdxM + M; int nodeIdxSnk = nodeIdxK + K; atcoder::mf_graph G(nodeIdxSnk + 1); i64 offset = 0; rep(i,N){ int a; cin >> a; G.add_edge(nodeIdxSrc, nodeIdxN+i, a); offset += a; } rep(i,M){ int a; cin >> a; G.add_edge(nodeIdxM+i, nodeIdxSnk, a); offset += a; } rep(i,K){ int a; cin >> a; G.add_edge(nodeIdxK+i, nodeIdxSnk, a); } rep(i,N){ int L; cin >> L; rep(j,L){ int k; cin >> k; k--; G.add_edge(nodeIdxN+i, nodeIdxK+k, INF); } } rep(i,P){ int n; cin >> n; n--; int m; cin >> m; m--; G.add_edge(nodeIdxN+n, nodeIdxM+m, INF); } i64 ans = offset - G.flow(nodeIdxSrc, nodeIdxSnk); auto cut = G.min_cut(nodeIdxSrc); cout << ans << '\n'; vector ansarr; rep(i,K) if(cut[nodeIdxK+i]) ansarr.push_back("Preparation " + to_string(i+1)); rep(i,N) if(cut[nodeIdxN+i]) ansarr.push_back("Goal " + to_string(i+1)); rep(i,M) if(!cut[nodeIdxM+i]) ansarr.push_back("Action " + to_string(i+1)); cout << ansarr.size() << '\n'; for(auto& a : ansarr) cout << a << '\n'; return 0; } struct ios_do_not_sync{ ios_do_not_sync(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); } } ios_do_not_sync_instance;