#include // #include // #include // #include // #include // #include // #include // #include using namespace std; using ll = long long; using VI = vector; using VL = vector; using VD = vector; using VS = vector; using VB = vector; using VVB = vector>; using VVI = vector; using VVL = vector; using VVD = vector; using VVVI = vector; using VVVL = vector; using VVVD = vector; using PII = std::pair; using VPII = std::vector>; using PLL = std::pair; using VPLL = std::vector>; using TI3 = std::tuple; using TI4 = std::tuple; using TL3 = std::tuple; using TL4 = std::tuple; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define repr(i, n) for (int i = (int)(n)-1; i >= 0; i--) #define rep2(i, s, n) for (int i = (s); i < (int)(n); i++) #define repr2(i, g, n) for (int i = (int)(n)-1; i >= (g); i--) #define rep3(i, s, n, d) for (int i = (s); i < (int)(n); i += (d)) #define repr3(i, g, n, d) for (int i = (int)(n)-1; i >= (g); i -= (d)) #define allpt(v) (v).begin(), (v).end() #define allpt_c(v) (v).cbegin(), (v).cend() #define allpt_r(v) (v).rbegin(), (v).rend() #define allpt_cr(v) (v).crbegin(), (v).crend() const int mod1 = 1e9 + 7, mod2 = 998244353, mod3 = 1e9 + 9; const int mod = mod1; const ll inf = 1e18; const int infint = 1e9; const vector adjust = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} }; const string wsp = " "; const string tb = "\t"; const string rt = "\n"; const string alphabets = "abcdefghijklmnopqrstuvwxyz"; template void show1dvec(const vector& v) { if (v.size() == 0) return; int n = v.size() - 1; rep(i, n) cout << v[i] << wsp; cout << v[n] << rt; return; } int get1dcoodinate(int w, int i, int j) { return i * w + j; } template ostream& operator<<(ostream& os, const vector& v) { if (v.size() == 0) return os; int n = (int)v.size() - 1; rep(i, n) os << v[i] << wsp; os << v[n] << rt; return os; } template istream& operator>>(istream& is, vector& v) { if (v.size() == 0) return is; int n = v.size(); rep(i, n) is >> v[i]; return is; } template ostream& operator<<(ostream& os, const vector>& v) { if (v.size() == 0) return os; auto n = v.size(); rep(i, n) os << v[i]; return os; } template istream& operator>>(istream& is, vector>& v) { if (v.size() == 0) return is; int n = v.size(); rep(i, n) is >> v[i]; return is; } template istream& operator>>(istream& is, pair& p) { is >> p.first >> p.second; return is; } template istream& operator>>(istream& is, vector>& v) { if (v.size() == 0) return is; auto n = v.size(); rep(i, n) is >> v[i].first >> v[i].second; return is; } template ostream& operator<<(ostream& os, const vector>& v) { if (v.size() == 0) return os; auto n = v.size(); rep(i, n) os << v[i].first << wsp << v[i].second << rt; return os; } void show2dvec(const vector& v) { int n = v.size(); rep(i, n) cout << v[i] << rt; } template void show2dvec(const vector>& v) { int n = v.size(); rep(i, n) show1dvec(v[i]); } template void range_sort(vector& arr, int l, int r) { sort(arr.begin() + l, arr.begin() + r); } template void show1dpair(const vector>& v) { int n = v.size(); rep(i, n) cout << v[i].first << v[i].second << rt; return; } template void pairzip(const vector>& v, vector& t, vector& s) { int n = v.size(); rep(i, n) { t.push_back(v[i].first); s.push_back(v[i].second); } return; } template void maxvec(vector& v) { T s = v[0]; int n = v.size(); rep(i, n - 1) { if (s > v[i + 1]) { v[i + 1] = s; } s = v[i + 1]; } } template bool myfind(T t, S s) { return find(t.cbegin(), t.cend(), s) != t.cend(); } // bool check(int y, int x, int h, int w) // { // return 0 <= y && y < h && 0 <= x && x < w; // } // bool check(int y, int x, int h1, int h2, int w1, int w2) // { // return h1 <= y && y < h2&& w1 <= x && x < w2; // } bool iskadomatsu(int a, int b, int c) { return (a != b && b != c && c != a) && ((a > b && b < c) || (a < b&& b > c)); } template bool iskadomatsu(vector v) { T a = v[0], b = v[1], c = v[2]; return (a != b && b != c && c != a) && ((a > b && b < c) || (a < b&& b > c)); } double euc_dist(PII a, PII b) { return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2)); } // VS split(string s, char c) { // VS ret; // string part; // s += c; // rep(i, s.length()) { // if (s[i] == c) { // if (part != "") ret.emplace_back(part); // part = ""; // } else if (s[i] != c) { // part += s[i]; // } // } // return ret; // } VS split(string s, char c, char d = ' ') { VS ret; // reverse(allpt(s)); string part; s += c; rep(i, s.length()) { if (s[i] == c) { if (part != "") { // string t; // t += c; // ret.emplace_back(t); ret.emplace_back(part); } part = ""; } else { part += s[i]; } } return ret; } template ll pow_mod(T p, S q, R mod = 1ll) { ll ret = 1, r = p; while (q) { if (q % 2) ret *= r, ret %= mod; r = (r * r) % mod, q /= 2; } return ret % mod; } template ll pow_no_mod(T p, S q) { ll ret = 1, r = p; while (q) { if (q % 2) ret *= r; r = (r * r), q /= 2; } return ret; } void make_frac_tables(VL& frac_list, VL& frac_inv_list) { rep(i, frac_list.size() - 1) { frac_list[i + 1] *= frac_list[i] * (i + 1); frac_list[i + 1] %= mod; frac_inv_list[i + 1] *= frac_inv_list[i] * pow_mod(i + 1, mod - 2, mod); frac_inv_list[i + 1] %= mod; } } pair make_frac_tables(int n) { VL frac_list(n + 1, 1), frac_inv_list(n + 1, 1); rep(i, n) { frac_list[i + 1] *= frac_list[i] * (i + 1); frac_list[i + 1] %= mod; frac_inv_list[i + 1] *= frac_inv_list[i] * pow_mod(i + 1, mod - 2, mod); frac_inv_list[i + 1] %= mod; } return make_pair(frac_list, frac_inv_list); } ll comb(int a, int b, const VL& frac_list, const VL& frac_inv_list) { if (a < b) return 0; if (b < 0) return 0; ll ret = frac_list[a]; ret *= frac_inv_list[b]; ret %= mod; ret *= frac_inv_list[a - b]; ret %= mod; return ret; } struct vec2d { ll x; ll y; vec2d(ll _x, ll _y) { x = _x; y = _y; } ll dot(vec2d p) { return x * p.x + y * p.y; } vec2d diff(vec2d p) { return vec2d(x - p.x, y - p.y); } }; struct node { int parent = -1; ll weight = 0; int depth = -1; int degree = -1; int subtree = 1; int check = 0; int scc = -1; bool is_lca = false; bool follow_has_lca = false; VPLL children; VI parent_list; VPLL connect; node() { parent = -1; weight = 0; depth = -1; degree = -1; subtree = 1; check = 0; is_lca = false; follow_has_lca = false; children; parent_list; connect; } }; struct graph { int _n; int root = 0; vector nodes; graph(int n) { _n = n; rep(i, _n) nodes.emplace_back(node()); } void getconnect_nocost() { ll a, b; cin >> a >> b; nodes[a].connect.emplace_back(b, 1); nodes[b].connect.emplace_back(a, 1); } void getconnect() { ll a, b, c; cin >> a >> b >> c; nodes[a].connect.emplace_back(b, c); nodes[b].connect.emplace_back(a, c); } void getconnect_decri_nocost() { ll a, b; cin >> a >> b; a--, b--; nodes[a].connect.emplace_back(b, 1); nodes[b].connect.emplace_back(a, 1); } void getconnect_decri() { ll a, b, c; cin >> a >> b >> c; a--, b--; nodes[a].connect.emplace_back(b, c); nodes[b].connect.emplace_back(a, c); } void showparent() { rep(i, _n - 1) cout << nodes[i].parent << wsp; cout << nodes[_n - 1].parent << rt; } void showweight() { rep(i, _n - 1) cout << nodes[i].weight << wsp; cout << nodes[_n - 1].weight << rt; } void showsubtree() { rep(i, _n - 1) cout << nodes[i].subtree << wsp; cout << nodes[_n - 1].subtree << rt; } void showdepth() { rep(i, _n - 1) cout << nodes[i].depth << wsp; cout << nodes[_n - 1].depth << rt; } }; struct point { int x; int y; point() { x = 0; y = 0; } point(int _x, int _y) { x = _x; y = _y; } void pointinput() { int _x, _y; cin >> _x >> _y; x = _x; y = _y; } void pointinv() { swap(x, y); } }; istream& operator>>(istream& is, point& p) { is >> p.x >> p.y; return is; } ostream& operator<<(ostream& os, point& p) { os << p.x << wsp << p.y << rt; return os; } double pointseuc(point a, point b) { ll ax = a.x, bx = b.x, ay = a.y, by = b.y; return sqrt(pow(ax - bx, 2) + pow(ay - by, 2)); } ll pointseucsquare(point a, point b) { ll ax = a.x, bx = b.x, ay = a.y, by = b.y; return (ax - bx) * (ax - bx) + (ay - by) * (ay - by); } int pointsmanhattan(point a, point b) { return abs(a.x - b.x) + abs(a.y - b.y); } double dist_segment_point(TL3 segment, point p) { double a = get<0>(segment); double b = get<1>(segment); double c = get<2>(segment); return abs(a * p.x + b * p.y - c) / (a * a + b * b + c * c); } TL3 segment_parameter(point p, point q) { ll a, b, c; a = q.y - p.y; b = p.x - q.x; c = a * p.x + b * p.y; TL3 ret = (TL3){ a, b, c }; // cout << a << b << c << rt; return ret; } int cross_check(TL3 segment, point p) { ll a = get<0>(segment); ll b = get<1>(segment); ll c = get<2>(segment); auto f = a * p.x + b * p.y - c; int ret; if (f > 0) ret = 1; if (f == 0) ret = 0; if (f < 0) ret = -1; return ret; } const int INTMAX = 2 * infint; const int NMAX = 2 * 1e3; template int dfs_for_maxflow(int s, int t, T f, vector>> edge, vector& used, VB check) { int d = 0; check[s] = true; if (s == t) { used.push_back(t); return f; } for (auto next : edge[s]) { if (!check[next.first] && next.second > 0) d = dfs_for_maxflow(next.first, t, min(next.second, f), edge, used, check); if (d > 0) { used.push_back(s); return d; } // DFSが終点まで行くと正の値dが帰ってくるので、辺の容量の調整をして終了 } return 0; //そうでなければ何もしない } template void get_maxflow(vector>> edge, int w) { int a, b, f = 1, ans = 0; const int t = edge.size(); vector used(t); VB check(t, false); while (f > 0) { for (int i = 0; i < t; i++) check[i] = false; f = dfs_for_maxflow(0, t - 1, INTMAX, edge, used, check); a = -1, b = -1; for (auto i : used) { a = b; b = i; if (a >= 0 && b >= 0) { for (auto& j : edge[a]) //値の変更を伴うので参照 if (j.first == b) { j.second += f; break; } for (auto& j : edge[b]) if (j.first == a) { j.second -= f; break; } } } ans += f; used.clear(); } cout << ((ans >= w) ? "SHIROBAKO" : "BANSAKUTSUKITA") << rt; } int main() { cin.tie(0); ios::sync_with_stdio(false); // リアクティブ問題のときはコメントアウト #ifdef DEBUG cout << "DEBUG MODE" << endl; ifstream in("input.txt"); // for debug cin.rdbuf(in.rdbuf()); // for debug #endif int w, n, m, t, f, a, b, ans; cin >> w; cin >> n; VI j_list(n); rep(i, n) cin >> j_list[i]; cin >> m; VI c_list(m); rep(i, m) cin >> c_list[i]; VVI x_list(m, VI(n, 1)); rep(i, m) { cin >> a; rep(j, a) { cin >> b; x_list[i][b - 1] = 0; } } t = n + m + 2; vector edge(t); vector used; for (int i = 0; i < n; i++) { edge[0].push_back(make_pair(i + 1, j_list[i])); edge[i + 1].push_back(make_pair(0, 0)); } for (int i = 0; i < m; i++) { edge[i + n + 1].push_back(make_pair(t - 1, c_list[i])); edge[t - 1].push_back(make_pair(i + n + 1, 0)); } for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { edge[i + n + 1].push_back(make_pair(j + 1, 0)); edge[j + 1].push_back(make_pair(i + n + 1, w * x_list[i][j])); } get_maxflow(edge, w); return 0; }