//#define _GLIBCXX_DEBUG #include using namespace std; #define pb push_back #define mp make_pair typedef long long ll; typedef vector vi; typedef vector vvi; typedef vector vll; typedef pair pii; typedef vector vii; #define sz(c) (int)(c).size() #define ALL(c) (c).begin(), (c).end() void print_ans (const vvi &g) { cout << sz(g) << '\n'; for (int i = 0; i < sz(g); i++) { cout << sz(g[i]); for (int j : g[i]) cout << ' ' << j + 1; cout << '\n'; } } int T = 0; void dfs(int u, const vvi &g, vector &finished, vector &discovered, vi &in, vi &out, int &b, int &f, int &c) { in[u] = T++; discovered[u] = true; for (int v: g[u]) { if (finished[v]) { // forward edge if u was on the stack when v was discovered if (in[u] <= in[v]) --f; else --c; // cross edge otherwise continue; } if (discovered[v]) { --b; continue; } // tree edge dfs(v, g, finished, discovered, in, out, b, f, c); } finished[u] = true; out[u] = T++; } bool check_ans (const vvi &g, int t, int b, int f, int c) { assert(sz(g) == t + 1); vector fin(sz(g)), disc(sz(g)); vi in(sz(g)), out(sz(g)); T = 0; dfs(0, g, fin, disc, in, out, b, f, c); return b == 0 && f == 0 && c == 0; } void dfs_io (int v, const vvi &g, vector &used, vi &in, vi &out) { in[v] = T++; used[v] = 1; for (int dest : g[v]) if (!used[dest]) dfs_io(dest, g, used, in, out); out[v] = T++; } void solve (int n) { int b, f, c; n++; cin >> b >> f >> c; // cerr << n << ' ' << b << ' ' << f << ' ' << c << '\n'; ll total_e = (ll)n * (ll)(n - 1) / 2LL; if (total_e < b + f + c + n - 1) { cout << -1 << '\n'; return; } if (n == 1) { assert(b == 0 && f == 0 && c == 0); vvi g(1); assert(check_ans(g, n - 1, b, f, c)); print_ans(g); return; } ll cur = (ll)(n - 1) * (ll)(n - 2) / 2LL; vi par(n); vi h(n); iota(ALL(par), -1); iota(ALL(h), 0); for (int i = n - 1; i >= 1; i--) if (cur >= b + f + h[i] - 1) { par[i] = 0; cur -= h[i] - 1; h[i] = 1; } else while (cur > b + f) { --cur; assert(par[i] != -1); par[i] = par[par[i]]; assert(par[i] != -1); --h[i]; } assert(cur == b + f); vvi g(n); for (int i = 1; i < n; i++) { assert(par[i] != -1 && par[i] < i); g[par[i]].pb(i); } vi in(n), out(n); vector used(n); T = 0; dfs_io(0, g, used, in, out); int mb = b, mc = c, mf = f; // // cerr << "par : "; // copy(ALL(par), ostream_iterator(cerr, " ")); // cerr << '\n'; for (int i = 1; i < n; i++) { assert(par[i] != -1); int x = par[par[i]]; while (x != -1) { if (mb > 0) { --mb; g[i].pb(x); } else if (mf > 0) { --mf; g[x].pb(i); } x = par[x]; } } vi nin(n), nout(n); used.assign(n, 0); T = 0; dfs_io(0, g, used, nin, nout); assert(in == nin && out == nout); assert(mb == 0 && mf == 0); for (int i = 0; mc > 0 && i < n; i++) for (int j = 0; mc > 0 && j < n; j++) if (out[i] < in[j]) { g[j].pb(i); --mc; } assert(mc == 0); // if (n == 4) // for (int i = 0; i < n; i++) // { // copy(ALL(g[i]), ostream_iterator(cerr, " ")); // cerr << '\n'; // } assert(check_ans(g, n - 1, b, f, c)); print_ans(g); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n; while (cin >> n) solve(n); }