#include <string>
#include <vector>
#include <algorithm>
using namespace std;

// 演算法 / Algorithm:
//   切成交替 0/1 段;每次交易淨收益 = 左0段長 + 右0段長 = ans[1段]。
//   Runs of 0/1; a trade's gain = leftZeroLen + rightZeroLen = ans[1-run].
//   內部段用線段樹區間最大;兩端截斷的段各自處理。答案 = 全串1數 + 最佳收益。
//   Segment tree for interior runs, special-case the two clamped boundary runs.

class Solution {
    vector<int> tree, ansv;                               // tree=線段樹, ansv=每段收益 / tree + per-run gains

    // 建樹:store max of ansv[lo..hi] / build max segment tree
    void build(int node, int lo, int hi) {
        if (lo == hi) { tree[node] = ansv[lo]; return; }  // 葉子存單段值 / leaf = one run's value
        int mid = (lo + hi) / 2;                          // 對半 / midpoint
        build(node * 2, lo, mid);                         // 左子樹 / left
        build(node * 2 + 1, mid + 1, hi);                 // 右子樹 / right
        tree[node] = max(tree[node * 2], tree[node * 2 + 1]); // 取兩子最大 / parent = max
    }

    // 區間最大查詢 [ql,qr] / range-max query
    int query(int node, int lo, int hi, int ql, int qr) {
        if (qr < lo || hi < ql) return 0;                 // 無交集 / no overlap
        if (ql <= lo && hi <= qr) return tree[node];      // 完全覆蓋 / fully covered
        int mid = (lo + hi) / 2;
        return max(query(node * 2, lo, mid, ql, qr),      // 合併左右 / combine children
                   query(node * 2 + 1, mid + 1, hi, ql, qr));
    }

public:
    vector<int> maxActiveSectionsAfterTrade(string s, vector<vector<int>>& queries) {
        int n = (int)s.size();                            // 字串長度 / length

        // rs/re/rv 用 vector 動態存段;push_back 逐段加入 / grow run arrays with push_back
        vector<int> rs, re, rv, segId(n);                 // segId: 位置 -> 段編號 / position to run id
        long long onesTotal = 0;                          // 全串 1 的總數 / total ones
        for (int i = 0; i < n; ) {                        // 掃描切段 / scan into runs
            int j = i;                                    // 找段尾 / find run end
            while (j < n && s[j] == s[i]) j++;            // 相同字元延伸 / extend equal chars
            int id = (int)rs.size();                      // 這是第 id 個段 / current run id
            rs.push_back(i);                              // 記起點 / start
            re.push_back(j - 1);                          // 記終點 / end
            rv.push_back(s[i] - '0');                     // 記值(0/1) / value
            if (s[i] == '1') onesTotal += (j - i);        // 是 1 段就累加 / count ones
            for (int k = i; k < j; k++) segId[k] = id;    // 標記位置歸屬 / label positions
            i = j;                                        // 下一段 / next run
        }
        int m = (int)rs.size();                           // 段數 / number of runs

        // 預算每個內部 1 段的收益 / precompute gains for interior 1-runs
        ansv.assign(m, 0);                                // 預設全 0 / default 0
        for (int i = 0; i < m; i++)
            if (rv[i] == 1 && i > 0 && i < m - 1)         // 內部 1 段才有左右鄰居 / interior 1-run has both neighbors
                ansv[i] = (re[i-1] - rs[i-1] + 1) + (re[i+1] - rs[i+1] + 1); // 左段長 + 右段長 / neighbor lengths

        tree.assign(4 * m, 0);                            // 線段樹配置 4m / allocate ~4m nodes
        build(1, 0, m - 1);                               // 建樹 / build

        vector<int> res;                                  // 答案 / results
        res.reserve(queries.size());                      // 先預留空間 / reserve capacity
        for (auto& qq : queries) {                        // range-for 逐個查詢 / iterate queries
            int l = qq[0], r = qq[1];                     // 結構化取值 / query range
            int a = segId[l], b = segId[r];               // 左右端所在段 / runs of l and r
            int best = 0;                                 // 最佳收益 / best gain

            if (a != b) {                                 // 同一段內無法交易 / single run: no trade
                int loIdx = (rs[a] == l) ? a : a + 1;     // 最小完整段 / smallest fully-inside run
                int hiIdx = (re[b] == r) ? b : b - 1;     // 最大完整段 / largest fully-inside run

                if (loIdx + 1 <= hiIdx - 1)               // 內部 1 段用線段樹 / interior via segment tree
                    best = max(best, query(1, 0, m - 1, loIdx + 1, hiIdx - 1));

                if (rv[a] == 0) {                         // 左邊界:l 在 0 段內 / left clamp
                    int i = a + 1;                        // 右鄰的 1 段 / the 1-run after l
                    if (re[i] <= r && i + 1 <= m - 1 && rs[i+1] <= r) { // 1 段完整且右邊有 0 / valid
                        int rz = min(re[i+1], r) - rs[i+1] + 1; // 右 0 段長(截斷) / right zeros clamped
                        int lz = rs[i] - l;               // 左 0 段長(從 l 起) / left zeros from l
                        best = max(best, lz + rz);        // 更新 / update
                    }
                }
                if (rv[b] == 0) {                         // 右邊界:r 在 0 段內 / right clamp
                    int i = b - 1;                        // 左鄰的 1 段 / the 1-run before r
                    if (rs[i] >= l && i - 1 >= 0 && re[i-1] >= l) { // 1 段完整且左邊有 0 / valid
                        int lz = re[i-1] - max(l, rs[i-1]) + 1; // 左 0 段長(截斷) / left zeros clamped
                        int rz = r - re[i];               // 右 0 段長(到 r) / right zeros up to r
                        best = max(best, lz + rz);        // 更新 / update
                    }
                }
            }
            res.push_back((int)onesTotal + best);         // 答案 = 全串1數 + 收益 / total ones + gain
        }
        return res;                                       // 回傳所有答案 / return answers
    }
};
