import java.io.PrintWriter
import java.util.StringTokenizer

fun main() {
    val s = readLn()

    val LEFT = SegmentEntry(0, 1, 0)
    val RIGHT = SegmentEntry(0, 0, 1)
    val ZERO = SegmentEntry(0, 0, 0)

    val tree = s.map { c ->
        if(c == '(') LEFT
        else RIGHT
    }.toSegmentTree(ZERO, SegmentEntry::plus)

    val m = readInt()

    output {
        repeat(m) {
            val (l, r) = readInts(2)
            val ans = tree[l - 1 until r].maxGood

            println(ans)
        }
    }
}

data class SegmentEntry(val maxGood: Int, val leftRem: Int, val rightRem: Int) {
    operator fun plus(other: SegmentEntry): SegmentEntry {
        val satisfied = minOf(leftRem, other.rightRem)
        return SegmentEntry(
            maxGood = maxGood + other.maxGood + satisfied * 2,
            leftRem = leftRem + other.leftRem - satisfied,
            rightRem = rightRem + other.rightRem - satisfied
        )
    }
}

/** Segment tree can be built for any monoid (set with associative binary operation and identity element) */
fun <T> Collection<T>.toSegmentTree(
    identityValue: T, combiner: (T, T) -> T
): SegmentTree<T> = SegmentTree(size, identityValue, combiner).also { it.copyFrom(this) }

class SegmentTree<T>(
    val size: Int,
    val identityValue: T,
    val combiner: (T, T) -> T) {

    @Suppress("UNCHECKED_CAST")
    private val array = Array<Any?>(2 * size) { identityValue } as Array<T>

    val lastIndex get() = size - 1
    val indices get() = 0 until size
    val asList: List<T> by lazy {
        object : AbstractList<T>() {
            override val size: Int get() = this@SegmentTree.size
            override fun get(index: Int): T = this@SegmentTree[index]
        }
    }

    /** instantiates values from an iterable, O(n) time */
    fun copyFrom(iterable: Iterable<T>) {
        run {
            iterable.forEachIndexed { i, t ->
                if(i > lastIndex) return@run
                array[i + size] = t
            }
        }
        for(i in size-1 downTo 1) {
            array[i] = combiner(array[i*2], array[i*2+1])
        }
    }

    /** Updates a value, O(log n) time */
    operator fun set(index: Int, value: T) {
        require(index in indices)
        var i = index + size
        array[i] = value
        while(true) {
            i = i shr 1
            if(i <= 0) break
            array[i] = combiner(array[i*2], array[i*2+1])
        }
    }

    /** Gets a value by its index, O(1) time */
    operator fun get(index: Int): T {
        require(index in indices)
        return array[index + size]
    }

    /** gets the result of applying the monoid operation to the values in the range, O(log n) time */
    operator fun get(range: IntRange): T {
        if(range.isEmpty()) return identityValue
        require(range.first in indices)
        require(range.endInclusive in indices)
        var l = range.first + size
        var r = range.endInclusive + size + 1

        // two accumulators to support non-commutative monoids
        var lAcc = identityValue
        var rAcc = identityValue

        while(l < r) {
            if(l and 1 == 1) {
                lAcc = combiner(lAcc, array[l++])
            }
            if(r and 1 == 1) {
                rAcc = combiner(array[--r], rAcc)
            }

            l = l shr 1
            r = r shr 1
        }

        return combiner(lAcc, rAcc)
    }
}

/** IO code start */
@JvmField val _reader = System.`in`.bufferedReader()
fun readLine(): String? = _reader.readLine()
fun readLn() = _reader.readLine()!!
@JvmField var _tokenizer: StringTokenizer = StringTokenizer("")
fun read(): String {
    while (_tokenizer.hasMoreTokens().not()) _tokenizer = StringTokenizer(_reader.readLine() ?: return "", " ")
    return _tokenizer.nextToken()
}
fun readInt() = read().toInt()
fun readDouble() = read().toDouble()
fun readLong() = read().toLong()
fun readStrings(n: Int) = List(n) { read() }
fun readInts(n: Int) = List(n) { read().toInt() }
fun readDoubles(n: Int) = List(n) { read().toDouble() }
fun readLongs(n: Int) = List(n) { read().toLong() }

@JvmField val _writer = PrintWriter(System.out, false)
inline fun output(block: PrintWriter.()->Unit) { _writer.apply(block).flush() }
fun iprintln(o: Any?) { println(o) } // immediate println for interactive, bypasses output{} blocks


import java.util.ArrayDeque

fun main() {
    val s = readLn()

    val tree = s.map { c ->
        if(c == '(') SegmentEntry(0, 1, 0)
        else SegmentEntry(0, 0, 1)
    }.toSegmentTree(SegmentEntry(0, 0, 0), SegmentEntry::plus)

    val m = readInt()
    repeat(m) {
        val (l, r) = readInts()
        val ans = tree[l-1 until r].maxGood

        println(ans)
    }
}

data class SegmentEntry(val maxGood: Int, val openRem: Int, val closeRem: Int) {
    operator fun plus(other: SegmentEntry): SegmentEntry {
        val satisfied = minOf(openRem, other.closeRem)
        return SegmentEntry(
            maxGood = maxGood + other.maxGood + satisfied * 2,
            openRem = openRem + other.openRem - satisfied,
            closeRem = closeRem + other.closeRem - satisfied
        )
    }
}

/** Segment tree can be built for any monoid (set with associative binary operation and identity element) */
fun <T> Collection<T>.toSegmentTree(identityValue: T, combiner: (T, T) -> T): SegmentTree<T> =
    SegmentTree(size, identityValue, combiner).also { it.copyFrom(this) }

class SegmentTree<T>(
    val size: Int,
    val identityValue: T,
    val combiner: (T, T) -> T) {

    @Suppress("UNCHECKED_CAST")
    private val array = Array<Any?>(2 * size) { identityValue } as Array<T>

    val lastIndex get() = size - 1
    val indices get() = 0 until size
    val asList: List<T> by lazy {
        object : AbstractList<T>() {
            override val size: Int get() = this@SegmentTree.size
            override fun get(index: Int): T = this@SegmentTree[index]
        }
    }

    /** instantiates values from an iterable, O(n) time */
    fun copyFrom(iterable: Iterable<T>) {
        run {
            iterable.forEachIndexed { i, t ->
                if(i > lastIndex) return@run
                array[i + size] = t
            }
        }
        for(i in size-1 downTo 1) {
            array[i] = combiner(array[i*2], array[i*2+1])
        }
    }

    /** Updates a value, O(log n) time */
    operator fun set(index: Int, value: T) {
        require(index in indices)
        var i = index + size
        array[i] = value
        while(true) {
            i = i shr 1
            if(i <= 0) break
            array[i] = combiner(array[i*2], array[i*2+1])
        }
    }

    /** Gets a value by its index, O(1) time */
    operator fun get(index: Int): T {
        require(index in indices)
        return array[index + size]
    }

    /** gets the result of applying the monoid operation to the values in the range, O(log n) time */
    operator fun get(range: IntRange): T {
        if(range.isEmpty()) return identityValue
        require(range.first in indices)
        require(range.endInclusive in indices)
        var l = range.first + size
        var r = range.endInclusive + size + 1

        var ans = identityValue

        val lDeq = ArrayDeque<T>()
        val rDeq = ArrayDeque<T>()

        while(l < r) {
            if(l and 1 == 1) {
                lDeq.add(array[l++])
            }
            if(r and 1 == 1) {
                rDeq.push(array[--r])
            }

            l = l shr 1
            r = r shr 1
        }

        ans = lDeq.fold(ans, combiner)
        ans = rDeq.fold(ans, combiner)

        return ans
    }
}

fun readLn() = readLine()!!
fun readInt() = readLn().toInt()
fun readDouble() = readLn().toDouble()
fun readLong() = readLn().toLong()
fun readStrings() = readLn().split(' ')
fun readStringSeq() = readLn().splitToSequence(' ')
fun readInts() = readStrings().map { it.toInt() }
fun readIntSeq() = readStringSeq().map { it.toInt() }
fun readDoubles() = readStrings().map { it.toDouble() }
fun readDoubleSeq() = readStringSeq().map { it.toDouble() }
fun readLongs() = readStrings().map { it.toLong() }
fun readLongSeq() = readStringSeq().map { it.toLong() }

class Output {
    val outputSb = StringBuilder()
    fun print(o: Any?) { outputSb.append(o) }
    fun println() { outputSb.append('\n') }
    fun println(o: Any?) { outputSb.append(o).append('\n') }
    @JvmName("_print") fun Any?.print() = print(this)
    @JvmName("_println") fun Any?.println() = println(this)
    fun nowPrint() { kotlin.io.print(outputSb) }
}
inline fun output(block: Output.()->Unit) { Output().apply(block).nowPrint() }


// Stanisław Szczesniak

#include <bits/stdc++.h>

#define pb push_back
#define ins insert
#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(x,b,e) for(int x= (b); (x) <= (e); x++)
#define FORD(x,b,e) for(int x= (b); (x) >= (e); x--)
#define fir first
#define sec second
#define D(x) cerr << "zmienna "<< #x << " = " << (x) << endl;
#define ALL(x) (x.begin()),(x.end())
#define SZ(x) (int)x.size()
#define Dp(x) cerr << "para " << #x << " = (" << x.first << "," << x.second << endl;
#define Da(x,len) cerr << "tablica " << #x << " = { "; \
for(int iiii=0;iiii<len;iiii++) cerr << x[iiii] << " ";\
cerr << "}\n";
#define Dab(x,len) cerr << "tablica " << #x << " = \n{ "; \
for(int iiii=0;iiii<len;iiii++) cerr << x[iiii] << " ";\
cerr << "}\n  ";\
for(int iiii=0;iiii<len;iiii++) cerr << iiii << " ";\
cerr << "\n";
#define Dv(x) cerr << "vector " << #x << " = { "; \
for(int iiii=0;iiii<(int)x.size();iiii++) cerr << x[iiii] << " ";\
cerr << "}\n";
#define Dvb(x) cerr << "vector " << #x << " = \n{ "; \
for(int iiii=0;iiii<x.size();iiii++) cerr << x[iiii] << " ";\
cerr << "}\n  ";\
for(int iiii=0;iiii<x.size();iiii++) cerr << iiii << " ";\
cerr << "\n";

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<pii> vpii;
typedef long double LD;

const int N = 1e5+77;

const int M = 1<<20;

int lwolne[M<<1];
int rwolne[M<<1];
int najl[M<<1];

vector<int> przed;
void query(int v,int a, int b, int p, int k) {
	if(p >= a && k <= b) {
		przed.push_back(v);
	}
	else if(!(k < a or p > b)) {
		query(v*2,a,b,p,(p+k)/2);
		query(v*2+1,a,b,(p+k)/2+1,k);
	}
}

int main () {
	ios_base::sync_with_stdio(false);
	string s;
	cin >> s;
	for(int i=0;i<(int)s.size();i++) {
		lwolne[M+i+1] = s[i] == '(' ? 1 : 0;
		rwolne[M+i+1] = s[i] == ')' ? 1 : 0;
	}
	for(int v=M-1;v>=1;v--) {
		najl[v] = najl[v*2] + najl[v*2+1] + min(lwolne[v*2],rwolne[v*2+1]);
		lwolne[v] = lwolne[v*2] + lwolne[v*2+1] - min(lwolne[v*2],rwolne[v*2+1]);
		rwolne[v] = rwolne[v*2] + rwolne[v*2+1] - min(lwolne[v*2],rwolne[v*2+1]);
	}
	int q;
	cin >> q;
	int a,b;
	for(int i=0;i<q;i++) {
		cin >> a >> b;
		przed.clear();
		query(1,a,b,0,M-1);
		int wl, r;
		wl = lwolne[przed[0]];
		r = najl[przed[0]];
		for(int i=1;i<(int)przed.size();i++) {
			int x = min(wl,rwolne[przed[i]]);
			r = r + najl[przed[i]] + x;
			wl = wl + lwolne[przed[i]] - x;
		}
		cout << r*2 << endl;
	}
}


// Stanisław Szczesniak

#include <bits/stdc++.h>

#define pb push_back
#define ins insert
#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(x,b,e) for(int x= (b); (x) <= (e); x++)
#define FORD(x,b,e) for(int x= (b); (x) >= (e); x--)
#define fir first
#define sec second
#define D(x) cerr << "zmienna "<< #x << " = " << (x) << endl;
#define ALL(x) (x.begin()),(x.end())
#define SZ(x) (int)x.size()
#define Dp(x) cerr << "para " << #x << " = (" << x.first << "," << x.second << endl;
#define Da(x,len) cerr << "tablica " << #x << " = { "; \
for(int iiii=0;iiii<len;iiii++) cerr << x[iiii] << " ";\
cerr << "}\n";
#define Dab(x,len) cerr << "tablica " << #x << " = \n{ "; \
for(int iiii=0;iiii<len;iiii++) cerr << x[iiii] << " ";\
cerr << "}\n  ";\
for(int iiii=0;iiii<len;iiii++) cerr << iiii << " ";\
cerr << "\n";
#define Dv(x) cerr << "vector " << #x << " = { "; \
for(int iiii=0;iiii<(int)x.size();iiii++) cerr << x[iiii] << " ";\
cerr << "}\n";
#define Dvb(x) cerr << "vector " << #x << " = \n{ "; \
for(int iiii=0;iiii<x.size();iiii++) cerr << x[iiii] << " ";\
cerr << "}\n  ";\
for(int iiii=0;iiii<x.size();iiii++) cerr << iiii << " ";\
cerr << "\n";

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<pii> vpii;
typedef long double LD;

