#!/usr/bin/env python3 import bisect # Would use this, but it is not avalible on olded versions of Python3 #from functools import cache from functools import lru_cache cache = lru_cache(maxsize=None) def mex(A): A = sorted(set(A)) n = len(A) i = 0 while i < n and i == A[i]: i += 1 return i n = int(input()) A = [+(c == 'b') for c in input()] # Add extra 0s to A to avoid indexing out of bounds later A += [0] * 4 for k in 4,3,2,1: """ Handle the case of removing k berries per query. """ # Calculates the Grundy number of A[l:r] with k removals @cache def grundy(l, r): seen = [] for i in range(l, r): l2 = max(l, i) r2 = min(r, i + 4) s = 0 for j in range(l2, r2): s += A[j] if s == k: seen.append(grundy(l, l2) ^ grundy(r2, r)) return mex(seen) # Find a removal to make the current state reach 0 @cache def find_removal(l, r): goal = current_state ^ grundy(l, r) assert goal < grundy(l, r) seen = [] for i in range(l, r): l2 = max(l, i) r2 = min(r, i + 4) s = 0 for j in range(l2, r2): s += A[j] if s == k and grundy(l, l2) ^ grundy(r2, r) == goal: return l2 assert False current_state = 0 L = [] R = [] def remove_interval(a, b): global current_state current_state ^= grundy(a, b) L.pop(bisect.bisect_left(L, a)) R.pop(bisect.bisect_left(R, b)) def add_interval(a, b): # Ignore adding too small intervals while a < b and (A[a] == 0 or sum(A[a:min(a + 4, b)]) < k): a += 1 while a < b and (A[b - 1] == 0 or sum(A[max(a, b - 4):b]) < k): b -= 1 if a >= b: return global current_state current_state ^= grundy(a, b) bisect.insort_left(L, a) bisect.insort_left(R, b) i = 0 while i < n: while i < n and sum(A[i:i+4]) < k: i += 1 if i < n: j = i while j < n and sum(A[j:j+4]): j += 1 j += 3 add_interval(i, j) i = j # Pick berries A[i:i+4] def apply_query(i): assert 0 <= i assert i + 4 <= n assert sum(A[i:i+4]) == k A[i] = A[i + 1] = A[i + 2] = A[i + 3] = 0 ind = bisect.bisect_left(R, i + 1) a = L[ind] b = R[ind] remove_interval(a, b) add_interval(a, i) add_interval(i + 4, b) # Handle the berry picking of k berries at a time while L: i = int(input()) - 1 apply_query(i) assert L if current_state: for a,b in zip(L, R): g = grundy(a, b) if g ^ current_state < g: break i = find_removal(a, b) else: i = L[-1] # Handle possible out of bounds i = min(i, n - 4) print(i + 1) apply_query(i) for i in range(n - 3): assert sum(A[i:i + 4]) < k