#include // #include using namespace std; // using namespace atcoder; constexpr int64_t INF = static_cast(1) << 60; template bool chmin(T &a, T b); template bool chmax(T &a, T b); // x^nを高速で計算する uint64_t pow64i(uint64_t x, uint64_t n); // cout << std::fixed << std::setprecision(15); using Graph = vector>; #include struct S { int l = 0, r = 0; int ans = 0; }; S op(S a, S b) { return {a.l + b.l - min(a.l, b.r), a.r + b.r - min(a.l, b.r), a.ans + b.ans + min(a.l, b.r) * 2}; } S e() { return {0, 0, 0}; } int main() { ios::sync_with_stdio(false); std::cin.tie(nullptr); int n, q; cin >> n >> q; string s; cin >> s; vector v(n); for (int i = 0; i < n; i++) { if (s.at(i) == '(') { v.at(i).l++; } else { v.at(i).r++; } } atcoder::segtree sg(v); for (; q > 0; q--) { int t; cin >> t; if (t == 1) { int x; char c; cin >> x >> c; x--; if (s.at(x) != c) { s.at(x) = c; if (c == '(') { sg.set(x, {1, 0, 0}); } else { sg.set(x, {0, 1, 0}); } } } else { int l, r; cin >> l >> r; l--; cout << sg.prod(l, r).ans << endl; } } return 0; } template bool chmin(T &a, T b) { if (a > b) { a = b; return true; } return false; } template bool chmax(T &a, T b) { if (a < b) { a = b; return true; } return false; } uint64_t pow64i(uint64_t x, uint64_t n) { uint64_t ret = 1; while (n > 0) { if (n & 1) ret *= x; // n の最下位bitが 1 ならば x^(2^i) をかける x *= x; n >>= 1; // n を1bit 左にずらす } return ret; }