const int N = 1e5+77;

const int M = 1<<20;

int lwolne[M<<1];
int rwolne[M<<1];
int najl[M<<1];

vector<int> przed;
void query(int v,int a, int b, int p, int k) {
	if(p >= a && k <= b) {
		przed.push_back(v);
	}
	else if(!(k < a or p > b)) {
		query(v*2,a,b,p,(p+k)/2);
		query(v*2+1,a,b,(p+k)/2+1,k);
	}
}

int main () {
	ios_base::sync_with_stdio(false);
	string s;
	cin >> s;
	for(int i=0;i<(int)s.size();i++) {
		lwolne[M+i+1] = s[i] == '(' ? 1 : 0;
		rwolne[M+i+1] = s[i] == ')' ? 1 : 0;
	}
	for(int v=M-1;v>=1;v--) {
		najl[v] = najl[v*2] + najl[v*2+1] + min(lwolne[v*2],rwolne[v*2+1]);
		lwolne[v] = lwolne[v*2] + rwolne[v*2+1] - min(lwolne[v*2],rwolne[v*2+1]);
		rwolne[v] = rwolne[v*2] + rwolne[v*2+1] - min(lwolne[v*2],rwolne[v*2+1]);
	}
	int q;
	cin >> q;
	int a,b;
	for(int i=0;i<q;i++) {
		cin >> a >> b;
		przed.clear();
		query(1,a,b,0,M-1);
		int wl, r;
		wl = lwolne[przed[0]];
		r = najl[przed[0]];
		for(int i=1;i<(int)przed.size();i++) {
			int x = min(wl,rwolne[przed[i]]);
			r = r + najl[przed[i]] + x;
			wl = wl + lwolne[przed[i]] - x;
		}
		cout << r*2 << endl;
	}
}


//
//  segment_tree.cpp
//  code
//
//  Created by Vignesh M on 07/02/15.
//  Copyright (c) 2015 xcode. All rights reserved.
//
// http://codeforces.com/contest/380/problem/C
#include <stdio.h>
#include <algorithm>
#include <string.h>

using namespace std;
struct node{
    int ans;
    int open;
    int close;
};
const int MAXN=1000010;
char arr[MAXN];
node tree[4*MAXN];
int n;

void pr(node nd){
    printf("%d %d %d\n",nd.ans,nd.open,nd.close);
}
//build [l,r)
void build(int root=1,int l=0,int r=n){
    if(r-l<2){
        tree[root]={0,arr[l]=='(',arr[l]==')'};
//        printf("%d %d %d\t",root,l,r);pr(tree[root]);
        return ;
    }
    int mid=(l+r)/2;
    build(2*root,l,mid);
    build(2*root+1,mid,r);
    //merge
    int newpairs=min(tree[2*root].open,tree[2*root+1].close);
    tree[root]={tree[2*root].ans+tree[2*root+1].ans+newpairs
        ,tree[2*root].open+tree[2*root+1].open-newpairs
        ,tree[2*root].close+tree[2*root+1].close-newpairs};
//    printf("%d %d %d\t",root,l,r,newpairs);pr(tree[root]);
}

//query [l,r) for [x,y)
node query(int x,int y,int root=1,int l=0,int r=n){
    if(l >= y || x >= r)   return {0,0,0}; //outside
    if(x<=l && r<=y) return tree[root];//full
    int mid=(l+r)/2;
    node left=query(x, y,2*root,l,mid),right=query(x,y,2*root+1,mid,r);
    int newpairs=min(left.open,right.close);
    //printf("%d %d\n",l,r);pr(left);pr(right);
    //merge
    return (node){left.ans+right.ans+newpairs
        ,left.open+right.open-newpairs
        ,left.close+right.close-newpairs};
}
int main(){
    #ifndef ONLINE_JUDGE
        freopen("/Users/vigneshm/Documents/codespace/code/input.txt","r",stdin);
        freopen("/Users/vigneshm/Documents/codespace/code/output.txt","w",stdout);
    #endif
    scanf("%s",arr);
    n=strlen(arr);
    //printf("%d %s\n",n,arr);
    build();
    int q;scanf("%d",&q);
    for(int i=0;i<q;i++){
        int l,r;
        scanf("%d %d",&l,&r);
        printf("%d\n",2*query(l-1,r).ans);
    }

}


//
//  segment_tree.cpp
//  code
//
//  Created by Vignesh M on 07/02/15.
//  Copyright (c) 2015 xcode. All rights reserved.
//
// http://codeforces.com/contest/380/problem/C
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node{
    int ans;
    int open;
    int close;
};
const int MAXN=1000010;
char arr[MAXN];
node tree[4*MAXN];
int n;

void pr(node nd){
    printf("%d %d %d\n",nd.ans,nd.open,nd.close);
}
//build [l,r)
void build(int root=1,int l=0,int r=n){
    if(r-l<2){
        tree[root]={0,arr[l]=='(',arr[l]==')'};
//        printf("%d %d %d\t",root,l,r);pr(tree[root]);
        return ;
    }
    int mid=(l+r)/2;
    build(2*root,l,mid);
    build(2*root+1,mid,r);
    //merge
    int newpairs=min(tree[2*root].open,tree[2*root+1].close);
    tree[root]={tree[2*root].ans+tree[2*root+1].ans+newpairs
        ,tree[2*root].open+tree[2*root+1].open-newpairs
        ,tree[2*root].close+tree[2*root+1].close-newpairs};
//    printf("%d %d %d\t",root,l,r,newpairs);pr(tree[root]);
}

//query [l,r) for [x,y)
node query(int x,int y,int root=1,int l=0,int r=n){
    if(l >= y || x >= r)   return {0,0,0}; //outside
    if(x<=l && r<=y) return tree[root];//full
    int mid=(l+r)/2;
    node left=query(x, y,2*root,l,mid),right=query(x,y,2*root+1,mid,r);
    int newpairs=min(left.open,right.close);
    //printf("%d %d\n",l,r);pr(left);pr(right);
    //merge
    return (node){left.ans+right.ans+newpairs
        ,left.open+right.open-newpairs
        ,left.close+right.close-newpairs};
}
int main(){
    #ifndef ONLINE_JUDGE
        freopen("/Users/vigneshm/Documents/codespace/code/input.txt","r",stdin);
        freopen("/Users/vigneshm/Documents/codespace/code/output.txt","w",stdout);
    #endif
    scanf("%s",arr);
    n=strlen(arr);
    //printf("%d %s\n",n,arr);
    build();
    int q;scanf("%d",&q);
    for(int i=0;i<q;i++){
        int l,r;
        scanf("%d %d",&l,&r);
        printf("%d\n",2*query(l-1,r).ans);
    }

}


#include <bits/stdc++.h>

using namespace std;

typedef pair <int, int> pii;
typedef pair <int, pii> ppi;

#define L second.first
#define R second.second
#define X first

const int maxn = 1e6 + 21;
const ppi Null = {0, {0, 0} };

int n, q, segleft[4 * maxn], segright[4 * maxn], segans[4 * maxn];
string str;

void built(int s = 0, int e = n, int x = 1)
{
    if(e - s == 1)
    {
        if( str[s] == '(' )
            segleft[ x ] = 1;
        else
            segright[ x ] = 1;

        return;
    }

    int mid = (s + e) / 2;

    built(s, mid, 2 * x);
    built(mid, e, 2 * x + 1);

    int V = min( segleft[2 * x], segright[2 * x + 1] );

    segans[ x ] = segans[2 * x] + segans[2 * x + 1] + V;
    segleft[ x ] = segleft[2 * x] + segleft[2 * x + 1] - V;
    segright[ x ] = segright[2 * x] + segright[2 * x + 1] - V;
}

ppi getbrc(int l, int r, int s = 0, int e = n, int x = 1)
{
    if(l <= s && e <= r)
        return{ segans[ x ], { segleft[ x ], segright[ x ] } };

    ppi ret = Null;

    int mid = (s + e) / 2;

    ppi a = Null, b = Null;

    if(l < mid)
        a = getbrc(l, r, s, mid, 2 * x);

    if(mid < r)
        b = getbrc(l, r, mid, e, 2 * x + 1);

    int V = min( a.L, b.R );

    ret.X = a.X + b.X + V;
    ret.L = a.L + b.L - V;
    ret.R = a.R + b.R - V;

    return ret;
}

int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> str;
    n = str.size();

    built();

    cin >> q;

   for(int i = 0; i < q; i++)
   {
       int l, r;
       cin >> l >> r;
       l--;

       cout << getbrc(l, r).X * 2 << "\n";
   }
}


#include <bits/stdc++.h>
#include <cassert>
using namespace std;
typedef long long ll; typedef long double ld;
#define rep(i,s,e) for (int i=(s);i<(e);++i)
#define all(x) begin(x),end(x)
#define clr(x,y) memset(x,y,sizeof x)
#define contains(x,y) ((x).find(y)!=end(x))
#define pb push_back
#define Tu tuple
#define mk make_pair
#define mkt make_tuple
#define fst first
#define snd second
#define _1 get<0>
#define _2 get<1>
#define _3 get<2>
#define _4 get<3>
#define sz(x) ((int)(x).size())
int dx[]={0,0,1,-1,1,-1,1,-1}, dy[]={-1,1,0,0,1,-1,-1,1};
void run();
int main() {
#ifdef LOCAL
#  define dbg(s, ...) printf(s "\n", __VA_ARGS__)
#else
#  define endl "\n"
#  define dbg(s,...)
#  define FILE "x"
  //freopen(FILE ".in", "r", stdin), freopen(FILE ".out", "w", stdout);
  ios::sync_with_stdio(0);
#endif
  cout << fixed << setprecision(16);
  run();
}

int n;
string s;

int rmq[21][1000100];
int getmin(int l, int w) {
  int k = 0;
  while ((1<<(k+1)) <= w) ++k;
  return min(rmq[k][l], rmq[k][l + w - (1<<k)]);
}

