#include using namespace std; struct Operation { int type; int x; int y; }; struct Query { int left; int right; int id; }; struct MoComparator { int blockSize; bool operator()(const Query& a, const Query& b) const { int blockA = a.left / blockSize; int blockB = b.left / blockSize; if (blockA != blockB) { return blockA < blockB; } if (blockA & 1) { return a.right > b.right; } return a.right < b.right; } }; void solveBatch( const string& S, vector& queries, vector& answers ) { if (queries.empty()) { return; } const int N = static_cast(S.size()); const int queryCount = static_cast(queries.size()); vector prefix(N + 1, 0); for (int i = 0; i < N; ++i) { prefix[i + 1] = prefix[i] + (S[i] == '(' ? 1 : -1); } const int blockSize = max( 1, static_cast( N / max(1.0, sqrt(static_cast(queryCount))) ) ); sort(queries.begin(), queries.end(), MoComparator{blockSize}); multiset values; int currentLeft = 0; int currentRight = -1; for (const Query& query : queries) { const int left = query.left; const int right = query.right; while (currentLeft > left) { --currentLeft; values.insert(prefix[currentLeft]); } while (currentRight < right) { ++currentRight; values.insert(prefix[currentRight]); } while (currentLeft < left) { auto it = values.find(prefix[currentLeft]); values.erase(it); ++currentLeft; } while (currentRight > right) { auto it = values.find(prefix[currentRight]); values.erase(it); --currentRight; } const int length = right - left + 1; const int intervalSum = prefix[right] - prefix[left - 1]; const int closeCount = (length - intervalSum) / 2; const int minimumPrefix = *values.begin(); const int unmatchedClose = max( 0, prefix[left - 1] - minimumPrefix ); const int matchedPairs = closeCount - unmatchedClose; answers[query.id] = matchedPairs * 2; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, Q; cin >> N >> Q; string S; cin >> S; vector operations(Q); int answerCount = 0; for (int i = 0; i < Q; ++i) { cin >> operations[i].type >> operations[i].x >> operations[i].y; if (operations[i].type == 2) { ++answerCount; } } vector answers(answerCount); vector batch; int answerId = 0; for (const Operation& operation : operations) { if (operation.type == 2) { batch.push_back({ operation.x, operation.y, answerId }); ++answerId; } else { solveBatch(S, batch, answers); batch.clear(); S[operation.x - 1] = (operation.y == 1 ? '(' : ')'); } } solveBatch(S, batch, answers); for (int answer : answers) { cout << answer << '\n'; } return 0; }