#include using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef vector vi; const int MAXN = 100001; int n; const int k = 4; vi berry; int score(int i){ int res = 0; rep(c1,0,k){ if(c1+i < n)res += berry[c1+i]; } return res; } vi positions; vi pos_to_i, i_grundy; vector intervals; set grundy_i; map grundy_map; vi get_left(vi &pos, int i){ vi res; rep(c1,0,i){ if(pos[c1] <= pos[i]-k)res.push_back(pos[c1]); } return res; } vi get_right(vi &pos, int i){ vi res; rep(c1,i+1,sz(pos)){ if(pos[c1] >= pos[i]+k)res.push_back(pos[c1]); } return res; } int grundy(vi pos){ if(sz(pos) == 0)return 0; /* for(int c1 = sz(pos)-1; c1 >= 0; c1--){ pos[c1] -= pos[0]; } */ if(grundy_map.find(pos) != grundy_map.end())return grundy_map[pos]; vi seen(sz(pos)+1, 0); rep(c1,0,sz(pos)){ vi L = get_left(pos, c1); vi R = get_right(pos, c1); int temp = (grundy(L)^grundy(R)); if(temp <= sz(pos))seen[temp] = 1; } int mex = sz(pos)+1; rep(c1,0,sz(pos)+1){ if(seen[c1] == 0){ mex = c1; break; } } grundy_map[pos] = mex; return mex; } int xo = 0; int turn = 0; void add_interval(vi pos){ if(sz(pos) == 0)return; intervals.push_back(pos); trav(y, pos){ pos_to_i[y] = sz(intervals)-1; } i_grundy.push_back(grundy(pos)); grundy_i.insert({i_grundy.back(), sz(intervals)-1}); xo ^= i_grundy.back(); } void make_move(int i){ int interval = pos_to_i[i]; assert(interval != -1); int j = -1; grundy_i.erase({i_grundy[interval], interval}); rep(c1,0,sz(intervals[interval])){ if(intervals[interval][c1] == i){ j = c1; } } int old_xo = xo; assert(j != -1); vi L = get_left(intervals[interval], j); vi R = get_right(intervals[interval], j); xo ^= i_grundy[interval]; add_interval(L); add_interval(R); rep(c1,0,k){ berry[i+c1] = 0; } } int find_interval_with_grundy(int g){ pii p = {g, -1}; auto it = grundy_i.lower_bound(p); if(it == grundy_i.end()) return -2; if((*it).first != g)return -1; return (*it).second; } int find_interval(){ rep(g,0,MAXN){ if(g > (g^xo)){ int i = find_interval_with_grundy(g); if(i == -2)return -1; if(i != -1)return i; } } return -1; } int main() { cin >> n; string s; cin >> s; grundy({0,1}); rep(c1,0,n){ berry.push_back((s[c1] == 'b')); } for(int b = k; b >= 1; b--){ //cerr << "PHASE " << b << " " << turn << "\n"; positions.clear(); i_grundy.clear(); pos_to_i.clear(); intervals.clear(); grundy_i.clear(); rep(c1,0,n){ pos_to_i.push_back(-1); if(score(c1) == b && berry[c1] == 1){ positions.push_back(c1); } } int last = -1000; trav(i, positions){ if(i-last >= k){ vi temp; intervals.push_back(temp); } pos_to_i[i] = sz(intervals)-1; intervals.back().push_back(i); last = i; } xo = 0; rep(c1,0,sz(intervals)){ i_grundy.push_back(grundy(intervals[c1])); grundy_i.insert({i_grundy.back(), c1}); xo ^= i_grundy.back(); } while(sz(grundy_i) > 0){ // grandpa's turn int i; cin >> i; i--; while(berry[i] == 0){ i++; } make_move(i); turn++; // our turn if(sz(grundy_i) == 0){ return 0; // we lost, WA } int interval = find_interval(); bool good = 1; if(interval == -1){ auto it = grundy_i.end(); it--; interval = (*it).second; good = 0; } assert(sz(intervals[interval]) != 0); i = intervals[interval][0]; rep(c1,0,sz(intervals[interval])){ vi L = get_left(intervals[interval], c1); vi R = get_right(intervals[interval], c1); int j = intervals[interval][c1]; if((grundy(L)^grundy(R)^i_grundy[interval]) == xo){ i = j; break; } } if(i == -1){ i = intervals[interval][0]; } make_move(i); cout << min(n-k,i)+1 << endl; turn++; } } return 0; }