#include using namespace std; using ll = long long; using matrix = vector>; matrix prod(matrix a, matrix b) { int n = a.size(); matrix ans(n, vector(n)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { // ans[i][j] for (int k = 0; k < n; k++) { ans[i][j] += a[i][k] * b[k][j]; } } } return ans; } struct RMQ { const matrix INF = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; int n; // 葉の数 vector dat; // 完全二分木の配列 RMQ(int n_) : n(), dat(n_ * 4, INF) { // 葉の数は 2^x の形 int x = 1; while (n_ > x) { x *= 2; } n = x; } void update(int i, matrix x) { i += n - 1; dat[i] = x; while (i > 0) { i = (i - 1) / 2; // parent dat[i] = prod(dat[i * 2 + 1], dat[i * 2 + 2]); } } // 半開区間[l,r) // the minimum element of [a,b) matrix query(int a, int b) { return query_sub(a, b, 0, 0, n); } matrix query_sub(int a, int b, int k, int l, int r) { if (r <= a || b <= l) { return INF; } else if (a <= l && r <= b) { return dat[k]; } else { matrix vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2); matrix vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r); return prod(vl, vr); } } }; void solve() { int n, q; cin >> n >> q; string s; cin >> s; s = "+" + s; RMQ seg(n / 2 + 10); for (int i = 0; i < s.size(); i += 2) { matrix now(4, vector(4, 0)); char op = s[i], tf = s[i + 1]; if (op == '+' and tf == 'T') { now[1][1] = 1; now[0][1] = 1; } else if (op == '*' and tf == 'F') { now[0][0] = 1; now[1][0] = 1; } else if (op == '^' and tf == 'T') { now[0][1] = 1; now[1][0] = 1; } else { now[0][0] = 1; now[1][1] = 1; } if (tf == 'T') now[2][1] = 1; else now[2][0] = 1; now[1][3] = 1; now[2][2] = 1; now[3][3] = 1; seg.update(i / 2, now); } for (int i = 0; i < q; i++) { int l, r; cin >> l >> r; l /= 2; r--; r /= 2; matrix mat = seg.query(l, r + 1); ll ans = mat[2][1] + mat[2][3]; cout << ans << endl; } } int main() { cin.tie(0)->sync_with_stdio(0); cout << fixed << setprecision(20); int CNT = 1; for (int i = 0; i < CNT; i++) solve(); }