void run() {
  cin >> s;
  n = s.size();
  rep(i,0,n) {
    rmq[0][i] = (i > 0 ? rmq[0][i - 1] : 0)
              + (s[i] == '(' ? 1 : -1);
    //cout << rmq[0][i] << " ";
  }
  //cout << endl;
  for (int k = 1, w = 2; w <= n; k++, w <<= 1) {
    for (int i = 0; i <= n - w; ++i) {
      rmq[k][i] = min(rmq[k - 1][i], rmq[k - 1][i + w/2]);
      //cout << rmq[k][i] << " ";
    }
    //cout << endl;
  }
  int q; cin >> q;
  rep(i,0,q) {
    int l, r; cin >> l >> r;
    l--; r--;
    int w = r - l + 1;
    int init = l > 0 ? rmq[0][l - 1] : 0;
    int mini = getmin(l, w) - init;
    int end = rmq[0][r] - init;
    int res = w;
    if (mini >= 0) {
      res -= end;
    } else {
      res += 2*mini - end;
    }
    cout << res << endl;
    //cout << mini << " " << init << endl;
  }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef pair< int ,int > pii;
#define SIZE(X) ((int)(X.size()))
#define X first
#define Y second
#define LENGTH(X) ((int)(X.length()))
#define pb push_back
#define MP(X,Y) make_pair(X,Y)
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
typedef long long int int64;
typedef unsigned long long uLL;
#define FOR(i,n) for(int i=0;i<n;i++)
#define FU(i,a,n) for(int i=a;i<=n;i++)
#define FD(i,a,n) for(int i=n;i>=a;i--)
#define GI(n) int (n); scanf("%d",&(n))
#define GS(n) scanf("%s"&s)
#define PII(n,m) printf("%d %d\n",n,m)
#define PL(n) printf("%I64d\n",n)
#define F(i,L,R) for (int i = L; i < R; i++)
#define GII(n,m) int (n),(m); scanf("%d %d",&(n),&(m))
#define IN GI(t);while(t--)
#define PLL(n) printf("%I64d\n",n)
#define GLL(n) scanf("%I64d",&n)
#define GL(n) scanf("%I64d",&n)
#define PN printf("\n")
#define MAX 100007
# define mod 1000000007

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

#define MAXN 1000007

int fen[MAXN];
int ans[MAXN];
void add(int i){
    //cout<<i<<endl;
    for (i++; i < MAXN; i += i & (-i)){
        fen[i]++;
        //cout<<fen[i]<<" "<<i<<endl;
    }
}

int get(int i)
{
    //cout<<i<<endl;
    int ans = 0;
    for (i++; i > 0; i -= i & (-i)){
        ans += fen[i];
        //cout<<fen[i]<<" "<<i<<endl;
    }
    return ans;
}

vector<pii> q[MAXN];
stack<int> st;
int main()
{
    ios_base::sync_with_stdio(false);
    string s;
    cin >> s;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int l, r;
        cin >> l >> r;
        l--, r--;
        q[l].push_back(pii(r, i));
    }
    for (int i = s.length() - 1; i >= 0; i--)
    {
        if (s[i] == ')')
            st.push(i);
        else if (!st.empty())
        {
            add(st.top());
            st.pop();
        }
        for (int j = 0; j < q[i].size(); j++){
            ans[q[i][j].second] = get(q[i][j].first);
            //cout<<q[i][j].second<<endl;
        }
    }
    for (int i = 0; i < n; i++)
        cout << ans[i] * 2 << endl;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef pair< int ,int > pii;
#define SIZE(X) ((int)(X.size()))
#define X first
#define Y second
#define LENGTH(X) ((int)(X.length()))
#define pb push_back
#define MP(X,Y) make_pair(X,Y)
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
typedef long long int int64;
typedef unsigned long long uLL;
#define FOR(i,n) for(int i=0;i<n;i++)
#define FU(i,a,n) for(int i=a;i<=n;i++)
#define FD(i,a,n) for(int i=n;i>=a;i--)
#define GI(n) int (n); scanf("%d",&(n))
#define GS(n) scanf("%s"&s)
#define PII(n,m) printf("%d %d\n",n,m)
#define PL(n) printf("%I64d\n",n)
#define F(i,L,R) for (int i = L; i < R; i++)
#define GII(n,m) int (n),(m); scanf("%d %d",&(n),&(m))
#define IN GI(t);while(t--)
#define PLL(n) printf("%I64d\n",n)
#define GLL(n) scanf("%I64d",&n)
#define GL(n) scanf("%I64d",&n)
#define PN printf("\n")
#define MAX 100007
# define mod 1000000007

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

string s;
int m;
ll ans;

int main(){
    ios::sync_with_stdio(0);
    cin>>s;
    cin>>m;
    FOR(i,m){
        ans = 0;
        stack<char> st;
        int l,r;
        cin>>l>>r;
        l--;r--;
        for(int j=l;j<=r;j++){
            if(s[j] == '('){
                 st.push('(');
            }else if(!st.empty() && s[j] == ')'){
                st.pop();
                ans += 2;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef pair< int ,int > pii;
#define SIZE(X) ((int)(X.size()))
#define X first
#define Y second
#define LENGTH(X) ((int)(X.length()))
#define pb push_back
#define MP(X,Y) make_pair(X,Y)
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
typedef long long int int64;
typedef unsigned long long uLL;
#define FOR(i,n) for(int i=0;i<n;i++)
#define FU(i,a,n) for(int i=a;i<=n;i++)
#define FD(i,a,n) for(int i=n;i>=a;i--)
#define GI(n) int (n); scanf("%d",&(n))
#define GS(n) scanf("%s"&s)
#define PII(n,m) printf("%d %d\n",n,m)
#define PL(n) printf("%I64d\n",n)
#define F(i,L,R) for (int i = L; i < R; i++)
#define GII(n,m) int (n),(m); scanf("%d %d",&(n),&(m))
#define IN GI(t);while(t--)
#define PLL(n) printf("%I64d\n",n)
#define GLL(n) scanf("%I64d",&n)
#define GL(n) scanf("%I64d",&n)
#define PN printf("\n")
#define MAX 100007
# define mod 1000000007

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

#define MAXN 100007

int fen[MAXN];
int ans[MAXN];
void add(int i){
    //cout<<i<<endl;
    for (i++; i < MAXN; i += i & (-i)){
        fen[i]++;
        //cout<<fen[i]<<" "<<i<<endl;
    }
}

int get(int i)
{
    cout<<i<<endl;
    int ans = 0;
    for (i++; i > 0; i -= i & (-i)){
        ans += fen[i];
        cout<<fen[i]<<" "<<i<<endl;
    }
    return ans;
}

vector<pii> q[MAXN];
stack<int> st;
int main()
{
    ios_base::sync_with_stdio(false);
    string s;
    cin >> s;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int l, r;
        cin >> l >> r;
        l--, r--;
        q[l].push_back(pii(r, i));
    }
    for (int i = s.length() - 1; i >= 0; i--)
    {
        if (s[i] == ')')
            st.push(i);
        else if (!st.empty())
        {
            add(st.top());
            st.pop();
        }
        for (int j = 0; j < q[i].size(); j++){
            ans[q[i][j].second] = get(q[i][j].first);
            //cout<<q[i][j].second<<endl;
        }
    }
    for (int i = 0; i < n; i++)
        cout << ans[i] * 2 << endl;
}


#include <iostream>
#include <array>
using namespace std;
typedef array<int, 3> i3;

const int SZ = 1 << 21, CAP = 1 << 20;
int seg[SZ][3]; // ans, excess (, excess )

void upd(int ind, int val) { // 1 for (, 2 for )
	ind += CAP;
	seg[ind][val] = 1;
	for (int i = ind / 2; i > 0; i >>= 1) {
		int ad = min(seg[2*i][1], seg[2*i + 1][2]);
		seg[i][0] = seg[2*i][0] + seg[2*i + 1][0] + ad;
		seg[i][1] = seg[2*i][1] + seg[2*i + 1][1] - ad;
		seg[i][2] = seg[2*i][2] + seg[2*i + 1][2] - ad;
//		cout << i << ' ' << seg[i][0] << ' ' << seg[i][1] << ' ' << seg[i][2] << '\n';
	}
}

i3 query(int l, int r, int curi, int cl, int cr) {
	if (cl > r || cr < l) return {0, 0, 0};
	if (cl >= l && cr <= r) return {seg[curi][0], seg[curi][1], seg[curi][2]};
	int mid = (cl + cr + 1) / 2;
	i3 r1 = query(l, r, 2*curi, cl, mid - 1);
	i3 r2 = query(l, r, 2*curi + 1, mid, cr);
	int ad = min(r1[1], r2[2]);
	r1[0] += r2[0] + ad;
	r1[1] += r2[1] - ad;
	r1[2] += r2[2] - ad;
	return r1;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	string s;
	int numq;
	cin >> s >> numq;

	for (int i = 0; i < s.length(); i++)
		upd(i, s[i] == '(' ? 1 : 2);

	for (int i = 0; i < numq; i++) {
		int l, r;
		cin >> l >> r;
		i3 res = query(l - 1, r - 1, 1, 0, CAP - 1);
		cout << 2 * res[0] << '\n';
	}
}


#include <iostream>
#include <array>
using namespace std;
typedef array<int, 3> i3;

const int SZ = 1 << 11, CAP = 1 << 10;
int seg[SZ][3]; // ans, excess (, excess )

void upd(int ind, int val) { // 1 for (, 2 for )
	ind += CAP;
	seg[ind][val] = 1;
	for (int i = ind / 2; i > 0; i >>= 1) {
		int ad = min(seg[2*i][1], seg[2*i + 1][2]);
		seg[i][0] = seg[2*i][0] + seg[2*i + 1][0] + ad;
		seg[i][1] = seg[2*i][1] + seg[2*i + 1][1] - ad;
		seg[i][2] = seg[2*i][2] + seg[2*i + 1][2] - ad;
//		cout << i << ' ' << seg[i][0] << ' ' << seg[i][1] << ' ' << seg[i][2] << '\n';
	}
}

i3 query(int l, int r, int curi, int cl, int cr) {
	if (cl > r || cr < l) return {0, 0, 0};
	if (cl >= l && cr <= r) return {seg[curi][0], seg[curi][1], seg[curi][2]};
	int mid = (cl + cr + 1) / 2;
	i3 r1 = query(l, r, 2*curi, cl, mid - 1);
	i3 r2 = query(l, r, 2*curi + 1, mid, cr);
	int ad = min(r1[1], r2[2]);
	r1[0] += r2[0] + ad;
	r1[1] += r2[1] - ad;
	r1[2] += r2[2] - ad;
	return r1;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	string s;
	int numq;
	cin >> s >> numq;

	for (int i = 0; i < s.length(); i++)
		upd(i, s[i] == '(' ? 1 : 2);

	for (int i = 0; i < numq; i++) {
		int l, r;
		cin >> l >> r;
		i3 res = query(l - 1, r - 1, 1, 0, CAP - 1);
		cout << 2 * res[0] << '\n';
	}
}


#include <bits/stdc++.h>
using namespace std;
template<typename T> inline void checkMin(T &a, T b) { if(b<a) a=b; }
template<typename T> inline void checkMax(T &a, T b) { if(a<b) a=b; }
#define X first
#define Y second
#define MP make_pair
#define PB push_back
#define SZ(c) int((c).size())
#define ALL(c) (c).begin(),(c).end()
#define REP(i,n) for (int i=0;i<int(n);++i)
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;

const int MAX_N = 1001000;
const int MAX_M = 100100;

int bit[MAX_N];
inline void add(int i, int d) {
  for (; i < MAX_N; i += i & -i) {
    bit[i] += d;
  }
}
inline int query_prefix(int i) {
  int r = 0;
  for (; i > 0; i -= i & -i) {
    r += bit[i];
  }
  return r;
}
inline int query_sum(int l, int r) {
  return query_prefix(r) - query_prefix(l - 1);
}

char s[MAX_N];
int go[MAX_N];

vector<PII> query[MAX_N];
int ans[MAX_M];

int main() {
  scanf("%s", s + 1);

  int n = strlen(s + 1), m, l, r;
  scanf("%d", &m);
  REP (i, m) {
    scanf("%d%d", &l, &r);
    query[l].PB(MP(r, i));
  }

  static stack<int> stk;
  for (int i = 1; s[i] != '\0'; ++i) {
    if (s[i] == '(') {
      stk.push(i);
    } else {
      if (!stk.empty()) {
        go[stk.top()] = i;
        stk.pop();
      }
    }
  }

  for (int l = 1; l <= n; ++l) {
    if (go[l]) {
      add(go[l], 1);
    }
  }

  for (int ll = 1; ll <= n; ++ll) {
    if (go[ll - 1] >= ll) {
      add(go[ll - 1], -1);
    }
    for (auto p: query[ll]) {
      int r = p.X, id = p.Y;
      ans[id] = query_sum(ll, r);
    }
  }

  REP (i, m) {
    printf("%d\n", ans[i] * 2);
  }
  return 0;
}


#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<map>
#include<list>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>

#define FOREACH(it,c) for(auto it=(c).begin();it!=(c).end();++it)
#define all(s) s.begin(),s.end()
#define pb push_back
#define mp make_pair
#define sd(x) scanf("%d",&x)
#define sl(x) scanf("%I64d",&x)
#define pd(x) printf("%d",x)
#define ll long long
#define mod (1E9)+7
#define intmax (1E9)+7

#ifndef ONLINE_JUDGE
#define TRACE
#endif
#ifdef TRACE
    #define trace(x)            cerr<<x<<endl;
    #define trace1(x)           cerr<<__FUNCTION__<<":"<<__LINE__<<": "#x" = "<<x<<endl;
    #define trace2(x,y)         cerr<<__FUNCTION__<<":"<<__LINE__<<": "#x" = "<<x<<" | "#y" = "<<y<<endl;
    #define trace3(x,y,z)       cerr<<__FUNCTION__<<":"<<__LINE__<<": "#x" = "<<x<<" | "#y" = "<<y<<" | "#z" = "<<z<<endl;
#else
    #define trace(x)
    #define trace1(x)
    #define trace2(x,y)
    #define trace3(x,y,z)
#endif

using namespace std;

//term
#define mid  ((start+end)/2)
#define left (2*node)
#define right (2*node+1)

//treenode defination

struct treenode
{

    int count;
    int o;
    int c;
};

treenode tree[3000006];

string s;

//merge
treenode merge_(treenode a,treenode b)
{
    treenode res;
    int k=min(a.o,b.c);
    res.count=a.count+b.count+2*k;
    res.o=a.o+b.o-k;
    res.c=a.c+b.c-k;
    return res;
}

//build
void build(int node,int start,int end)
{

    if(start==end)
    {
         //initialization
        tree[node].count=0;
        tree[node].c=0;
        tree[node].o=0;

        if(s[start]=='(') tree[node].o=1;
        else tree[node].c=1;

        return;
    }

    build(left,start,mid);
    build(right,mid+1,end);
    tree[node]=merge_(tree[left],tree[right]);

}

//query part
/*

initilly defined res and a ,b global
but it gave wrong res don,t know why

*/

treenode query(int node,int start,int end,int l,int r)
{

    if(start>r||end<l)
    {
         treenode res;
         res.count=-1;
         return res;
    }

    if(start>=l&&end<=r) {return tree[node];}

    treenode a=query(left,start,mid,l,r);
    treenode b=query(right,mid+1,end,l,r);
    if(a.count==-1) return b;
    if(b.count==-1) return a;
   // trace2(a.count,b.count);

    return merge_(a,b);

}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    #endif
    int test,a,b,c;
    treenode res;
    cin>>s;
    build(1,0,s.size()-1);

    sd(a);
    while(a--)
    {

        sd(b);
        sd(c);
        res=query(1,0,s.size()-1,b-1,c-1);
        cout<<res.count<<endl;

    }

    return 0;

}


#include <bits/stdc++.h>
using namespace std;
#define DBG(x) cout << #x << " = " << x << endl;
/*
Compile:
    -Wall -Wextra -pedantic -std=c++11 -O2 -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wcast-qual -Wcast-align -fwhole-program -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -lmcheck -fsanitize=address

Check for memory usage:
    valgrind --tool=massif
 */

const int MAXN = 1005000;

int n, m;
string s;

int open[MAXN], close[MAXN], sum[MAXN];

struct TreeNode
{
    vector<int> numbers;
    int idx_left, idx_right;
    int min_val;
    TreeNode *son1, *son2;

    TreeNode(): son1(nullptr), son2(nullptr) {}

    int get(int fr, int to)
    {
        if(idx_right < fr or idx_left > to)
            return MAXN * 5;

        if(fr <= idx_left and idx_right <= to)
            return min_val;

        return min(son1->get(fr, to), son2->get(fr, to));
    }
};

TreeNode* build_tree(int le, int rg)
{
    assert(le <= rg);

    auto ret = new TreeNode();
    ret->idx_left = le;
    ret->idx_right = rg;

    if(rg == le)
        ret->min_val = sum[le];
    else {
        int mid = (le + rg) / 2;
        ret->son1 = build_tree(le, mid);
        ret->son2 = build_tree(mid + 1, rg);

        ret->min_val = min(ret->son1->min_val, ret->son2->min_val);
    }
    return ret;
}

inline int norm(int a, int b)
{
    if(a <= b)
        return b - a;
    return 0;
}

inline int query(TreeNode* root, int fr, int to)
{
    return to - fr + 1 + (close[to] - close[fr - 1]) - (open[to] - open[fr - 1]) -
        2 * norm(root->get(fr, to), sum[fr - 1]);
}

void init()
{
    for(int i = 1; i <= n; i++) {
        open[i] = open[i - 1] + (s[i - 1] == '(');
        close[i] = close[i - 1] + (s[i - 1] == ')');
        sum[i] = sum[i - 1] + (s[i - 1] == ')' ? -1 : 1);
    }
}

int main()
{
    cin.sync_with_stdio(false);

    cin >> s >> m;
    n = s.size();

    init();
    auto root = build_tree(1, n);

    for(int i = 0; i < m; i++) {
        int fr, to;
        cin >> fr >> to;
        cout << query(root, fr, to) << "\n";
    }
    return 0;
}


#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;

const int N = 1e6+9;
char s[N];
struct TreeArray {
    int a[N];
    void init() {
        fill(a, a+N, 0);
    }
    void update(int id, int add) {
        for(; id<N; id += id&-id) {
            a[id] += add;
        }
    }
    int getSum(int id) {
        int r=0;
        for(; id; id -= id&-id) {
            r += a[id];
        }
        return r;
    }
}ta;

struct Query {
    int L, R, id;
    bool operator<(const Query & q) const {
        return R<q.R;
    }
}q[N];
stack<int> st;
int ans[N];
int main()
{
    int i,  m;

    while(scanf("%s%d", s, &m) != EOF)
    {
        for(i=0; i<m; ++i) {
            scanf("%d%d", &q[i].L, &q[i].R);
            --q[i].L;
            --q[i].R;
            q[i].id = i;
        }
        sort(q, q+m);
        int cur=0;
        for(i=0; i<m; ++i) {
            while(cur<=q[i].R) {
                if(s[cur]==')' && !st.empty()) {
                    ta.update(st.top()+1, 1);
                    st.pop();
                }
                else if(s[cur]=='(') st.push(cur);
                ++cur;
            }
            ans[q[i].id] = ta.getSum(q[i].R+1);
            if(q[i].L) ans[q[i].id] -= ta.getSum(q[i].L);
        }
        for(i=0; i<m; ++i) {
            printf("%d\n", ans[i]<<1);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define Nmax 1000005

using namespace std;

int n,poz[Nmax],st[Nmax],top,aib[Nmax],solutie[Nmax];
char sir[Nmax];

struct el
{
    int val,poz;
};
vector <el> L[Nmax];

inline void Update(int p)
{
    int i;
    for(i=p;i>0;i-=(i&(-i))) ++aib[i];
}

inline int Query(int p)
{
    int i,sol=0;
    for(i=p;i<=n;i+=(i&(-i))) sol+=aib[i];
    return sol;
}

inline void Stiva()
{
    int i;
    for(i=1;i<=n;++i)
        if(sir[i]=='(') st[++top]=i;
        else poz[i]=st[top--];
}

int main()
{
    int i,x,y,m;
    el w;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin>>(sir+1); n=strlen(sir+1);
    Stiva();
    cin>>m;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        w.val=x; w.poz=i;
        L[y].push_back(w);
    }
    for(i=1;i<=n;++i)
    {
        Update(poz[i]);
        vector <el> ::iterator it;
        for(it=L[i].begin();it!=L[i].end();++it)
            solutie[it->poz]=Query(it->val);
    }
    for(i=1;i<=m;++i) cout<<solutie[i]*2<<"\n";
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define Nmax 1000005

using namespace std;

int n,poz[Nmax],st[Nmax],top,aib[Nmax],solutie[Nmax];
char sir[Nmax];

struct el
{
    int val,poz;
};
vector <el> L[Nmax];

inline void Update(int p)
{
    int i;
    for(i=p;i>0;i-=(i&(-i))) ++aib[i];
}

inline int Query(int p)
{
    int i,sol=0;
    for(i=p;i<=n;i+=(i&(-i))) sol+=aib[i];
    return sol;
}

inline void Stiva()
{
    int i;
    for(i=1;i<=n;++i)
        if(sir[i]=='(') st[++top]=i;
        else
            if(top) poz[i]=st[top--];
}

int main()
{
    int i,x,y,m;
    el w;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin>>(sir+1); n=strlen(sir+1);
    Stiva();
    cin>>m;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        w.val=x; w.poz=i;
        L[y].push_back(w);
    }
    for(i=1;i<=n;++i)
    {
        if(poz[i] && sir[i]==')') Update(poz[i]);
        vector <el> ::iterator it;
        for(it=L[i].begin();it!=L[i].end();++it)
            solutie[it->poz]=Query(it->val);
    }
    for(i=1;i<=m;++i) cout<<solutie[i]*2<<"\n";
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define Nmax 1000005

using namespace std;

int n,poz[Nmax],st[Nmax],top,aib[Nmax],solutie[Nmax];
char sir[Nmax];

struct el
{
    int val,poz;
};
vector <el> L[Nmax];

inline void Update(int p)
{
    int i;
    for(i=p;i>0;i-=(i&(-i))) ++aib[i];
}

inline int Query(int p)
{
    int i,sol=0;
    for(i=p;i<=n;i+=(i&(-i))) sol+=aib[i];
    return sol;
}

inline void Stiva()
{
    int i;
    for(i=1;i<=n;++i)
        if(sir[i]=='(') st[++top]=i;
        else poz[i]=st[top--];
}

int main()
{
    int i,x,y,m;
    el w;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin>>(sir+1); n=strlen(sir+1);
    Stiva();
    cin>>m;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        w.val=x; w.poz=i;
        L[y].push_back(w);
    }
    for(i=1;i<=n;++i)
    {
        if(poz[i] && sir[i]==')') Update(poz[i]);
        vector <el> ::iterator it;
        for(it=L[i].begin();it!=L[i].end();++it)
            solutie[it->poz]=Query(it->val);
    }
    for(i=1;i<=m;++i) cout<<solutie[i]*2<<"\n";
    return 0;
}


//ITNOG
#include <bits/stdc++.h>

using namespace std;
//#define int long long

const int maxN = 1000*1000 + 2;
int seg[4 * maxN];
int cn1[4 * maxN];
int cn2[4 * maxN];
void add(int p, int val, int s, int e, int ind)
{
    if(e - s == 1)
    {
	  if(val == 1) cn1[ind] ++;
	  else cn2[ind] ++;
	  return;
    }
    int mid = (s + e) >> 1;
    if(p < mid) add(p, val, s, mid, 2 * ind);
    else add(p, val, mid, e, 2 * ind + 1);

    seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
    seg[ind] += min(cn1[2 * ind], cn2[2 * ind + 1]);

    cn1[ind] = cn1[2 * ind + 1];
    cn2[ind] = cn2[2 * ind];
    if(cn1[2 * ind] > cn2[2 * ind + 1])
	  cn1[ind] += cn1[2 * ind] - cn2[2 * ind + 1];
    else
	  cn2[ind] += cn2[2 * ind + 1] - cn1[2 * ind];
}

pair< int , pair<int, int> > get(int l, int r, int s, int e, int ind)
{
    if(l >= e || r <= s) return make_pair(0, make_pair(0, 0));
    if(l <= s && e <= r) return make_pair(seg[ind], make_pair(cn1[ind], cn2[ind]));

    int mid = (s + e) >> 1;
    auto x = get(l, r, s, mid, 2 * ind + 0);
    auto y = get(l, r, mid, e, 2 * ind + 1);

    auto ans = x;
    ans.first = x.first + y.first;
    ans.first += min(x.second.first, y.second.second);

    ans.second.first = y.second.first;
    ans.second.second = x.second.second;
    if(x.second.first > y.second.second)
	  ans.second.first += x.second.first - y.second.second;
    else
	  ans.second.second += y.second.second - x.second.first;

    return ans;
}
main()
{
    ios::sync_with_stdio(0); cin.tie(0);

    string s; cin >> s; int n = s.size();
    for(int i = 0; i < s.size(); i ++)
    {
	  int val = 0;
	  if(s[i] == '(') val = 1;
	  else val = -1;
	  add(i, val, 0, n, 1);
    }

    int q; cin >> q;
    while(q --)
    {
	  int l, r; cin >> l >> r; l --;
	  cout << 2 * get(l, r, 0, n, 1).first << endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int N = 1e6+1;

char in[N];
int seg[N*4], n, m, vet[N], F;

inline void init()
{
    F = 1;
    while (F < m) F *= 2;
    for (int i = 1; i <= m; ++i) seg[F+i-1] = vet[i];
    for (int i = F-1; i >= 1; --i) seg[i] = min(seg[i*2], seg[i*2+1]);
}

inline int query(int a, int b)
{
    int r = N;
    a += F-1;
    b += F-1;
    while (a <= b)
    {
        if (a&1) r = min(r, seg[a]);
        if (!(b&1)) r = min(r, seg[b]);
        a = (a+1)/2;
        b = (b-1)/2;
    }
    return r;
}

int main()
{
    scanf("%s%d", in, &n);
    for (int i = 0; in[i]; ++i, ++m)
        vet[i+1] = (in[i] == '(' ? 1 : -1) + vet[i];
    init();
    while (n--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        int tot = b-a+1;
        int neg = min(0, query(a, b)-vet[a-1]);
        int ult = vet[b]-vet[a-1];
        printf("%d\n", tot+neg-(ult-neg));
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MX = 1e6+10;
int n , ps1[MX] , ps2[MX] , a[MX] , b[MX];
bool mark[MX];
string s;
vector<int> v;

main(){
	cin >>s;
	for(int i=0;i<s.size();++i)
		if(s[i] == '(')
			mark[i] = 1;

	for(int i=0;i<s.size();++i){
		if(mark[i])
			v.push_back(i);
		else{
			if(v.size() != 0){
				int x = v[v.size()-1];
				v.pop_back();
				a[i+1] = 1;
				b[x+1] = 1;
			}
		}
	}
//	cout <<endl;
	for(int i=1;i<=s.size();++i){
		ps1[i] = ps1[i-1] + a[i];
//		cout <<ps1[i]<<" ";
	}
	for(int i=s.size();i>0;--i){
		ps2[i] = ps2[i+1] + b[i];
	}
//	cout<<endl;
	n = s.size();
	ps1[n+1] = ps1[n];
	cin >>n;
	for(int i=0;i<n;++i){
		int l , r;
		cin >>l >>r;
		cout <<2*(min(ps1[r] - ps1[l] , ps2[l] - ps2[r]) )<<endl;
	}
}


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#define pb push_back
#define ll long long
using namespace std;

#define mp make_pair
#define fi first
#define se second
#define inf ((1<<30)-2)

int pref[2197152];
int sm[1000010];

int gt(int a,int b){
    if(a>b) return 0;
    return sm[b]-sm[a-1];
}

#define left (node<<1)
#define right (left|1)
#define mid ((s+e)>>1)
int cur;
void add(int node,int s,int e,int i,int val){
    if(s>i || e<i) return;
    if(s==e){
        pref[node]=val;
        return;
    }
    add(left,s,mid,i,val);
    add(right,mid+1,e,i,val);
    pref[node]=min(pref[left],gt(max(cur,s),mid)+pref[right]);
}

int get(int node,int s,int e,int j){
    if(s>j) return inf;
    if(e<=j){
        return pref[node];
    }
    int a=get(left,s,mid,j);
    int b=get(right,mid+1,e,j);
    if(b!=inf) b+=gt(max(cur,s),mid);

    return min(a,b);
}

vector<pair<int,int> > qr[1000010];
int ans[100010];
#include<cassert>
int main() {

    string s;cin>>s;
    int n=s.size();
    vector<int> in(s.size());
    for(int i=0;i<in.size();i++)
        in[i]=(s[i]=='(')?1:-1;

    for(int i=1;i<=n;i++) sm[i]+=sm[i-1]+in[i-1];

    int m;cin>>m;
    for(int i=0;i<m;i++){
        int a,b;scanf("%d%d",&a,&b);
        qr[a].pb(mp(b,i));
    }

    int last=0;
    for(int i=n;i>=1;i--){
        cur=i;
        add(1,1,n,i,in[i-1]);
        for(pair<int,int> a : qr[i]){
            int &an=ans[a.se]=a.fi-i+1;
            int minpre=get(1,1,n,a.fi);
            if(minpre<0){
                an+=minpre;
                int su=gt(i,a.fi)-minpre;
                if(su!=0) an-=su;
                assert(su>=0);
            }else{
                int su=gt(i,a.fi);
                if(su!=0) an-=su;
                assert(su>=0);
            }
            assert(an>=0);

        }
    }
    for(int i=0;i<m;i++) printf("%d\n",ans[i]);

    return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#define pb push_back
#define ll long long
using namespace std;

#define mp make_pair
#define fi first
#define se second
#define inf ((1<<30)-2)

int pref[2197152];
int sm[1000010];

int gt(int a,int b){
    return sm[b]-sm[a-1];
}

#define left (node<<1)
#define right (left|1)
#define mid ((s+e)>>1)
int cur;
void add(int node,int s,int e,int i,int val){
    if(s>i || e<i) return;
    if(s==e){
        pref[node]=val;
        return;
    }
    add(left,s,mid,i,val);
    add(right,mid+1,e,i,val);
    pref[node]=min(pref[left],gt(max(cur,s),mid)+pref[right]);
}

int get(int node,int s,int e,int j){
    if(s>j) return inf;
    if(e<=j){
        return pref[node];
    }
    int a=get(left,s,mid,j);
    int b=get(right,mid+1,e,j);
    if(b!=inf) b+=gt(max(cur,s),mid);

    return min(a,b);
}

vector<pair<int,int> > qr[1000010];
int ans[100010];

int main() {
    //freopen("C:\\a","r",stdin);
    string s;cin>>s;
    int n=s.size();
    vector<int> in(s.size());
    for(int i=0;i<in.size();i++)
        in[i]=(s[i]=='(')?1:-1;

    for(int i=1;i<=n;i++) sm[i]+=sm[i-1]+in[i-1];

    int m;cin>>m;
    for(int i=0;i<m;i++){
        int a,b;scanf("%d%d",&a,&b);
        qr[a].pb(mp(b,i));
    }

    int last=0;
    for(int i=n;i>=1;i--){
        cur=i;
        add(1,1,n,i,in[i-1]);
        for(pair<int,int> a : qr[i]){
            int &an=ans[a.se]=a.fi-i+1;
            int minpre=get(1,1,n,a.fi);
            if(minpre<0){
                an+=minpre;
                int su=gt(i,a.fi)-minpre;
                if(su!=0) an-=su;
            }else{
                int su=gt(i,a.fi);
                if(su!=0) an-=su;
            }

        }
    }
    for(int i=0;i<m;i++) printf("%d\n",ans[i]);

    return 0;
}


#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<algorithm>

#define foreach(i,v) for(__typeof((v).begin())i=(v).begin();i<(v).end();++i)

char s[1<<20];
int n,m,ans[1<<17];
std::stack<int> stack;
std::vector<std::pair<int,int> > query[1<<17];

int fen[1<<20];
int read(int x) {
    ++x;
    int ans=0;
    while(x>0) {
        ans+=fen[x];
        x-=(x&-x);
    }
    return ans;
}
void add(int x) {
    ++x;
    while(x<=n) {
        fen[x]++;
        x+=(x&-x);
    }
}

int main() {
    while(scanf("%s",s)==1) {
        n=strlen(s);
        for(int i=0; i<n; ++i) {
            query[i].clear();
        }
        scanf("%d",&m);
        for(int i=0,l,r; i<m; ++i) {
            scanf("%d%d",&l,&r);
            --l,--r;
            query[l].push_back(std::make_pair(r,i));
        }
        while(!stack.empty()) {
            stack.pop();
        }
        std::fill(fen+1,fen+n+1,0);
        for(int i=n-1; i>=0; --i) {
            if(s[i]=='(') {
                if(!stack.empty()) {
                    add(stack.top());
                    stack.pop();
                }
            } else {
                stack.push(i);
            }
            foreach(j,query[i]) {
                ans[(*j).second]=read((*j).first);
            }
        }
        for(int i=0; i<m; ++i) {
            printf("%d\n",ans[i]*2);
        }
    }
    return 0;
}


#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<algorithm>

#define foreach(i,v) for(__typeof((v).begin())i=(v).begin();i<(v).end();++i)

char s[1<<20];
int n,m,ans[1<<17];
std::stack<int> stack;
std::vector<std::pair<int,int> > query[1<<20];

int fen[1<<20];
int read(int x) {
    ++x;
    int ans=0;
    while(x>0) {
        ans+=fen[x];
        x-=(x&-x);
    }
    return ans;
}
void add(int x) {
    ++x;
    while(x<=n) {
        fen[x]++;
        x+=(x&-x);
    }
}

int main() {
    while(scanf("%s",s)==1) {
        n=strlen(s);
        for(int i=0; i<n; ++i) {
            query[i].clear();
        }
        scanf("%d",&m);
        for(int i=0,l,r; i<m; ++i) {
            scanf("%d%d",&l,&r);
            --l,--r;
            query[l].push_back(std::make_pair(r,i));
        }
        while(!stack.empty()) {
            stack.pop();
        }
        std::fill(fen+1,fen+n+1,0);
        for(int i=n-1; i>=0; --i) {
            if(s[i]=='(') {
                if(!stack.empty()) {
                    add(stack.top());
                    stack.pop();
                }
            } else {
                stack.push(i);
            }
            foreach(j,query[i]) {
                ans[(*j).second]=read((*j).first);
            }
        }
        for(int i=0; i<m; ++i) {
            printf("%d\n",ans[i]*2);
        }
    }
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <string>
#define MAXN 1000005
#define mid ((bgn+end)/2)
using namespace std;
struct seq
{
    int sag,sol,tam;
}seg[MAXN*3];
seq yap(int a,int b,int c)
{
    seq pasta;
    pasta.sol=a;
    pasta.sag=b;
    pasta.tam=c;
    return pasta;
}
seq operator+(seq a,seq b)
{
    seq c;
    c.tam=min(a.sol,b.sag);
    a.sol-=c.tam;
    b.sag-=c.tam;
    c.tam+=a.tam+b.tam;
    c.sag=a.sag+b.sag;
    c.sol=a.sol+b.sol;
    return c;
}
int n,m,d[MAXN];
string str;
seq kur(int lvl,int bgn,int end)
{
    if (bgn==end) return seg[lvl]=(str[bgn]=='(') ? yap(1,0,0) : yap(0,1,0);
    return seg[lvl]=kur(lvl*2,bgn,mid)+kur(lvl*2+1,mid+1,end);
}
seq find(int lvl,int bgn,int end,int b,int e)
{
    if (b>end || e<bgn) return yap(0,0,0);
    if (b<=bgn && end<=e) return seg[lvl];
    return find(lvl*2,bgn,mid,b,e)+find(lvl*2+1,mid+1,end,b,e);
}
int main()
{
    cin >> str;
    n=str.size();
    kur(1,0,n-1);
    scanf("%d",&m);
    for (int i=1,a,b;i<=m;i++)
    {
        scanf("%d %d",&a,&b);
        printf("%d\n",2*find(1,0,n-1,a-1,b-1).tam);
    }
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

const int maxn = 1000000 + 100;

char s[maxn];
int n;
int nn;

int a[maxn * 4];
int b[maxn * 4];
int c[maxn * 4];

void createTree(int v, int lv, int rv)
{
    if (lv == rv)
    {
        a[v] = b[v] = c[v] = 0;
        if (lv < n)
        {
            if (s[lv] == '(')
                b[v] = 1;
            else if (s[lv] == ')')
                c[v] = 1;
        }
        return;
    }
    int med = lv + (rv - lv) / 2;
    createTree(2 * v + 1, lv, med);
    createTree(2 * v + 2, med + 1, rv);
    int t = min(b[2 * v + 1], c[2 * v + 2]);
    a[v] = a[2 * v + 1] + a[2 * v + 2] + t;
    b[v] = b[2 * v + 1] + b[2 * v + 2] - t;
    c[v] = c[2 * v + 1] + c[2 * v + 2] - t;
}

struct Elem
{
    int a, b, c;
    Elem (int _a = 0, int _b = 0, int _c = 0): a(_a), b(_b), c(_c) {}
};

Elem getValues(int v, int lv, int rv, int l, int r)
{
    if (lv == l && r == rv)
    {
        return Elem(a[v], b[v], c[v]);
    }
    int med = lv + (rv - lv) / 2;
    if (r <= med)
        return getValues(2 * v + 1, lv, med, l, r);
    if (l >= med + 1)
        return getValues(2 * v + 2, med + 1, rv, l, r);
    Elem e1 = getValues(2 * v + 1, lv, med, l, med);
    Elem e2 = getValues(2 * v + 2, med + 1, rv, med + 1, r);
    int t = min(e1.b, e2.c);
    return Elem(e1.a + e2.a + t, e1.b + e2.b - t, e1.c + e2.c - t);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif

    scanf("%s", &s);
    n = strlen(s);

    nn = 1;
    while (nn < n)
        nn <<= 1;

    createTree(0, 0, nn - 1);

    int m;
    scanf("%d", &m);
    for (int i = 0; i < m; ++i)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        int answer = getValues(0, 0, nn - 1, l - 1, r - 1).a;
        printf("%d\n", answer * 2);
    }

    return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

const int maxn = 1000000 + 100;

char s[maxn];
int n;
int nn;

int a[maxn * 4];
int b[maxn * 4];
int c[maxn * 4];

void createTree(int v, int lv, int rv)
{
    if (lv == rv)
    {
        a[v] = b[v] = c[v] = 0;
        if (s[lv] == '(')
            b[v] = 1;
        else if (s[lv] == ')')
            c[v] = 1;
        return;
    }
    int med = lv + (rv - lv) / 2;
    createTree(2 * v + 1, lv, med);
    createTree(2 * v + 2, med + 1, rv);
    int t = min(b[2 * v + 1], c[2 * v + 2]);
    a[v] = a[2 * v + 1] + a[2 * v + 2] + t;
    b[v] = b[2 * v + 1] + b[2 * v + 2] - t;
    c[v] = c[2 * v + 1] + c[2 * v + 2] - t;
}

struct Elem
{
    int a, b, c;
    Elem (int _a = 0, int _b = 0, int _c = 0): a(_a), b(_b), c(_c) {}
};

Elem getValues(int v, int lv, int rv, int l, int r)
{
    if (lv == l && r == rv)
    {
        return Elem(a[v], b[v], c[v]);
    }
    int med = lv + (rv - lv) / 2;
    if (r <= med)
        return getValues(2 * v + 1, lv, med, l, r);
    if (l >= med + 1)
        return getValues(2 * v + 2, med + 1, rv, l, r);
    Elem e1 = getValues(2 * v + 1, lv, med, l, med);
    Elem e2 = getValues(2 * v + 2, med + 1, rv, med + 1, r);
    int t = min(e1.b, e2.c);
    return Elem(e1.a + e2.a + t, e1.b + e2.b - t, e1.c + e2.c - t);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif

    scanf("%s", &s);
    n = strlen(s);

    nn = 1;
    while (nn < n)
        nn <<= 1;

    createTree(0, 0, nn - 1);

    int m;
    scanf("%d", &m);
    for (int i = 0; i < m; ++i)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        int answer = getValues(0, 0, nn - 1, l - 1, r - 1).a;
        printf("%d\n", answer * 2);
    }

    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#define SIZE 1000005
#define MX 100005

using namespace std;
typedef pair <int,int> P;

struct BIT
{
	int bit[SIZE];
	int n;

	void add(int k,int x)
	{
		while(k<=n)
		{
			bit[k]+=x;
			k+=k&-k;
		}
	}
	int sum(int k)
	{
		int ret=0;
		while(k>0)
		{
			ret+=bit[k];
			k-=k&-k;
		}
		return ret;
	}
};
BIT bit;
vector <P> vec[SIZE];
int rui[SIZE],ans[SIZE];
int tg[SIZE];
char str[SIZE];
int n;

int main()
{
	scanf("%s",&str);
	n=strlen(str);
	int mn=0;
	for(int i=0;i<n;i++)
	{
		rui[i]=str[i]=='('?1:-1;
		if(i>0) rui[i]+=rui[i-1];
		mn=min(mn,rui[i]);
	}
	for(int i=0;i<n;i++) rui[i]-=mn;
	stack <int> st;
	for(int i=0;i<n;i++)
	{
		tg[i]=-1;
		if(str[i]=='(') st.push(i);
		else
		{
			if(!st.empty())
			{
				int tp=st.top();st.pop();
				tg[tp]=i;
			}
		}
	}
	bit.n=n+2;
	int m;
	scanf("%d",&m);
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(P(b,i));
	}
	for(int i=n-1;i>=0;i--)
	{
		if(tg[i]>=0) bit.add(tg[i]+1,1);
		for(int j=0;j<vec[i].size();j++)
		{
			P p=vec[i][j];
			ans[p.second]=bit.sum(p.first+1);
		}
	}
	for(int i=0;i<m;i++) printf("%d\n",ans[i]*2);
	return 0;
}


#include <stdio.h>
#include <string.h>
#define MAXN 1000005
using namespace std;

typedef struct {
	int o, c, mn;
} aint_node;

aint_node ai[4 * MAXN], sol;
char s[MAXN];
int n, nrq, lq, rq, lasto;

inline int MIN(int a, int b){
	return (a < b)?a:b;
}

void build_ai(int nod, int l, int r);
void query_ai(int nod, int l, int r);

void print_ai(int nod, int l, int r){
	printf("%d %d: \nmn: %d  o: %d   c: %d\n\n", l, r, ai[nod].mn, ai[nod].o, ai[nod].c);

	if(l == r)
		return;

	int mid = (l + r) / 2;
	print_ai(2 * nod, l, mid);
	print_ai(2 * nod + 1, mid + 1, r);
}

int main(){
	int i;

	gets(s + 1);
	n = strlen(s + 1);

	build_ai(1, 1, n);

	//print_ai(1, 1, n);

	scanf("%d", &nrq);
	while(nrq--){
		scanf("%d %d", &lq, &rq);
		sol = {0, 0, 0};
		query_ai(1, 1, n);
		printf("%d\n", 2 * sol.mn);
	}
	return 0;
}

void build_ai(int nod, int l, int r){
	if(l == r){
		ai[nod].mn = ai[nod].o = ai[nod].c = 0;
		if(s[l] == '(')		ai[nod].o = 1;
		else	ai[nod].c = 1;
		return;
	}
	int mid = (l + r) >> 1;

	build_ai(2 * nod, l, mid);
	build_ai(2 * nod + 1, mid + 1, r);

	int x = MIN(ai[2 * nod].o, ai[2 * nod + 1].c);
	ai[nod].mn = ai[2 * nod].mn + ai[2 * nod + 1].mn + x;
	ai[nod].o = ai[2 * nod].o + ai[2 * nod + 1].o - x;
	ai[nod].c = ai[2 * nod].c + ai[2 * nod + 1].c - x;
}

void query_ai(int nod, int l, int r){
	if(l >= lq && r <= rq){
		int x = MIN(sol.o, ai[nod].c);
		sol.mn += ai[nod].mn + x;
		sol.o += ai[nod].o - x;
		sol.c += ai[nod].c - x;
		return;
	}

	int mid = (l + r) >> 1;

	if(lq <= mid)
		query_ai(2 * nod, l, mid);
	if(rq >= mid + 1)
		query_ai(2 * nod + 1, mid + 1, r);
}


#include<bits/stdc++.h>

#define IT(a,it) for(auto it=a.begin(); it != a.end(); it++)
#define REV_IT(a,it) for(auto it=a.rbegin(); it != a.rend(); it++)
#define LL long long
#define LD long double
#define MP make_pair
#define FF first
#define SS second
#define PB push_back
#define INF (int)(1e9)
#define EPS (double)(1e-9)

#ifndef ONLINE_JUDGE
#  define LOG(x) cerr << #x << " = " << (x) << endl
#else
#  define LOG(x) 0
#endif

#define MAXX 6000006

using namespace std;

typedef pair <int, int> pi_i;
typedef pair<int, pi_i> pi_ii;

bool cmp(int a, int b){ return a>b; }
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a * b / gcd(a, b); }

int ST[MAXX], OP[MAXX], CL[MAXX], k;
//char s[MAXX];
string s;

void build(int idx, int start, int end){
	//cout<<start<<" "<<end<<" "<<" "<<idx<<endl;
	if(start == end){
		ST[idx] = 0;
		if(s[start] == '(') OP[idx] = 1;
		else CL[idx] = 1;return;
	}
	int mid = (start+end)/2;
	build(2*idx, start, mid);
	build(2*idx+1, mid+1, end);

	int temp = min( OP[2*idx], CL[2*idx+1] );
	ST[idx] = ST[2*idx] + ST[2*idx+1] + temp;
	OP[idx] = OP[2*idx] + OP[2*idx+1] - temp;
	CL[idx] = CL[2*idx] + CL[2*idx+1] - temp;
}

pi_ii query(int idx, int start, int end, int L, int R){
	if(R < start || L > end) return MP(0, MP(0, 0));
	if(L <= start && R >= end){
		//cout<<start<<" "<<end<<" "<<L<<" "<<R<<" "<<idx<<endl;
		return MP( ST[idx] , MP( OP[idx] , CL[idx] ) );
	}
	pi_ii p1 = MP(0, MP(0, 0)), p2 = MP(0, MP(0, 0)), p3 = MP(0, MP(0, 0));
	int mid = (start+end)/2;
	p1 = query(2*idx, start, mid, L, R);
	p2 = query(2*idx+1, mid+1, end, L, R);

	int temp = min( p1.SS.FF, p2.SS.SS );
	int t1 = p1.FF + p2.FF + temp;
	int t2 = p1.SS.FF + p2.SS.FF - temp;
	int t3 = p1.SS.SS + p2.SS.SS - temp;
	return MP( t1 , MP( t2, t3) );
}

int main(){
	ios_base::sync_with_stdio(false);
	//freopen("out.txt","w",stdout);

	cin>>s;
	cin>>k;
	build(1, 0, s.size()-1);

	int ll, rr;
	while( k-- ){
		cin>>ll>>rr;
		ll--;rr--;
		pi_ii pp = query(1, 0, s.size()-1, ll, rr);
		cout<<2*pp.FF<<endl;
	}

return 0;
}


#include <iomanip>
#include <iostream>
#include <utility>
#include <algorithm>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>

using namespace std;

/* CHECKLIST
 * 1) long longs
 * 2) lower_bound etc - out of bound
 * */

const int DBG = 0, INF = int(1e9);

#include <memory>
template<class T>
class AvlTree {
   struct Node {
      Node(T val, shared_ptr<const Node> left, shared_ptr<const Node> right, int height, int size):
         val(val), left(left), right(right), height(height), size(size) {}
      T val;
      shared_ptr<const Node> left, right;
      int height;
      int size; // number of elements in a subtree
   };
   typedef shared_ptr<const Node> Tree;
   friend inline int height(const Tree& t) {
      if (!t) return 0;
      return t->height;
   }
   friend inline int siz(const Tree& t) {
      if (!t) return 0;
      return t->size;
   }
   friend inline int rootCount(const Tree& t) {
      if (!t) return 0;
      return t->size - siz(t->left) - siz(t->right);
   }
   friend inline bool isBalanced(const Tree& t) {
      if (!t) return true;
      return abs(height(t->left) - height(t->right)) <= 2;
   }
   friend inline Tree create(const Tree& left, T val, int count, const Tree& right) {
      //assert(isBalanced(left));
      //assert(isBalanced(right));
      //assert(!left || maxElem(left) < val); // TODO comment out, this is costly
      //assert(!right || val < minElem(right)); // TODO comment out, this is costly
      //assert(abs(height(left) - height(right)) <= 2);
      return make_shared<Node>(val, left, right, max(height(left), height(right)) + 1,
         siz(left) + siz(right) + count);
   }
   friend Tree createAndBalance(const Tree& left, T val, int count, const Tree& right) {
      //assert(isBalanced(left));
      //assert(isBalanced(right));
      //assert(!left || maxElem(left) < val); // TODO comment out, this is costly
      //assert(!right || val < minElem(right)); // TODO comment out, this is costly
      //assert(abs(height(left) - height(right)) <= 3);
      if (height(left) > height(right) + 2) {
         //assert(left);
         if (height(left->left) >= height(left->right)) return
            create(
               left->left,
               left->val,
               rootCount(left),
               create(left->right, val, count, right)
            );
         //assert(left->right);
         return create(
            create(left->left, left->val, rootCount(left), left->right->left),
            left->right->val,
            rootCount(left->right),
            create(left->right->right, val, count, right)
         );
      }
      if (height(left) + 2 < height(right)) {
         //assert(right);
         if (height(right->left) <= height(right->right)) return
            create(
               create(left, val, count, right->left),
               right->val,
               rootCount(right),
               right->right
            );
         //assert(right->left);
         return create(
            create(left, val, count, right->left->left),
            right->left->val,
            rootCount(right->left),
            create(right->left->right, right->val, rootCount(right), right->right)
         );
      }
      // inline expansion of create for better speed in the most frequent case
      // where no rebalancing is required
      return make_shared<Node>(val, left, right, max(height(left), height(right)) + 1,
         siz(left) + siz(right) + count);
   }

   friend Tree add(const Tree& t, T val) {
      if (!t) return make_shared<Node>(val, shared_ptr<Node>(), shared_ptr<Node>(), 1, 1);
      if (val == t->val) return make_shared<Node>(val, t->left, t->right,
         t->height, t->size + 1);
      if (val < t->val) return
         createAndBalance(add(t->left, val), t->val, rootCount(t), t->right);
      return createAndBalance(t->left, t->val, rootCount(t), add(t->right, val));
   }

   friend T minElem(const Tree& t) {
      //assert(t);
      if (!t->left) return t->val;
      return minElem(t->left);
   }

   friend T maxElem(const Tree& t) {
      //assert(t);
      if (!t->right) return t->val;
      return maxElem(t->right);
   }

   // number of occurences of smallest element in the t
   friend int minElemOccur(const Tree& t) {
      //assert(t);
      if (!t->left) return rootCount(t);
      return minElemOccur(t->left);
   }

   // remove ALL occurences of the smallest element in the t
   friend Tree removeMinElem(const Tree& t) {
      //assert(t);
      if (!t->left) return t->right;
      return createAndBalance(removeMinElem(t->left), t->val, rootCount(t), t->right);
   }

   friend Tree merge(const Tree& t1, const Tree& t2) {
      //assert(!t1 || !t2 || maxElem(t1) < minElem(t2));
      //assert(abs(height(t1) - height(t2)) <= 2);
      if (!t1) return t2;
      if (!t2) return t1;
      return createAndBalance(t1, minElem(t2), minElemOccur(t2), removeMinElem(t2));
   }

   friend int count(const Tree& t, T val) {
      if (!t) return 0;
      if (t->val == val) return rootCount(t);
      if (val < t->val) return count(t->left, val);
      return count(t->right, val);
   }

   friend int countSmall(const Tree& t, T val) {
      if (!t) return 0;
      if (t->val == val) return siz(t->left);
      if (val < t->val) return countSmall(t->left, val);
      return siz(t->left) + rootCount(t) + countSmall(t->right, val);
   }

   friend int countBig(const Tree& t, T val) {
      if (!t) return 0;
      if (val == t->val) return siz(t->right);
      if (t->val < val) return countBig(t->right, val);
      return siz(t->right) + rootCount(t) + countBig(t->left, val);
   }

   friend Tree remove(const Tree& t, T val) {
      if (!t) return t;
      if (val < t->val)
         return createAndBalance(remove(t->left, val), t->val, rootCount(t), t->right);
      if (val > t->val)
         return createAndBalance(t->left, t->val, rootCount(t), remove(t->right, val));
      if (rootCount(t) > 1)
         return make_shared<Node>(t->val, t->left, t->right, t->height, t->size - 1);
      return merge(t->left, t->right);
   }

   shared_ptr<const Node> t;

   explicit AvlTree(shared_ptr<const Node> node) : t(node) {}

   public:
      AvlTree(): t(shared_ptr<const Node>()) {}
      int size() const { return siz(t); }
      bool empty() const { return t ? false : true; }
      int count(T val) const { return count(t, val); }
      int countSmaller(T val) const { return countSmall(t, val); }
      int countBigger(T val) const { return countBig(t, val); }
      AvlTree insert(T val) const { return AvlTree(add(t, val)); }
      AvlTree erase(T val) const { return AvlTree(remove(t, val)); }

      friend void swap(AvlTree<T>& s1, AvlTree<T>& s2) { swap(s1.t, s2.t); }
};

int main() {
   ios_base::sync_with_stdio(0);
   cout.setf(ios::fixed);
   string s; cin >> s;
   int m; cin >> m;
   vector<pair<pair<int, int>, int>> q(m);
   for (auto& it: q) cin >> it.first.first >> it.first.second;
   for (int i = 0; i < m; ++i) q[i].second = i;
   for (auto& it: q) swap(--it.first.first, --it.first.second);
   sort(q.begin(), q.end());
   AvlTree<int> matches;
   vector<int> st;
   int pos = 0;
   vector<int> result(m);
   for (auto& it: q) {
      int l = it.first.second, r = it.first.first, tc = it.second;
      for (;pos <= r; ++pos) {
         //cout << pos << " " << r << endl;
         if (s[pos] == '(') {
            st.push_back(pos);
            continue;
         }
         if (st.empty()) continue;
         matches = matches.insert(st.back());
         st.pop_back();
      }
      result[tc] = 2 * matches.countBigger(l - 1);
   }
   for (auto it: result) cout << it << endl;
   return 0;
}


#include <iomanip>
#include <iostream>
#include <utility>
#include <algorithm>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>

using namespace std;

/* CHECKLIST
 * 1) long longs
 * 2) lower_bound etc - out of bound
 * */

const int DBG = 0, INF = int(1e9);

int bin(int n) {
   int m = 1;
   while (m <= n) m *= 2;
   return m;
}

class CountTree {
   int M;
   vector<int> w;
   public:
   CountTree(int n) : M(bin(n)), w(vector<int>(2 * bin(n))) {}
   void insert(int v) {
      v += M;
      while (v > 0) {
         w[v]++;
         v /= 2;
      }
   }
   int query(int a, int b) {
      a += M, b += M;
      int res = w[a];
      if (a != b) res += w[b];
      while (a / 2 != b / 2) {
         if (a % 2 == 0) res += w[a + 1];
         if (b % 2 == 1) res += w[b - 1];
         a /= 2, b /= 2;
      }
      return res;
   }
};

int main() {
   ios_base::sync_with_stdio(0);
   cout.setf(ios::fixed);
   string s; cin >> s;
   int m; cin >> m;
   vector<pair<pair<int, int>, int>> q(m);
   for (auto& it: q) cin >> it.first.first >> it.first.second;
   for (int i = 0; i < m; ++i) q[i].second = i;
   for (auto& it: q) swap(--it.first.first, --it.first.second);
   sort(q.begin(), q.end());
   CountTree matches(s.size());
   vector<int> st;
   int pos = 0;
   vector<int> result(m);
   for (auto& it: q) {
      int l = it.first.second, r = it.first.first, tc = it.second;
      for (; pos <= r; ++pos) {
         if (s[pos] == '(') {
            st.push_back(pos);
            continue;
         }
         if (st.empty()) continue;
         matches.insert(st.back());
         st.pop_back();
      }
      result[tc] = 2 * matches.query(l, r);
   }
   for (auto it: result) cout << it << endl;
   return 0;
}


#include <iomanip>
#include <iostream>
#include <utility>
#include <algorithm>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>

using namespace std;

/* CHECKLIST
 * 1) long longs
 * 2) lower_bound etc - out of bound
 * */

const int DBG = 0, INF = int(1e9);

#include <memory>
template<class T>
class AvlTree {
   struct Node {
      Node(T val, shared_ptr<const Node> left, shared_ptr<const Node> right, int height, int size):
         val(val), left(left), right(right), height(height), size(size) {}
      T val;
      shared_ptr<const Node> left, right;
      int height;
      int size; // number of elements in a subtree
   };
   typedef shared_ptr<const Node> Tree;
   friend inline int height(const Tree& t) {
      if (!t) return 0;
      return t->height;
   }
   friend inline int siz(const Tree& t) {
      if (!t) return 0;
      return t->size;
   }
   friend inline int rootCount(const Tree& t) {
      if (!t) return 0;
      return t->size - siz(t->left) - siz(t->right);
   }
   friend inline bool isBalanced(const Tree& t) {
      if (!t) return true;
      return abs(height(t->left) - height(t->right)) <= 2;
   }
   friend inline Tree create(const Tree& left, T val, int count, const Tree& right) {
      //assert(isBalanced(left));
      //assert(isBalanced(right));
      //assert(!left || maxElem(left) < val); // TODO comment out, this is costly
      //assert(!right || val < minElem(right)); // TODO comment out, this is costly
      //assert(abs(height(left) - height(right)) <= 2);
      return make_shared<Node>(val, left, right, max(height(left), height(right)) + 1,
         siz(left) + siz(right) + count);
   }
   friend Tree createAndBalance(const Tree& left, T val, int count, const Tree& right) {
      //assert(isBalanced(left));
      //assert(isBalanced(right));
      //assert(!left || maxElem(left) < val); // TODO comment out, this is costly
      //assert(!right || val < minElem(right)); // TODO comment out, this is costly
      //assert(abs(height(left) - height(right)) <= 3);
      if (height(left) > height(right) + 2) {
         //assert(left);
         if (height(left->left) >= height(left->right)) return
            create(
               left->left,
               left->val,
               rootCount(left),
               create(left->right, val, count, right)
            );
         //assert(left->right);
         return create(
            create(left->left, left->val, rootCount(left), left->right->left),
            left->right->val,
            rootCount(left->right),
            create(left->right->right, val, count, right)
         );
      }
      if (height(left) + 2 < height(right)) {
         //assert(right);
         if (height(right->left) <= height(right->right)) return
            create(
               create(left, val, count, right->left),
               right->val,
               rootCount(right),
               right->right
            );
         //assert(right->left);
         return create(
            create(left, val, count, right->left->left),
            right->left->val,
            rootCount(right->left),
            create(right->left->right, right->val, rootCount(right), right->right)
         );
      }
      // inline expansion of create for better speed in the most frequent case
      // where no rebalancing is required
      return make_shared<Node>(val, left, right, max(height(left), height(right)) + 1,
         siz(left) + siz(right) + count);
   }

   friend Tree add(const Tree& t, T val) {
      if (!t) return make_shared<Node>(val, shared_ptr<Node>(), shared_ptr<Node>(), 1, 1);
      if (val == t->val) return make_shared<Node>(val, t->left, t->right,
         t->height, t->size + 1);
      if (val < t->val) return
         createAndBalance(add(t->left, val), t->val, rootCount(t), t->right);
      return createAndBalance(t->left, t->val, rootCount(t), add(t->right, val));
   }

   friend T minElem(const Tree& t) {
      //assert(t);
      if (!t->left) return t->val;
      return minElem(t->left);
   }

   friend T maxElem(const Tree& t) {
      //assert(t);
      if (!t->right) return t->val;
      return maxElem(t->right);
   }

   // number of occurences of smallest element in the t
   friend int minElemOccur(const Tree& t) {
      //assert(t);
      if (!t->left) return rootCount(t);
      return minElemOccur(t->left);
   }

   // remove ALL occurences of the smallest element in the t
   friend Tree removeMinElem(const Tree& t) {
      //assert(t);
      if (!t->left) return t->right;
      return createAndBalance(removeMinElem(t->left), t->val, rootCount(t), t->right);
   }

   friend Tree merge(const Tree& t1, const Tree& t2) {
      //assert(!t1 || !t2 || maxElem(t1) < minElem(t2));
      //assert(abs(height(t1) - height(t2)) <= 2);
      if (!t1) return t2;
      if (!t2) return t1;
      return createAndBalance(t1, minElem(t2), minElemOccur(t2), removeMinElem(t2));
   }

   friend int count(const Tree& t, T val) {
      if (!t) return 0;
      if (t->val == val) return rootCount(t);
      if (val < t->val) return count(t->left, val);
      return count(t->right, val);
   }

   friend int countSmall(const Tree& t, T val) {
      if (!t) return 0;
      if (t->val == val) return siz(t->left);
      if (val < t->val) return countSmall(t->left, val);
      return siz(t->left) + rootCount(t) + countSmall(t->right, val);
   }

   friend int countBig(const Tree& t, T val) {
      if (!t) return 0;
      if (val == t->val) return siz(t->right);
      if (t->val < val) return countBig(t->right, val);
      return siz(t->right) + rootCount(t) + countBig(t->left, val);
   }

   friend Tree remove(const Tree& t, T val) {
      if (!t) return t;
      if (val < t->val)
         return createAndBalance(remove(t->left, val), t->val, rootCount(t), t->right);
      if (val > t->val)
         return createAndBalance(t->left, t->val, rootCount(t), remove(t->right, val));
      if (rootCount(t) > 1)
         return make_shared<Node>(t->val, t->left, t->right, t->height, t->size - 1);
      return merge(t->left, t->right);
   }

   shared_ptr<const Node> t;

   explicit AvlTree(shared_ptr<const Node> node) : t(node) {}

   public:
      AvlTree(): t(shared_ptr<const Node>()) {}
      int size() const { return siz(t); }
      bool empty() const { return t ? false : true; }
      int count(T val) const { return count(t, val); }
      int countSmaller(T val) const { return countSmall(t, val); }
      int countBigger(T val) const { return countBig(t, val); }
      AvlTree insert(T val) const { return AvlTree(add(t, val)); }
      AvlTree erase(T val) const { return AvlTree(remove(t, val)); }

      friend void swap(AvlTree<T>& s1, AvlTree<T>& s2) { swap(s1.t, s2.t); }
};

int main() {
   ios_base::sync_with_stdio(0);
   cout.setf(ios::fixed);
   string s; cin >> s;
   int m; cin >> m;
   vector<pair<pair<int, int>, int>> q(m);
   for (auto& it: q) cin >> it.first.first >> it.first.second;
   for (int i = 0; i < m; ++i) q[i].second = i;
   for (auto& it: q) swap(--it.first.first, --it.first.second);
   sort(q.begin(), q.end());
   AvlTree<int> matches;
   vector<int> st;
   int pos = 0;
   vector<int> result(m);
   for (auto& it: q) {
      int l = it.first.second, r = it.first.first, tc = it.second;
      for (; pos <= r; ++pos) {
         if (s[pos] == '(') {
            st.push_back(pos);
            continue;
         }
         if (st.empty()) continue;
         matches = matches.insert(st.back());
         st.pop_back();
      }
      result[tc] = 2 * matches.countBigger(l - 1);
   }
   for (auto it: result) cout << it << endl;
   return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define INF 1000000000000000000
#define MOD 1000000007

using namespace std;

string s;
int n, l, r;
struct node{
    int a, b, c;
} st[4000001];
node comp(node A, node B) {
    node ans;
    int X = min(A.b, B.c);
    ans.a = A.a + B.a + X * 2;
    ans.b = A.b + B.b - X;
    ans.c = A.c + B.c - X;
    return ans;
}
void build(int v, int l, int r) {
    if (l == r) {
        if (s[l - 1] == '(') st[v].b = 1;
        else st[v].c = 1;
        return;
    }
    int mid = (l + r) / 2;
    build(v * 2, l, mid);
    build(v * 2 + 1, mid + 1, r);
    st[v] = comp(st[v * 2], st[v * 2 + 1]);
}
node qr(int v, int A, int B, int l, int r) {
    node ans;
    ans.a = ans.b = ans.c = 0;
    if (l > B || r < A) return ans;
    if (A == l && B == r) return st[v];
    int mid = (A + B) / 2;
    node L = qr(v * 2, A, mid, l, min(mid, r));
    node R = qr(v * 2 + 1, mid + 1, B, max(mid + 1, l), r);
    return comp(L, R);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin >> s;
    cin >> n;
    build(1, 1, s.length());
    while (n--) {
        cin >> l >> r;
        cout << qr(1, 1, s.length(), l, r).a << endl;
    }

    return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#define For(i,n) for(int i=1; i<=n; i++)
#define mid ((l+r)>>1)
#define lc (o<<1)
#define rc (o<<1|1)
#define N 1000000

using namespace std;

char brackets[N+10];
int a[N<<2],b[N<<2],c[N<<2];
void build(int o,int l,int r){
  if(l==r){
    a[o]=b[o]=c[o]=0;
    if(brackets[l]=='(')a[o]=1;
    else b[o]=1;
    return;
  }
  build(lc,l,mid);
  build(rc,mid+1,r);
  c[o]=c[lc]+c[rc]+min(a[lc],b[rc]);
  a[o]=a[lc]+a[rc]-min(a[lc],b[rc]);
  b[o]=b[lc]+b[rc]-min(a[lc],b[rc]);
}
int L,R;
struct Ans{
  int a,b,c;
  Ans(){a=b=c=0;}
};
void update(Ans& o,Ans l,Ans r){
  o.c=l.c+r.c+min(l.a,r.b);
  o.a=l.a+r.a-min(l.a,r.b);
  o.b=l.b+r.b-min(l.a,r.b);
}
Ans query(int o,int l,int r){
  //printf("%d %d\n",l,r);
  Ans ret;
  if(L>r||R<l)return ret;
  if(L<=l&&r<=R){
    ret.a=a[o];
    ret.b=b[o];
    ret.c=c[o];
    return ret;
  }
  Ans lret,rret;
  lret=query(lc,l,mid);
  rret=query(rc,mid+1,r);
  update(ret,lret,rret);
  return ret;
}
int n,m;
int main(){
#ifndef ONLINE_JUDGE
  freopen("in.txt","r",stdin);
#endif
  scanf("%s",brackets+1);
  n=strlen(brackets+1);
  build(1,1,n);
  scanf("%d",&m);
  For(i,m){
    scanf("%d%d",&L,&R);
    printf("%d\n",query(1,1,n).c<<1);
  }
  return 0;

}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<string>
using namespace std;
#define rep(i,f,t) for(int i = (f),end_##i = (t); i < end_##i; ++i)
//#define ONLINE_JUDGE
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
char s[1000 * 1000 + 11];
ll baz[1000 * 1000 + 1], bas[1000 * 1000 + 1];

ll dfs(int x, int y){
	if (x >= y) return 0;
	int t = (x + y) / 2;
	ll lft = dfs(x, t), rit = dfs(t + 1, y);
	ll aa = baz[t] - (x == 0 ? 0 : baz[x - 1]) - lft / 2,
		bb = bas[y] - (t == 0 ? 0 : bas[t - 1]) - rit / 2;
	return lft + rit + 2 * min(aa, bb);
	//return dfs(x, t) + dfs(t + 1, y) + min(baz[t] - (x == 0 ? 0 : baz[x - 1]), bas[y] - (t == 0 ? 0 : bas[t - 1]));
}

void __main() {
	gets(s);
	char *sp = s;
	int i = 1;
	baz[0] = *sp == '(';
	bas[0] = *sp == ')';
	++sp;
	while (*sp)
		baz[i] = baz[i - 1] + (*sp == '('),
		bas[i] = bas[i - 1] + (*sp == ')'),
		++i,
		++sp;
	int m; scanf("%d", &m);
	int x, y;
	rep(i, 0, m){
		scanf("%d%d", &x, &y);
		cout << dfs(x - 1, y - 1) << endl;
	}
}

int main(){
#ifndef ONLINE_JUDGE
	FILE* fin = NULL;
	fin = fopen("in.txt", "w+");
	fprintf(fin, "())(())(())(\n7\n1 1\n2 3\n1 2\n1 12\n8 12\n5 11\n2 10\n");
	fclose(fin);
	freopen("in.txt", "r", stdin);
	printf("Test Case #1 ...\n\tExpected: ");
	printf("0\n0\n2\n10\n4\n6\n6\n");
	printf("\tReceived: ");
	__main();
	printf("\n");
#else
	__main();
#endif

	return 0;
}


#ifndef do_not_compile_this_file
#include<iostream>
#include<algorithm>
#include<climits>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<deque>
#include<set>
#include<map>
using namespace std;
#define rep(i,f,t) for(int i = (f),end_##i = (t); i < end_##i; ++i)
#define all(v) begin(v),end(v)

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
const int Mx = 1000 * 1000 + 10;
int dp[Mx][21], op[Mx][21], cl[Mx][21];
char a[Mx];

void __main() {
	scanf("%s", a);
	int n = strlen(a);
	rep(i, 0, n)
		op[i][0] = (a[i] == '('),
		cl[i][0] = (a[i] == ')');

	for (int j = 1; (1 << j) <= n; ++j)  for (int i = 0; i + (1 << j) <= n; ++i){
		int k = i + (1 << (j - 1));
		int dif = min(op[i][j - 1], cl[k][j - 1]);
		dp[i][j] = dp[i][j - 1] + dp[k][j - 1] + 2 * dif;
		op[i][j] = op[i][j - 1] + op[k][j - 1] - dif;
		cl[i][j] = cl[i][j - 1] + cl[k][j - 1] - dif;
	}
	int m; scanf("%d", &m);
	rep(i, 0, m){
		int x, y; scanf("%d %d", &x, &y); --x;
		int j = 20, tdp = 0, top = 0;
		while (x < y && j >= 0){
			if (y - x >= (1 << j)){
				int dif = min(top, cl[x][j]);
				top += op[x][j] - dif;
				tdp += dp[x][j] + 2 * dif;
				x += (1 << j);
			}
			--j;
		}
		printf("%d\n", tdp);
	}
}

//#define ONLINE_JUDGE
int main(){
#ifndef ONLINE_JUDGE
	FILE* fin = NULL;
	fin = fopen("in.txt", "w+");
	fprintf(fin, "())(())(())(\n7\n1 1\n2 3\n1 2\n1 12\n8 12\n5 11\n2 10\n");
	fclose(fin);
	freopen("in.txt", "r", stdin);
	printf("Test Case #1 ...\n\tExpected: ");
	printf("0\n0\n2\n10\n4\n6\n6\n");
	printf("\tReceived: ");
	__main();
	printf("\n");
#else
	__main();
#endif

	return 0;
}
#endif


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<string>
using namespace std;
#define rep(i,f,t) for(int i = (f),end_##i = (t); i < end_##i; ++i)

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
char s[1000 * 1000 + 11];
ll baz[1000 * 1000 + 1], bas[1000 * 1000 + 1];

ll dfs(int x, int y){
	if (x >= y) return 0;
	int t = (x + y) / 2;
	ll lft = dfs(x, t), rit = dfs(t + 1, y);
	ll aa = baz[t] - (x == 0 ? 0 : baz[x - 1]) - lft/2,
		bb = bas[y] - (t == 0 ? 0 : bas[t - 1]) - rit/2;
	return lft + rit + 2 * min(aa, bb);
	//return dfs(x, t) + dfs(t + 1, y) + min(baz[t] - (x == 0 ? 0 : baz[x - 1]), bas[y] - (t == 0 ? 0 : bas[t - 1]));
}

void __main() {
	gets(s);
	char *sp = s;
	int i = 1;
	baz[0] = *sp == '(';
	bas[0] = *sp == ')';
	++sp;
	while (*sp)
		baz[i] = baz[i - 1] + (*sp == '('),
		bas[i] = bas[i - 1] + (*sp == ')'),
		++i,
		++sp;
	int m; scanf("%d", &m);
	int x, y;
	rep(i, 0, m){
		scanf("%d%d", &x, &y);
		cout << dfs(x - 1, y - 1) << endl;
	}
}

int main(){
#ifndef UNLINE_JUDGE
	FILE* fin = NULL;
	fin = fopen("in.txt", "w+");
	fprintf(fin, "())(())(())(\n7\n1 1\n2 3\n1 2\n1 12\n8 12\n5 11\n2 10\n");
	fclose(fin);
	freopen("in.txt", "r", stdin);
	printf("Test Case #1 ...\n\tExpected: ");
	printf("0\n0\n2\n10\n4\n6\n6\n");
	printf("\tReceived: ");
	__main();
	printf("\n");
#else
	__main();
#endif

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstdio>
#include <set>
#include <queue>
#include <cassert>
#include <climits>
using namespace std;
char S[1000005];
int L[1000005], R[1000005];
int main() {
	int M, n = 0, m = 0;
	scanf("%s%d", S, &M);
	for (int i = 0; i < strlen(S); ++i) {
		if (S[i] == '(') L[n++] = i + 1;
		else if (m < n) R[m++] = i + 1;
	}
	while (m < n) R[m++] = INT_MAX;
	while (M--) {
		int l, r;
		scanf("%d%d", &l, &r);
		int start = lower_bound(L, L + n, l) - L;
		int ans = upper_bound(R + start, R + n, r) - R - start;
		printf("%d\n", ans * 2);
	}
}


#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstdio>
#include <set>
#include <queue>
#include <tuple>
#include <cassert>
#include <climits>
using namespace std;
const int MAXB = (1 << 21);
char S[1000005];
int hangs[MAXB][2], pairs[MAXB];
void update(int sn, int s, int e, int p, bool type) {
	if (s == e) {
		hangs[sn][type] = 1;
		return;
	}
	int m = (s + e) / 2, lsn = sn * 2 + 1, rsn = sn * 2 + 2;
	if (p <= m) update(lsn, s, m, p, type);
	else update(rsn, m + 1, e, p, type);
	int extras = min(hangs[lsn][0], hangs[rsn][1]);
	pairs[sn] = pairs[lsn] + pairs[rsn] + extras;
	hangs[sn][0] = hangs[lsn][0] + hangs[rsn][0] - extras;
	hangs[sn][1] = hangs[lsn][1] + hangs[rsn][1] - extras;
}
void query(int sn, int s, int e, int qs, int qe, int &a, int &b, int &c) {
	if (qs <= s && e <= qe) {
		a = pairs[sn];
		b = hangs[sn][0];
		c = hangs[sn][1];
		return;
	}
	int m = (s + e) / 2, lsn = sn * 2 + 1, rsn = sn * 2 + 2, ta, tb, tc;
	a = b = c = 0;
	int extras = 0;
	if (qs <= m) {
		query(lsn, s, m, qs, qe, ta, tb, tc);
		a += ta;
		b += tb;
		c += tc;
		extras = tb;
	}
	if (qe > m) {
		query(rsn, m + 1, e, qs, qe, ta, tb, tc);
		a += ta;
		b += tb;
		c += tc;
		extras = min(extras, tc);
	} else {
		extras = 0;
	}
	a += extras;
	b -= extras;
	c -= extras;
}
int main() {
	int M;
	scanf("%s%d", S, &M);
	int N = strlen(S);
	for (int i = 0; i < N; ++i) {
		update(0, 1, N, i + 1, S[i] == ')');
	}
	while (M--) {
		int l, r, a, b, c;
		scanf("%d%d", &l, &r);
		query(0, 1, N, l, r, a, b, c);
		printf("%d\n", a * 2);
	}
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <cassert>
#include <memory>
#include <thread>
using namespace std;

#define INF 1e+9

#define MAXN 1000100

char str[MAXN];
int n;
int bal[MAXN];

struct stree{
    int l, r;
    int min;
    stree * lt, * rt;
};

stree * create(int l, int r) {
    int m = (l + r) / 2;
    stree * s;
    if (l + 1 == r) {
        s = new stree();
        s->l = l;
        s->r = r;
        s->lt = s->rt = 0;
        s->min = bal[l];
    } else {
        s = new stree();
        s->l = l;
        s->r = r;
        s->lt = create(l, m);
        s->rt = create(m, r);
        s->min = min(s->lt->min, s->rt->min);
    }
    return s;
}

int ssize = 0;

int getmin(stree * root, int l, int r) {
    if (root == 0 || root->l >= r || root->r <= l) return 1e+9;
    if (l <= root->l && root->r <= r) return root->min;
    return min(getmin(root->lt, l, r), getmin(root->rt, l, r));
}

int main() {
    ios_base::sync_with_stdio(false);
    gets(str);
    n = strlen(str);
    int b = 0;
    memset(bal, 0, sizeof bal);
    for (int i = 0; i < n; i++) {
        bal[i] = b;
        if (str[i] == '(') b++;
        else b--;
    }
    bal[n] = b;
    stree * s = create(0, n + 1);
    int m; scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d%d", &l, &r);
        int bmin = getmin(s, l - 1, r + 1);
        cout <<  (r - l + 1 - ((bal[l - 1] - bmin) + (bal[r] - bmin))) << "\n";
    }
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <cassert>
#include <memory>
#include <thread>
using namespace std;

#define INF 1e+9

#define MAXN 1000100

char str[MAXN];
int n;
int bal[MAXN];

struct stree{
    int l, r;
    int min;
    stree * lt, * rt;
};

stree * create(int l, int r) {
    int m = (l + r) / 2;
    stree * s;
    if (l + 1 == r) {
        s = new stree();
        s->l = l;
        s->r = r;
        s->lt = s->rt = 0;
        s->min = bal[l];
    } else {
        s = new stree();
        s->l = l;
        s->r = r;
        s->lt = create(l, m);
        s->rt = create(m, r);
        s->min = min(s->lt->min, s->rt->min);
    }
    return s;
}

int ssize = 0;

int getmin(stree * root, int l, int r) {
    if (root == 0 || root->l >= r || root->r <= l) return 1e+9;
    if (l <= root->l && root->r <= r) return root->min;
    return min(getmin(root->lt, l, r), getmin(root->rt, l, r));
}

int main() {
    ios_base::sync_with_stdio(false);
    gets(str);
    n = strlen(str);
    int b = 0;
    memset(bal, 0, sizeof bal);
    for (int i = 0; i < n; i++) {
        bal[i] = b;
        if (str[i] == '(') b++;
        else b--;
    }
    bal[n] = b;
    stree * s = create(0, n);
    int m; scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d%d", &l, &r);
        int bmin = getmin(s, l - 1, r + 1);
        cout <<  (r - l + 1 - ((bal[l - 1] - bmin) + (bal[r] - bmin))) << "\n";
    }
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <cassert>
#include <memory>
#include <thread>
using namespace std;

#define INF 1e+9

#define MAXN 1000100

char str[MAXN];
int n;
int bal[MAXN];

struct stree{
    int l, r;
    int min;
    stree * lt, * rt;
};

stree * create(int l, int r) {
    int m = (l + r) / 2;
    stree * s;
    if (l + 1 == r) {
        s = new stree();
        s->l = l;
        s->r = r;
        s->lt = s->rt = 0;
        s->min = bal[l];
    } else {
        s = new stree();
        s->l = l;
        s->r = r;
        s->lt = create(l, m);
        s->rt = create(m, r);
        s->min = min(s->lt->min, s->rt->min);
    }
    return s;
}

int ssize = 0;

int getmin(stree * root, int l, int r) {
    if (root == 0 || root->l >= r || root->r <= l) return 1e+9;
    if (l <= root->l && root->r <= r) return root->min;
    return min(getmin(root->lt, l, r), getmin(root->rt, l, r));
}

int main() {
    ios_base::sync_with_stdio(false);
    gets(str);
    n = strlen(str);
    int b = 0;
    memset(bal, 0, sizeof bal);
    for (int i = 0; i < n; i++) {
        bal[i] = b;
        if (str[i] == '(') b++;
        else b--;
    }
    stree * s = create(0, n);
    int m; scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d%d", &l, &r);
        int bmin = getmin(s, l - 1, r + 1);
        cout <<  (r - l + 1 - ((bal[l - 1] - bmin) + (bal[r] - bmin))) << "\n";
    }
}


#include <iostream>

using namespace std;

struct str{
    int open;
    int close;
    int res;
    str(){};
    str(int a,int b, int c){
        open=a;close=b;res=c;
    }
    bool operator ==(const str b){
        if (open==b.open&&close==b.close&&res==b.res)
            return true;
        return false;
    }
};

str seg[4000006];
string inp;
const str inf=str(-1,-1,-1);
void init(int node , int l,int r){
    if (l==r){
        if (inp[l]=='('){
            seg[node]=str(1,0,0);
        }
        else if (inp[l]==')'){
            seg[node]=str(0,1,0);
        }
        return ;
    }
    int mid=(l+r)/2;
    init(node*2,l,mid);
    init(node*2+1,mid+1,r);
    int x=min(seg[2*node].open,seg[2*node+1].close);
    int res=2*x+seg[2*node].res+seg[2*node+1].res;
    int open=seg[2*node].open-x+seg[2*node+1].open;
    int close=seg[2*node+1].close-x+seg[2*node].close;
    seg[node]=str(open,close,res);
}

str query(int node ,int l,int r,int begin,int end){
    if (l>=begin&&r<=end){
        return seg[node];
    }
    if (l>end||r<begin){
        return inf;
    }
    int mid=(l+r)/2;
    str a=query(2*node,l,mid,begin,end);
    str b=query(2*node+1,mid+1,r,begin,end);
    if (a==inf){
        return b;
    }
    if (b==inf){
        return a;
    }
    int x=min(a.open,b.close);
    int res=2*x+a.res+b.res;
    int open=a.open-x+b.open;
    int close=b.close-x+a.close;

    return str(open,close,res);
}

int main(){
    cin>>inp;
    init(1,0,inp.length()-1);
    int q;
    cin>>q;
    for (int i=0;i<q;++i){
        int begin,end;
        cin>>begin>>end;
        cout<<query(1,0,inp.length()-1,begin-1,end-1).res<<endl;
    }
    return 0;
}