#include <bits/stdc++.h>

//#define endl "\n"

using namespace std;

typedef long long ll;
typedef pair< ll , ll> ii;

const int M = 1e3+10 , N = 1e6+10;

int a[N];
string s;

struct Node{
	int l , r , cntopen , cntclose , ans;
	Node():
		l(-1) , r(-1) , ans(0) , cntopen(0) , cntclose(0) {}
};

struct segtree{
	Node node[2*N + 100];

	Node merg(Node left , Node right){
		Node ans;
		int mn = min( left.cntopen , right.cntclose );
		ans.ans = left.ans + right.ans + 2*mn;
		ans.cntopen = left.cntopen + right.cntopen - mn;
		ans.cntclose = left.cntclose + right.cntclose - mn;
		return ans;
	}

	void build(int l , int r , int index){
		if(r == l){
			node[index].cntopen = s[r] == '(' ? 1 : 0;
			node[index].cntclose = s[r] == ')' ? 1 : 0;
			node[index].l = l;
			node[index].r = r;
			return;
		}
		int mid = (l+r)/2;
		build(l , mid , 2*index);
		build(mid+1 , r , 2*index + 1);
		node[index] = merg( node[2*index]  , node[2*index + 1] );
		node[index].l = l;
		node[index].r = r;
	}
	Node ask(int lq , int rq , int index){
		int l = node[index].l , r = node[index].r;
		if(lq > r || l > rq)
			return Node();
		if(l >= lq && r <= rq)
			return node[index];
		int mid = (l + r) / 2;

		//Node ne = merg( ask(lq , rq , 2*index) , ask(lq , rq , 2*index+1) );
		return merg( ask(lq , rq , 2*index) , ask(lq , rq , 2*index+1) );
	}

};

int main(){
	ios_base::sync_with_stdio( false );cin.tie(0);cout.tie(0);
	cin >> s;
	int n = s.size();
	segtree *st = new segtree();
	st->build(0 , n-1 , 1);
	int m;cin >> m;
	for(int i=0 ; i<m ; i++){
		int l , r;cin >> l >> r;l--;r--;
		cout << st->ask(l , r , 1).ans << "\n";
	}
	delete st;
}


#include <iostream>
#include <cstdio>

using namespace std;

class FastIO{
public:
    FastIO & operator << (const int &a){ printf("%d" , a); return *this; }
    FastIO & operator << (const char *a){ printf("%s" , a); return *this; }
    FastIO operator >> (int &a){ scanf("%d" , &a); return *this; }
    FastIO operator >> (char *a){ scanf("%s" , a); return *this; }
}hir;

struct node{
    int ans , op , cl;
    node():
        ans(0) , op(0) , cl(0) {};

};

const int N = 1e6+1 , LG = 20;

node lr[N][LG];
char s[N];
node merg(node *a , node *b){
    node ret;
    int mn = std::min(a->op , b->cl );
    ret.ans = 2*mn + a->ans + b->ans;
    ret.op = a->op + b->op - mn;
    ret.cl = a->cl + b->cl - mn;
    return ret;
}

node get_par(int v , int cnt){
    node ans;
    for(int p=0 ; p<LG ; p++)
        if( cnt & (1<<p) ){
            ans = merg(&lr[v][p] , &ans);
            v = v - (1<<p);
        }
    return ans;
}

int main(){
    node a , b;
    hir >> s;
    int n=0;
    while( s[n] != NULL ) n++;

    for(int i=0 ; i<=n ; i++)
        for(int j=0 ; j<LG ; j++)
            lr[i][j] = node();

    for(int i=0 ; i<=n ; i++){
        if(i == 0) continue;
        node cur;
        if(s[i-1] == '(') cur.op++; else cur.cl++;
        lr[i][0] = cur;
        for(int bit=1 ; bit<LG ; bit++){
            if( i - (1<<(bit-1)) < 0 ) continue;
            lr[i][bit] = merg( &lr[ i - (1<<(bit-1)) ][bit-1] , &lr[i][bit-1] );
        }
    }
    int q;hir >> q;
    for(int i=0 ; i<q ; i++){
        int l ,r;hir >> l >> r;l--;
        hir << get_par(r , r-l).ans << "\n";
    }
}


#include <iostream>
#include <conio.h>
using namespace std;

struct node{
    int ans , op , cl;
    node():
        ans(0) , op(0) , cl(0) {};

};

const int N = 1e6+1 , LG = 20;

node lr[N][LG];
int par[N][LG];

node merg(node *a , node *b){
    node ret;
    int mn = min(a->op , b->cl );
    ret.ans = 2*mn + a->ans + b->ans;
    ret.op = a->op + b->op - mn;
    ret.cl = a->cl + b->cl - mn;
    return ret;
}

node get_par(int v , int cnt){
    node ans;
    for(int p=0 ; p<LG ; p++)
        if( cnt & (1<<p) ){
            ans = merg(&lr[v][p] , &ans);
            v = par[v][p];
        }
    return ans;
}

int main(){
    node a , b;
    string s;cin >> s;
    int n = s.size();

    for(int i=0 ; i<=n ; i++)
        for(int j=0 ; j<LG ; j++)
            lr[i][j] = node() , par[i][j] = -1;

    for(int i=0 ; i<=n ; i++){
        if(i == 0) continue;
        node cur;
        if(s[i-1] == '(') cur.op++; else cur.cl++;
        lr[i][0] = cur;
        par[i][0] = i-1;
        for(int bit=1 ; bit<LG ; bit++){
            if( par[i][bit-1] < 0 ) continue;
            par[i][bit] = par[ par[i][bit-1] ][bit-1];
            lr[i][bit] = merg( &lr[ par[i][bit-1] ][bit-1] , &lr[i][bit-1] );
        }
    }
    int q;cin >> q;
    for(int i=0 ; i<q ; i++){
        int l ,r;cin >> l >> r;l--;
        cout << get_par(r , r-l).ans << endl;
    }
}


#include <iostream>
#include <cstdio>

using namespace std;

class FastIO{
public:
    inline FastIO & operator << (const int &a){ printf("%d" , a); return *this; }
    inline FastIO & operator << (const char * const&a){ printf("%s" , a); return *this; }
    inline FastIO & operator >> (const int &a){ scanf("%d" , &a); return *this; }
    inline FastIO & operator >> (const char * const&a){ scanf("%s" , a); return *this; }
}hir;

struct node{
    int ans , op , cl;
    node():
        ans(0) , op(0) , cl(0) {};

};

const int N = 1e6+1 , LG = 20;

node lr[N][LG];
char s[N];
node merg(node *a , node *b){
    node ret;
    int mn = std::min(a->op , b->cl );
    ret.ans = 2*mn + a->ans + b->ans;
    ret.op = a->op + b->op - mn;
    ret.cl = a->cl + b->cl - mn;
    return ret;
}

node get_par(int v , int cnt){
    node ans;
    for(int p=0 ; p<LG ; p++)
        if( cnt & (1<<p) ){
            ans = merg(&lr[v][p] , &ans);
            v = v - (1<<p);
        }
    return ans;
}

int main(){
    node a , b;
    hir >> s;
    int n=0;
    while( s[n] != NULL ) n++;

    for(int i=0 ; i<=n ; i++)
        for(int j=0 ; j<LG ; j++)
            lr[i][j] = node();

    for(int i=0 ; i<=n ; i++){
        if(i == 0) continue;
        node cur;
        if(s[i-1] == '(') cur.op++; else cur.cl++;
        lr[i][0] = cur;
        for(int bit=1 ; bit<LG ; bit++){
            if( i - (1<<(bit-1)) < 0 ) continue;
            lr[i][bit] = merg( &lr[ i - (1<<(bit-1)) ][bit-1] , &lr[i][bit-1] );
        }
    }
    int q;hir >> q;
    for(int i=0 ; i<q ; i++){
        int l ,r;hir >> l >> r;l--;
        hir << get_par(r , r-l).ans << "\n";
    }
}


#include <iostream>
#include <conio.h>
using namespace std;

struct node{
    int ans , op , cl;
    node():
        ans(0) , op(0) , cl(0) {};

};

const int N = 1e6+100 , LG = 20;

node lr[N][LG];
int par[N][LG];

node merg(node a , node b){
    node ret;
    int mn = min(a.op , b.cl );
    ret.ans = 2*mn + a.ans + b.ans;
    ret.op = a.op + b.op - mn;
    ret.cl = a.cl + b.cl - mn;
    return ret;
}

node get_par(int v , int cnt){
    node ans;
    for(int p=0 ; p<LG ; p++)
        if( cnt & (1<<p) ){
            ans = merg(lr[v][p] , ans);
            v = par[v][p];
        }
    return ans;
}

int main(){
    node a , b;
    string s;cin >> s;
    int n = s.size();

    for(int i=0 ; i<=n ; i++)
        for(int j=0 ; j<LG ; j++)
            lr[i][j] = node() , par[i][j] = -1;

    for(int i=0 ; i<=n ; i++){
        if(i == 0) continue;
        node cur;
        if(s[i-1] == '(') cur.op++; else cur.cl++;
        lr[i][0] = cur;
        par[i][0] = i-1;
        for(int bit=1 ; bit<LG ; bit++){
            if( par[i][bit-1] < 0 ) continue;
            par[i][bit] = par[ par[i][bit-1] ][bit-1];
            lr[i][bit] = merg( lr[ par[i][bit-1] ][bit-1] , lr[i][bit-1] );
        }
    }
    int q;cin >> q;
    for(int i=0 ; i<q ; i++){
        int l ,r;cin >> l >> r;l--;
        cout << get_par(r , r-l).ans << endl;
    }
}


#include <cstdio>
#include <iostream>

struct node{
    int ans , op , cl;
    node():
        ans(0) , op(0) , cl(0) {};

};

const int N = 1e6+1 , LG = 20;

node lr[N][LG];
char s[N];
node merg(node *a , node *b){
    node ret;
    int mn = std::min(a->op , b->cl );
    ret.ans = 2*mn + a->ans + b->ans;
    ret.op = a->op + b->op - mn;
    ret.cl = a->cl + b->cl - mn;
    return ret;
}

node get_par(int v , int cnt){
    node ans;
    for(int p=0 ; p<LG ; p++)
        if( cnt & (1<<p) ){
            ans = merg(&lr[v][p] , &ans);
            v = v - (1<<p);
        }
    return ans;
}

int main(){
    node a , b;
    scanf("%s" , s);
    int n=0;
    while( s[n] != NULL ) n++;

    for(int i=0 ; i<=n ; i++)
        for(int j=0 ; j<LG ; j++)
            lr[i][j] = node();

    for(int i=0 ; i<=n ; i++){
        if(i == 0) continue;
        node cur;
        if(s[i-1] == '(') cur.op++; else cur.cl++;
        lr[i][0] = cur;
        for(int bit=1 ; bit<LG ; bit++){
            if( i - (1<<(bit-1)) < 0 ) continue;
            lr[i][bit] = merg( &lr[ i - (1<<(bit-1)) ][bit-1] , &lr[i][bit-1] );
        }
    }
    int q;scanf("%d" , &q);
    for(int i=0 ; i<q ; i++){
        int l ,r;scanf("%d%d" , &l , &r);l--;
        printf( "%d\n" , get_par(r , r-l).ans);
    }
}


#include <iostream>
#include <conio.h>
using namespace std;

struct node{
    int ans , op , cl;
    node():
        ans(0) , op(0) , cl(0) {};

};

const int N = 1e6+100 , LG = 23;

node lr[N][LG];
int par[N][LG];

node merg(node a , node b){
    node ret;
    int mn = min(a.op , b.cl );
    ret.ans = 2*mn + a.ans + b.ans;
    ret.op = a.op + b.op - mn;
    ret.cl = a.cl + b.cl - mn;
    return ret;
}

node get_par(int v , int cnt){
    node ans;
    for(int p=0 ; p<LG ; p++)
        if( cnt & (1<<p) ){
            ans = merg(lr[v][p] , ans);
            v = par[v][p];
        }
    return ans;
}

int main(){
    node a , b;
    string s;cin >> s;
    int n = s.size();

    for(int i=0 ; i<=n ; i++)
        for(int j=0 ; j<LG ; j++)
            lr[i][j] = node() , par[i][j] = -1;

    for(int i=0 ; i<=n ; i++){
        if(i == 0) continue;
        node cur;
        if(s[i-1] == '(') cur.op++; else cur.cl++;
        lr[i][0] = cur;
        par[i][0] = i-1;
        for(int bit=1 ; bit<LG ; bit++){
            if( par[i][bit-1] < 0 ) continue;
            par[i][bit] = par[ par[i][bit-1] ][bit-1];
            lr[i][bit] = merg( lr[ par[i][bit-1] ][bit-1] , lr[i][bit-1] );
        }
    }
    int q;cin >> q;
    for(int i=0 ; i<q ; i++){
        int l ,r;cin >> l >> r;l--;
        cout << get_par(r , r-l).ans << endl;
    }
}


#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>
#define MAX 2098000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
string s;
void clear()
{
	for(long long int i=0;i<MAX;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(2*id,l,mid);
	build(2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	long long int z;
	cin>>s;
	z=s.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build();
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <bits/stdc++.h>
#include <string>
#include <algorithm>
#include <math.h>
#define MAX 4298000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
char s[MAX];
void clear()
{
	for(long long int i=0;i<MAX;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(2*id,l,mid);
	build(2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	}
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	}
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	long long int i,z;
	cin>>s;
	z=strlen(s);
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build();
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <math.h>
#define MAX 5000000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
void clear()
{
	for(long long int i=0;i<MAX;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(string s,long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(s,2*id,l,mid);
	build(s,2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	string str;
	long long int z;
	cin>>str;
	z=str.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build(str);
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <math.h>
#define MAX 4000000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(string s,long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(s,2*id,l,mid);
	build(s,2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	string str;
	long long int z;
	cin>>str;
	z=str.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build(str);
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <math.h>
#define MAX 1049000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(string s,long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(s,2*id,l,mid);
	build(s,2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	string str;
	long long int z;
	cin>>str;
	z=str.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build(str);
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>
#define MAX 2098000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(string s,long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(s,2*id,l,mid);
	build(s,2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	string str;
	long long int z;
	cin>>str;
	z=str.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build(str);
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>
#define MAX 2098000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
string s;
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(2*id,l,mid);
	build(2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	long long int z;
	cin>>s;
	z=s.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build();
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>
#define MAX 4298000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
string s;
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(2*id,l,mid);
	build(2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	}
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	}
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	long long int z;
	cin>>s;
	z=s.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build();
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>
#define MAX 4298000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
string s;
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(2*id,l,mid);
	build(2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	long long int z;
	cin>>s;
	z=s.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build();
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <iostream>
#include <string>
#include <math.h>
#define MAX 2098000
using namespace std;
/*typedef pair<long long int ,long long int> pii;
typedef pair<long long int ,pii> node;*/
struct node
{
	long long int t1,t2,t3;
}node1;
long long int n,t[MAX],o[MAX],c[MAX];
void clear()
{
	for(long long int i=0;i<n;i++)
	{
		t[i]=0;
		c[i]=0;
		o[i]=0;
	}
}
void build(string s,long long int id=1,long long int l=0,long long int r=n)
{
	if(r-l<2)
	{
		if(s[l]=='(')
		o[id]=1;
		else
		c[id]=1;
		return;
	}
	long long int mid=(l+r)/2;
	build(s,2*id,l,mid);
	build(s,2*id+1,mid,r);
	long long int temp=min(o[2*id],c[2*id+1]);
	t[id]=t[2*id]+t[2*id+1]+2*temp;
		o[id]=o[2*id]+o[2*id+1]-temp;
			c[id]=c[2*id]+c[2*id+1]-temp;

}
node search(long long int x,long long int y,long long id=1,long long int l=0,long long int r=n)
{
	struct node node1;
	if(x>=r ||y<=l)
	{
		node1.t1=0;
		node1.t2=0;
		node1.t3=0;
    	return node1;
	};
	if(x<=l && y>=r)
    {
		node1.t1=t[id];
		node1.t2=o[id];
		node1.t3=c[id];
    	return node1;
	};
	long long int mid=(l+r)/2;
	node a=search(x,y,2*id,l,mid);
	node b=search(x,y,2*id+1,mid,r);
	long long int temp,T,O,C;
	temp=min(a.t2,b.t3);
	T=a.t1+b.t1+2*temp;
	O=a.t2+b.t2-temp;
	C=a.t3+b.t3-temp;
	node1.t1=T;
	node1.t2=O;
	node1.t3=C;
   	return node1;
}
signed main()
{
	string str;
	long long int z;
	cin>>str;
	z=str.size();
	n=ceil(log2(z));
	n=2*pow(2,n)-1;
	clear();
	build(str);
	long long int q;
	cin>>q;
	while(q--)
	{
		long long int x,y;
		node ans;
		cin >>x>>y;
		ans=search(x-1,y);
		cout<<ans.t1<<"\n";
	}
}


#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
const int N = 1000005;

struct node {
	int dl, dr, v;
}s[N*2];

int n, r[N], l[N], len;
char str[N];

int build (int x, int y, int f) {
	s[f].dl = x, s[f].dr = y;

	if (x == y) return s[f].v = l[x];

	int mid = (x + y) / 2;
	return s[f].v = min(build(x, mid, 2 * f), build(mid+1, y, 2*f+1));
}

int query(int x, int y, int f) {
	if (x == s[f].dl && y == s[f].dr) return s[f].v;

	int mid = (s[f].dl + s[f].dr) / 2;
	if (mid >= x && mid < y) return min(query(x, mid, 2*f), query(mid+1, y, 2*f+1));
	else if (mid >= x && mid >= y) return query(x, y, 2*f);
	else return query(x, y, 2*f+1);
}

void solve () {
	memset(r, 0, sizeof(r));
	memset(l, 0, sizeof(l));
	len = strlen(str);
	int tmp = 0;
	for (int i = 1; i <= len; i++) {
		r[i] = r[i-1];

		if (str[i-1] == '(') tmp++;
		else if (tmp) {
			r[i]++; tmp--;
		}
		l[i] = tmp;
	}
	build(1, len, 1);
}

int main () {
	gets(str);
	solve ();

	int a, b;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &a, &b);
		a = min(len, a); b = min(len, b);
		printf("%d\n", (r[b] - r[a-1] - max(l[a-1] - query(a, b, 1), 0)) * 2);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
const int N = 1000005;

struct node {
	int dl, dr, v;
}s[N*2];

int n, r[N], l[N], len;
char str[N];

int build (int x, int y, int f) {
	s[f].dl = x, s[f].dr = y;

	if (x == y) return s[f].v = l[x];

	int mid = (x + y) / 2;//
	return s[f].v = min(build(x, mid, 2 * f), build(mid+1, y, 2*f+1));
}

int query(int x, int y, int f) {
	if (x == s[f].dl && y == s[f].dr) return s[f].v;

	int mid = (s[f].dl + s[f].dr) / 2;
	if (mid >= x && mid < y) return min(query(x, mid, 2*f), query(mid+1, y, 2*f+1));
	else if (mid >= x && mid >= y) return query(x, y, 2*f);
	else return query(x, y, 2*f+1);
}

void solve () {
	memset(r, 0, sizeof(r));
	memset(l, 0, sizeof(l));
	len = strlen(str);
	int tmp = 0;
	for (int i = 1; i <= len; i++) {
		r[i] = r[i-1];

		if (str[i-1] == '(') tmp++;
		else if (tmp) {
			r[i]++; tmp--;
		}
		l[i] = tmp;
	}
	build(1, len, 1);
}

int main () {
	gets(str);
	solve ();

	int a, b;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &a, &b);
		a = min(len, a); b = min(len, b);
		printf("%d\n", (r[b] - r[a-1] - max(l[a-1] - query(a, b, 1), 0)) * 2);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
const int N = 10;

struct node {
	int dl, dr, v;
}s[N*3];

int n, r[N], l[N], len;
char str[N];

int build (int x, int y, int f) {
	s[f].dl = x, s[f].dr = y;

	if (x == y) return s[f].v = l[x];

	int mid = (x + y) / 2;
	return s[f].v = min(build(x, mid, 2 * f), build(mid+1, y, 2*f+1));
}

int query(int x, int y, int f) {
	if (x == s[f].dl && y == s[f].dr) return s[f].v;

	int mid = (s[f].dl + s[f].dr) / 2;
	if (mid >= x && mid < y) return min(query(x, mid, 2*f), query(mid+1, y, 2*f+1));
	else if (mid >= x && mid >= y) return query(x, y, 2*f);
	else return query(x, y, 2*f+1);
}

void solve () {
	memset(r, 0, sizeof(r));
	memset(l, 0, sizeof(l));
	len = strlen(str);
	int tmp = 0;
	for (int i = 1; i <= len; i++) {
		r[i] = r[i-1];

		if (str[i-1] == '(') tmp++;
		else if (tmp) {
			r[i]++; tmp--;
		}
		l[i] = tmp;
	}
	build(1, len, 1);
}

int main () {
	gets(str);
	solve ();

	int a, b;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &a, &b);
		a = min(len, a); b = min(len, b);
		printf("%d\n", (r[b] - r[a-1] - max(l[a-1] - query(a, b, 1), 0)) * 2);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
const int N = 1000005;

struct node {
	int dl, dr, v;
}s[N*3];

int n, r[N], l[N], len;
char str[N];

int build (int x, int y, int f) {
	s[f].dl = x, s[f].dr = y;

	if (x == y) return s[f].v = l[x];

	int mid = (x + y) / 2;
	return s[f].v = min(build(x, mid, 2 * f), build(mid+1, y, 2*f+1));
}

int query(int x, int y, int f) {
	if (x == s[f].dl && y == s[f].dr) return s[f].v;

	int mid = (s[f].dl + s[f].dr) / 2;
	if (mid >= x && mid < y) return min(query(x, mid, 2*f), query(mid+1, y, 2*f+1));
	else if (mid >= x && mid >= y) return query(x, y, 2*f);
	else return query(x, y, 2*f+1);
}

void solve () {
	memset(r, 0, sizeof(r));
	memset(l, 0, sizeof(l));
	len = strlen(str);
	int tmp = 0;
	for (int i = 1; i <= len; i++) {
		r[i] = r[i-1];

		if (str[i-1] == '(') tmp++;
		else if (tmp) {
			r[i]++; tmp--;
		}
		l[i] = tmp;
	}
	build(1, len, 1);
}

int main () {
	gets(str);
	solve ();

	int a, b;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &a, &b);
		a = min(len, a); b = min(len, b);
		printf("%d\n", (r[b] - r[a-1] - max(l[a-1] - query(a, b, 1), 0)) * 2);
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<map>
#include<set>
using namespace std;
const int maxn=10005;
set<int> vis[maxn];
void init()
{
    for(int i=0;i<maxn;++i)
    {
        vis[i].clear();
    }
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        map<int,int> map;
        for(int i=1;i<=n;++i)
        {
            int a;
            scanf("%d",&a);
            map[i]=a;
        }
        for(int i=0;i<m;++i)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(map[a]!=map[b])//和自身相等的颜色不算
            {
                vis[map[a]].insert(map[b]);
                vis[map[b]].insert(map[a]);
            }
        }
        int ans=map[1];
        for(int i=1;i<=n;++i)
        {
            if(vis[ans].size()<vis[map[i]].size()||
            vis[ans].size()==vis[map[i]].size()&&ans>map[i])//判断条件
            {
                ans=map[i];
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int Nmax = 1e6 + 1;

struct Node
{
    int sol;
    int open;
    int closed;
};

Node A[4 * Nmax];
string str;
int N, M;

Node merge(const Node& left, const Node& right)
{
    Node ans = { 0, 0, 0 };

    int t = min( left.open, right.closed );

    ans.sol = left.sol + right.sol + t;
    ans.open = left.open + right.open - t;
    ans.closed = left.closed + right.closed - t;

    return ans;
}

void build(int nod, int st, int dr)
{
    if ( st == dr )
    {
        A[nod].sol = 0;
        A[nod].open = (str[st - 1] == '(');
        A[nod].closed = (str[st - 1] == ')');
    }
    else
    {
        int m = ( st + dr ) / 2;

        build(2 * nod, st, m);
        build(2 * nod + 1, m + 1, dr);

        A[nod] = merge(A[2 * nod], A[2 * nod + 1]);
    }
}

Node query(int nod, int st, int dr, int st_q, int dr_q)
{
    if ( st_q <= st && dr <= dr_q )
    {
        return A[nod];
    }
    else
    {
        int m = ( st + dr ) / 2;
        Node sol = { 0, 0, 0 };

        if ( st_q <= m )
            sol = merge(sol, query(2 * nod, st, m, st_q, dr_q) );

        if ( m < dr_q )
            sol = merge(sol, query(2 * nod + 1, m + 1, dr, st_q, dr_q) );

        return sol;
    }
}

int main()
{
    ///ifstream cin("data.in");

    ios_base::sync_with_stdio( false );

    cin >> str;
    N = str.size();

    build( 1, 1, N );

    cin >> M;

    while ( M-- )
    {
        int a, b;

        cin >> a >> b;
        cout << 2 * query(1, 1, N, a, b).sol << "\n";
    }

    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int N=1000002;
char s[N];
vector<int> start,finish,sum;
int q;
stack<pair<int,int> > st;
int bs1(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(finish[mi]>key)
		{
			ans=mi;
			hi=mi-1;
		}
		else
		{
			lo=mi+1;
		}
	}
	return ans;
}
int bs2(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(start[mi]<key)
		{
			ans=mi;
			lo=mi+1;
		}
		else
		{
			hi=mi-1;
		}
	}
	return ans;
}
int main()
{
	int l,i,k,one,two;
	pair<int,int> temp;
	bool cont;
	scanf("%s",s);
	l=strlen(s);
	s[l]='(';
	cont=false;
	k=0;
	for(i=0;i<=l;++i)
	{
		if(st.empty())
		{
			st.push(make_pair(s[i],i));
			if(cont)
			{
				start.push_back(i-2*k);
				finish.push_back(i-1);
				cont=false;
			}
		}
		else if(s[i]=='(')
		{
			if(cont)
			{
				start.push_back(i-2*k);
				finish.push_back(i-1);
				cont=false;
			}
			st.push(make_pair(s[i],i));
		}
		else
		{
			temp=st.top();
			if(temp.first==')')
			{
				st.push(make_pair(s[i],i));
				cont=false;
				start.push_back(i-2*k);
				finish.push_back(i-1);
			}
			else
			{
				if(cont)
				{
					k++;
				}
				else
				{
					cont=true;
					k=1;
				}
				st.pop();
			}
		}
	}
	int acc=0;
	for(i=0;i<start.size();++i)
	{
		acc+=(finish[i]-start[i]+1);
		sum.push_back(acc);
	}
	scanf("%d",&q);
	for(i=1;i<=q;++i)
	{
		scanf("%d",&one);scanf("%d",&two);
		one--;two--;
		int temp1=bs1(one);
		int temp2=bs2(two);
		if(temp1==-1||temp2==-1||temp1>temp2) printf("\n0");
		else if(temp1==temp2)
		{
			if(one>(start[temp1]+finish[temp2])/2||two<=(start[temp1]+finish[temp2])/2) printf("\n0");
			else if(start[temp1]<one||finish[temp1]>two) printf("\n%d",2*min((start[temp1]+finish[temp2])/2-one+1,two-(start[temp1]+finish[temp2])/2));
			else printf("\n%d",(finish[temp1]-start[temp1]+1));
		}
		else
		{
			int ans=sum[temp2-1]-sum[temp1];
			if(start[temp1]>one) ans+=(finish[temp1]-start[temp1]+1);
			else ans+=one>(start[temp1]+finish[temp1])/2?0:(start[temp1]+finish[temp1]-1)-2*one+2;
			if(finish[temp2]<two) ans+=(finish[temp2]-start[temp2]+1);
			else ans+=two<=(start[temp2]+finish[temp2])/2?0:two*2-(start[temp2]+finish[temp2]-1);
			printf("\n%d",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int N=1000002;
char s[N];
vector<int> start,end,sum;
int q;
stack<pair<int,int> > st;
int bs1(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(end[mi]>key)
		{
			ans=mi;
			hi=mi-1;
		}
		else
		{
			lo=mi+1;
		}
	}
	return ans;
}
int bs2(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(start[mi]<key)
		{
			ans=mi;
			lo=mi+1;
		}
		else
		{
			hi=mi-1;
		}
	}
	return ans;
}
int main()
{
	int l,i,k,one,two;
	pair<int,int> temp;
	bool cont;
	scanf("%s",s);
	l=strlen(s);
	s[l]='(';
	cont=false;
	k=0;
	for(i=0;i<=l;++i)
	{
		if(st.empty())
		{
			st.push(make_pair(s[i],i));
			if(cont)
			{
				start.push_back(i-2*k);
				end.push_back(i-1);
				cont=false;
			}
		}
		else if(s[i]=='(')
		{
			if(cont)
			{
				start.push_back(i-2*k);
				end.push_back(i-1);
				cont=false;
			}
			st.push(make_pair(s[i],i));
		}
		else
		{
			temp=st.top();
			if(temp.first==')')
			{
				st.push(make_pair(s[i],i));
				cont=false;
				start.push_back(i-2*k);
				end.push_back(i-1);
			}
			else
			{
				if(cont)
				{
					k++;
				}
				else
				{
					cont=true;
					k=1;
				}
				st.pop();
			}
		}
	}
	int acc=0;
	for(i=0;i<start.size();++i)
	{
		acc+=(end[i]-start[i]+1);
		sum.push_back(acc);
	}
	scanf("%d",&q);
	for(i=1;i<=q;++i)
	{
		scanf("%d",&one);scanf("%d",&two);
		one--;two--;
		int temp1=bs1(one);
		int temp2=bs2(two);
		if(temp1==-1||temp2==-1||temp1>temp2) printf("\n0");
		else if(temp1==temp2)
		{
			if(one>(start[temp1]+end[temp2])/2||two<=(start[temp1]+end[temp2])/2) printf("\n0");
			else if(start[temp1]<one||end[temp1]>two) printf("\n%d",2*min((start[temp1]+end[temp2])/2-one+1,two-(start[temp1]+end[temp2])/2));
			else printf("\n%d",(end[temp1]-start[temp1]+1));
		}
		else
		{
			int ans=sum[temp2-1]-sum[temp1];
			if(start[temp1]>one) ans+=(end[temp1]-start[temp1]+1);
			else ans+=one>(start[temp1]+end[temp1])/2?0:(start[temp1]+end[temp1]-1)-2*one+2;
			if(end[temp2]<two) ans+=(end[temp2]-start[temp2]+1);
			else ans+=two<=(start[temp2]+end[temp2])/2?0:two*2-(start[temp2]+end[temp2]-1);
			printf("\n%d",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int N=1000002;
char s[N];
vector<int> start,end,sum;
int q;
stack<pair<int,int> > st;
int bs1(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(end[mi]>key)
		{
			ans=mi;
			hi=mi-1;
		}
		else
		{
			lo=mi+1;
		}
	}
	return ans;
}
int bs2(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(start[mi]<key)
		{
			ans=mi;
			lo=mi+1;
		}
		else
		{
			hi=mi-1;
		}
	}
	return ans;
}
int main()
{
	int l,i,k,one,two;
	pair<int,int> temp;
	bool cont;
	scanf("%s",s);
	l=strlen(s);
	s[l]='(';
	cont=false;
	k=0;
	for(i=0;i<=l;++i)
	{
		if(st.empty())
		{
			st.push(make_pair(s[i],i));
			if(cont)
			{
				start.push_back(i-2*k);
				end.push_back(i-1);
				cont=false;
			}
		}
		else if(s[i]=='(')
		{
			if(cont)
			{
				start.push_back(i-2*k);
				end.push_back(i-1);
				cont=false;
			}
			st.push(make_pair(s[i],i));
		}
		else
		{
			temp=st.top();
			if(temp.first==')')
			{
				st.push(make_pair(s[i],i));
				cont=false;
				start.push_back(i-2*k);
				end.push_back(i-1);
			}
			else
			{
				if(cont)
				{
					k++;
				}
				else
				{
					cont=true;
					k=1;
				}
				st.pop();
			}
		}
	}
	int acc=0;
	for(i=0;i<start.size();++i)
	{
		acc+=(end[i]-start[i]+1);
		sum.push_back(acc);
	}
	scanf("%d",&q);
	for(i=1;i<=q;++i)
	{
		scanf("%d",&one);scanf("%d",&two);
		one--;two--;
		int temp1=bs1(one);
		int temp2=bs2(two);
		if(temp1==-1||temp2==-1||temp1>temp2) printf("\n0");
		else if(temp1==temp2)
		{
			if(one>(start[temp1]+end[temp2])/2||two<=(start[temp1]+end[temp2])/2) printf("\n0");
			else if(start[temp1]<one||end[temp1]>two) printf("\n%d",2*min((start[temp1]+end[temp2])/2-one+1,two-(start[temp1]+end[temp2])/2));
			else printf("\n%d",(end[temp1]-start[temp1]+1));
		}
		else
		{
			int ans=sum[temp2-1]-sum[temp1];
			if(start[temp1]>one) ans+=(end[temp1]-start[temp1]+1);
			else ans+=one>(start[temp1]+end[temp1])/2?0:(start[temp1]+end[temp1]-1)-2*one+2;
			if(end[temp2]<two) ans+=(end[temp2]-start[temp2]+1);
			else ans+=two<=(start[temp2]+end[temp2])/2?0:two*2-(start[temp2]+end[temp2]-1);
			printf("\n%d",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int N=1000002;
char s[N];
vector<int> start,finish,sum;
int q;
stack<pair<int,int> > st;
int bs1(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(finish[mi]>key)
		{
			ans=mi;
			hi=mi-1;
		}
		else
		{
			lo=mi+1;
		}
	}
	return ans;
}
int bs2(int key)
{
	int ans=-1;
	if(start.size()==0) return ans;
	int lo=0,hi=start.size()-1;
	while(lo<=hi)
	{
		int mi=(lo+hi)/2;
		if(start[mi]<key)
		{
			ans=mi;
			lo=mi+1;
		}
		else
		{
			hi=mi-1;
		}
	}
	return ans;
}
int main()
{
	int l,i,k,one,two;
	pair<int,int> temp;
	bool cont;
	scanf("%s",s);
	l=strlen(s);
	s[l]='(';
	cont=false;
	k=0;
	for(i=0;i<=l;++i)
	{
		if(st.empty())
		{
			st.push(make_pair(s[i],i));
			if(cont)
			{
				start.push_back(i-2*k);
				finish.push_back(i-1);
				cont=false;
			}
		}
		else if(s[i]=='(')
		{
			if(cont)
			{
				start.push_back(i-2*k);
				finish.push_back(i-1);
				cont=false;
			}
			st.push(make_pair(s[i],i));
		}
		else
		{
			temp=st.top();
			if(temp.first==')')
			{
				st.push(make_pair(s[i],i));
				if(cont)
				{
					cont=false;
					start.push_back(i-2*k);
					finish.push_back(i-1);
				}
			}
			else
			{
				if(cont)
				{
					k++;
				}
				else
				{
					cont=true;
					k=1;
				}
				st.pop();
			}
		}
	}
	int acc=0;
	for(i=0;i<start.size();++i)
	{
		acc+=(finish[i]-start[i]+1);
		sum.push_back(acc);
	}
	scanf("%d",&q);
	for(i=1;i<=q;++i)
	{
		scanf("%d",&one);scanf("%d",&two);
		one--;two--;
		int temp1=bs1(one);
		int temp2=bs2(two);
		if(temp1==-1||temp2==-1||temp1>temp2) printf("\n0");
		else if(temp1==temp2)
		{
			if(one>(start[temp1]+finish[temp2])/2||two<=(start[temp1]+finish[temp2])/2) printf("\n0");
			else if(start[temp1]<one||finish[temp1]>two) printf("\n%d",2*min((start[temp1]+finish[temp2])/2-one+1,two-(start[temp1]+finish[temp2])/2));
			else printf("\n%d",(finish[temp1]-start[temp1]+1));
		}
		else
		{
			int ans=sum[temp2-1]-sum[temp1];
			if(start[temp1]>one) ans+=(finish[temp1]-start[temp1]+1);
			else ans+=one>(start[temp1]+finish[temp1])/2?0:(start[temp1]+finish[temp1]+1)-2*one;
			if(finish[temp2]<two) ans+=(finish[temp2]-start[temp2]+1);
			else ans+=two<=(start[temp2]+finish[temp2])/2?0:two*2-(start[temp2]+finish[temp2]-1);
			printf("\n%d",ans);
		}
	}
	return 0;
}


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

int tree[MAX][3];
    string str;

int* query(int ts,int te,int qs,int qe,int pos)
{
            int* a = new int[3];
    //cout<<ts<<" "<<te<< " "<<pos<<endl;
    if(qs<=ts && qe>=te)
    {
        a[0]  = tree[pos][0];
        a[1]  = tree[pos][1];
        a[2]  = tree[pos][2];
        return a;
    }
    if(qs>te || qe<ts)
    {
        a[0] = 0;
        a[1] = 0;
        a[2] = 0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(ts,mid,qs,qe,2*pos);
    int* rt = query(mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    a[0] = lf[0]+rt[0]+ 2*MIN;
    a[1] = lf[1]+rt[1]-MIN;
    a[2] = lf[2]+rt[2]-MIN;
     delete lf;
     delete rt;
    return a;
}
void fill(int id,int l,int r){
    if (l==r) {
		if (str[l-1]=='(') {
		    tree[id][0] = 0;
		    tree[id][1]= 1;
		    tree[id][2] =0;

		}
		else{

		 tree[id][0] = 0;
		 tree[id][1]=0;
		 tree[id][2] =1;
		}
		return;
	}
	int mid = (l+r)/2;
	fill(2*id,l,mid);
	fill(2*id+1,mid+1,r);
	int MIN = min(tree[2*id][1],tree[2*id+1][2]);
	tree[id][0] = tree[2*id][0] + tree[2*id+1][0] + 2*MIN;
	tree[id][1] = tree[2*id][1] + tree[2*id+1][1] -MIN;
	tree[id][2] = tree[2*id][2] + tree[2*id+1][2] - MIN;

}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    cin>>str;
    sz = str.size();
    n = sz;

   // int** tree = new int*[2*n];

    char tmp;
    int MIN,l,r;
    // for(int i=0;i<n;i++)
    // {
    //       // tree[n+i] = new int[3];

    //         if(i<sz)
    //         {
    //             if(str[i]=='(')
    //             {
    //                 tree[n+i][0] = 0;
    //                 tree[n+i][1] = 1;
    //                 tree[n+i][2] = 0;
    //             }
    //             else if(str[i]==')')
    //             {
    //                 tree[n+i][0] = 0;
    //                 tree[n+i][1] = 0;
    //                 tree[n+i][2] = 1;

    //             }
    //         }
    //         else
    //         {
    //             tree[n+i][0]= 0;
    //             tree[n+i][1] = 0;
    //             tree[n+i][2] = 0;
    //         }

    // }
    fill(1,1,n);
    // for(int i=n-1;i>=1;i--)
    // {
    //     MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     tree[i] =new int[3];
    //     tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
    //     tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
    //     tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    // }
    // for(int i=1;i<2*n;i++)
    // {
    //     //MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;

        int * ans = query(1,n,l,r,1);
        cout<<ans[0]<<endl;
        delete ans;
    }

    return 0;
}


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

 struct tree
{
    int a,b,c;
    tree(int x=0,int y=0, int z=0)
    {
        a=x;
        b=y;
        c=z;
    }
};
tree T[MAX];
    string str;

tree solve(int id,int l, int r, int u, int v) {
       // cout<<l<<" "<<r<< " "<<id<<endl;

	if (u>r || v<l) return tree(0,0,0);
	if (u<=l && r<=v) return T[id];
	int mid = (l+r)/2;
	tree a = solve(2*id,l,mid,u,v);
	tree b =solve(2*id+1,mid+1,r,u,v);
	int MIN = min(a.b,b.c);
	return tree(a.a+b.a+2*MIN,a.b+b.b-MIN,a.c+b.c-MIN);
}
void fill(int id,int l,int r){

    if (l==r) {
		if (str[l-1]=='(') {
		    T[id] =tree(0,1,0);
		}
		else{
		 T[id]=tree(0,0,1);
		}
		return;
	}
	int mid = (l+r)/2;
	fill(2*id,l,mid);
	fill(2*id+1,mid+1,r);
	int MIN = min(T[2*id].b,T[2*id+1].c);
	T[id]= tree(T[2*id].a+ T[2*id+1].a + 2*MIN, T[2*id].b + T[2*id+1].b -MIN,T[2*id].c + T[2*id+1].c - MIN);

}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    cin>>str;
    n = str.size();

    int MIN,l,r;

    fill(1,1,n);
    // for(int i=1;i<2*n;i++)
    // {
    //     //MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<T[i].a <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;
        cout<<solve(1,1,n,l,r).a<<endl;
    }

    return 0;
}


#include <iostream>
using namespace std;

struct node {
	int best,open,close;
	node(int b = 0,int o = 0,int c = 0) {
		best = b; open = o; close = c;
	}
};
node operator+(const node& a, const node& b) {
	node add;
	int tmp = min(a.open,b.close);
	add.best = a.best + b.best + 2*tmp;
	add.open = a.open + b.open - tmp;
	add.close = a.close + b.close - tmp;
	return add;
}
const int maxN = 1e6;
string s;
node ST[4*maxN+1];

void init(int id,int l, int r) {
	if (l==r) {
		if (s[l-1]=='(') ST[id] = node(0,1,0);
		else ST[id] = node(0,0,1);
		return;
	}
	int mid = (l+r)/2;
	init(2*id,l,mid);
	init(2*id+1,mid+1,r);
	ST[id] = ST[2*id] + ST[2*id+1];
}
node solve(int id,int l, int r, int u, int v) {
       // cout<<l<<" "<<r<< " "<<id<<endl;

	if (u>r || v<l) return node(0,0,0);
	if (u<=l && r<=v) return ST[id];
	int mid = (l+r)/2;
	return solve(2*id,l,mid,u,v) + solve(2*id+1,mid+1,r,u,v);
}
int main() {
	cin >> s;
	int n = s.length();
	init(1,1,n);
	int t; cin >> t;
	while (t--) {
		int u,v; cin >> u >> v;
		node res = solve(1,1,n,u,v);
		cout << res.best << '\n';
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MAX 10000009
int tree[MAX][3];
int* query(int ts,int te,int qs,int qe,int pos)
{
    if(qs<=ts && qe>=te)
    {
        return tree[pos];
    }
    if(qs>te || qe<ts)
    {
        int* a = new int[3];
        a[0]=0;
        a[1]= 0;
        a[2] =0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(ts,mid,qs,qe,2*pos);
    int* rt = query(mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    int* ret =  new int[3];
    ret[0] = lf[0]+rt[0]+ 2*MIN;
    ret[1] = lf[1]+rt[1]-MIN;
    ret[2] = lf[2]+rt[2]-MIN;
    // delete lf;
    // delete rt;
    return ret;
}

int main()
{
    ios_base::sync_with_stdio(false);
cin.tie(NULL);
    cout.tie(0);
    int n,N,sz;
    string str;
    cin>>str;
    sz = str.size();
    n = pow(2, (int)ceil(log2(sz)));
    memset(tree, 0, sizeof tree);
    char tmp;
    int MIN,l,r;
    for(int i=0;i<sz;i++)
    {

            if(str[i]=='(')
                tree[n+i][1] = 1;
            else if(str[i]==')')
                tree[n+i][2] = 1;

    }

    for(int i=n-1;i>=1;i--)
    {
        MIN = min(tree[2*i][1],tree[2*i+1][2]);
        tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
        tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
        tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    }
    //     for(int i=0;i<=2*n;i++)
    // {
    //     MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;
        int * ans = query(1,n,l,r,1);
        cout<<ans[0]<<endl;
        //delete ans;
    }

    return 0;
}


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

int tree[MAX][3];
    string str;

int  * solve(int id,int l, int r, int u, int v) {
       // cout<<l<<" "<<r<< " "<<id<<endl;

	if (u>r || v<l) return new int[3]{0,0,0};
	if (u<=l && r<=v) return tree[id];
	int mid = (l+r)/2;
	int *a ;
	a =solve(2*id,l,mid,u,v);
	int *b =solve(2*id+1,mid+1,r,u,v);
	int MIN = min(a[1],b[2]);
	return new int[3]{a[0]+b[0]+2*MIN,a[1]+b[1]-MIN,a[2]+b[2]-MIN};
}
void fill(int id,int l,int r){
    if (l==r) {
		if (str[l-1]=='(') {
		    tree[id][0] = 0;
		    tree[id][1]= 1;
		    tree[id][2] =0;

		}
		else{

		 tree[id][0] = 0;
		 tree[id][1]=0;
		 tree[id][2] =1;
		}
		return;
	}
	int mid = (l+r)/2;
	fill(2*id,l,mid);
	fill(2*id+1,mid+1,r);
	int MIN = min(tree[2*id][1],tree[2*id+1][2]);
	tree[id][0] = tree[2*id][0] + tree[2*id+1][0] + 2*MIN;
	tree[id][1] = tree[2*id][1] + tree[2*id+1][1] -MIN;
	tree[id][2] = tree[2*id][2] + tree[2*id+1][2] - MIN;

}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    cin>>str;
    sz = str.size();
    n = sz;

   // int** tree = new int*[2*n];

    char tmp;
    int MIN,l,r;

    fill(1,1,n);

    cin>>N;
    while(N--)
    {
        cin>>l>>r;

        int * ans = solve(1,1,n,l,r);
        cout<<ans[0]<<endl;
        //delete ans;
    }

    return 0;
}


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

int* query(int** tree,int ts,int te,int qs,int qe,int pos)
{
            int* a = new int[3];
    //cout<<ts<<" "<<te<< " "<<pos<<endl;
    if(qs<=ts && qe>=te)
    {
        a[0]  = tree[pos][0];
        a[1]  = tree[pos][1];
        a[2]  = tree[pos][2];
        return a;
    }
    if(qs>te || qe<ts)
    {
        a[0] = 0;
        a[1] = 0;
        a[2] = 0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(tree,ts,mid,qs,qe,2*pos);
    int* rt = query(tree,mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    a[0] = lf[0]+rt[0]+ 2*MIN;
    a[1] = lf[1]+rt[1]-MIN;
    a[2] = lf[2]+rt[2]-MIN;
     delete lf;
     delete rt;
    return a;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    string str;
    cin>>str;
    sz = str.size();
    n = pow(2, (int)ceil(log2(sz)));

    int** tree = new int*[2*n];

    char tmp;
    int MIN,l,r;
    for(int i=0;i<n;i++)
    {
            tree[n+i] = new int[3];

            if(i<sz)
            {
                if(str[i]=='(')
                {
                    tree[n+i][0] = 0;
                    tree[n+i][1] = 1;
                    tree[n+i][2] = 0;
                }
                else if(str[i]==')')
                {
                    tree[n+i][0] = 0;
                    tree[n+i][1] = 0;
                    tree[n+i][2] = 1;

                }
            }
            else
            {
                tree[n+i][0]= 0;
                tree[n+i][1] = 0;
                tree[n+i][2] = 0;
            }

    }

    for(int i=n-1;i>=1;i--)
    {
        MIN = min(tree[2*i][1],tree[2*i+1][2]);
        tree[i] =new int[3];
        tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
        tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
        tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    }
    // for(int i=1;i<2*n;i++)
    // {
    //     //MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;

        int * ans = query(tree,1,n,l,r,1);
        cout<<ans[0]<<endl;
        delete ans;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MAX 1000009
int tree[MAX][3];
int* query(int ts,int te,int qs,int qe,int pos)
{
    if(qs<=ts && qe>=te)
    {
        return tree[pos];
    }
    if(qs>te || qe<ts)
    {
        int* a = new int[3];
        a[0]=0;
        a[1]= 0;
        a[2] =0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(ts,mid,qs,qe,2*pos);
    int* rt = query(mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    int* ret =  new int[3];
    ret[0] = lf[0]+rt[0]+ 2*MIN;
    ret[1] = lf[1]+rt[1]-MIN;
    ret[2] = lf[2]+rt[2]-MIN;
    // delete lf;
    // delete rt;
    return ret;
}

int main()
{
    int n,N,sz;
    string str;
    cin>>str;
    sz = str.size();
    n = pow(2, (int)ceil(log2(sz)));
    memset(tree, 0, sizeof tree);
    char tmp;
    int MIN,l,r;
    for(int i=0;i<sz;i++)
    {

            if(str[i]=='(')
                tree[n+i][1] = 1;
            else if(str[i]==')')
                tree[n+i][2] = 1;

    }

    for(int i=n-1;i>=1;i--)
    {
        MIN = min(tree[2*i][1],tree[2*i+1][2]);
        tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
        tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
        tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    }
    //     for(int i=0;i<=2*n;i++)
    // {
    //     MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;
        int * ans = query(1,n,l,r,1);
        cout<<ans[0]<<endl;
        //delete ans;
    }

    return 0;
}


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

int* query(int** tree,int ts,int te,int qs,int qe,int pos)
{
            int* a = new int[3];
    //cout<<ts<<" "<<te<< " "<<pos<<endl;
    if(qs<=ts && qe>=te)
    {
        a[0]  = tree[pos][0];
        a[1]  = tree[pos][1];
        a[2]  = tree[pos][2];
        return a;
    }
    if(qs>te || qe<ts)
    {
        a[0] = 0;
        a[1] = 0;
        a[2] = 0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(tree,ts,mid,qs,qe,2*pos);
    int* rt = query(tree,mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    a[0] = lf[0]+rt[0]+ 2*MIN;
    a[1] = lf[1]+rt[1]-MIN;
    a[2] = lf[2]+rt[2]-MIN;
     delete lf;
     delete rt;
    return a;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n,N,sz;
    string str;
    cin>>str;
    sz = str.size();
    n = pow(2, (int)ceil(log2(sz)));

    int** tree = new int*[2*n];

    char tmp;
    int MIN,l,r;
    for(int i=0;i<n;i++)
    {
            tree[n+i] = new int[3];

            if(i<sz)
            {
                if(str[i]=='(')
                {
                    tree[n+i][0] = 0;
                    tree[n+i][1] = 1;
                    tree[n+i][2] = 0;
                }
                else if(str[i]==')')
                {
                    tree[n+i][0] = 0;
                    tree[n+i][1] = 0;
                    tree[n+i][2] = 1;

                }
            }
            else
            {
                tree[n+i][0]= 0;
                tree[n+i][1] = 0;
                tree[n+i][2] = 0;
            }

    }

    for(int i=n-1;i>=1;i--)
    {
        MIN = min(tree[2*i][1],tree[2*i+1][2]);
        tree[i] =new int[3];
        tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
        tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
        tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    }
    // for(int i=1;i<2*n;i++)
    // {
    //     //MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;

        int * ans = query(tree,1,n,l,r,1);
        cout<<ans[0]<<endl;
        delete ans;
    }

    return 0;
}


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

 struct tree
{
    int a,b,c;
    tree(int x=0,int y=0, int z=0)
    {
        a=x;
        b=y;
        c=z;
    }
};
tree T[MAX];
    string str;

tree solve(int id,int l, int r, int u, int v) {
       // cout<<l<<" "<<r<< " "<<id<<endl;

	if (u>r || v<l) return tree(0,0,0);
	if (u<=l && r<=v) return T[id];
	int mid = (l+r)/2;
	tree a = solve(2*id,l,mid,u,v);
	tree b =solve(2*id+1,mid+1,r,u,v);
	int MIN = min(a.b,b.c);
	return tree(a.a+b.a+2*MIN,a.b+b.b-MIN,a.c+b.c-MIN);
}
void fill(int id,int l,int r){

    if (l==r) {
		if (str[l-1]=='(') {
		    T[id] =tree(0,1,0);
		}
		else{
		 T[id]=tree(0,0,1);
		}
		return;
	}
	int mid = (l+r)/2;
	fill(2*id,l,mid);
	fill(2*id+1,mid+1,r);
	int MIN = min(T[2*id].b,T[2*id+1].c);
	T[id]= tree(T[2*id].a+ T[2*id+1].a + 2*MIN, T[2*id].b + T[2*id+1].b -MIN,T[2*id].c + T[2*id+1].c - MIN);

}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    cin>>str;
    n = str.size();

    int MIN,l,r;

    fill(1,1,n);
    // for(int i=1;i<2*n;i++)
    // {
    //     //MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<T[i].a <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;
        cout<<solve(1,1,n,l,r).a<<endl;
    }

    return 0;
}


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

int tree[MAX][3];
    string str;

int* query(int ts,int te,int qs,int qe,int pos)
{
            int* a = new int[3];
    //cout<<ts<<" "<<te<< " "<<pos<<endl;
    if(qs<=ts && qe>=te)
    {
        a[0]  = tree[pos][0];
        a[1]  = tree[pos][1];
        a[2]  = tree[pos][2];
        return a;
    }
    if(qs>te || qe<ts)
    {
        a[0] = 0;
        a[1] = 0;
        a[2] = 0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(ts,mid,qs,qe,2*pos);
    int* rt = query(mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    a[0] = lf[0]+rt[0]+ 2*MIN;
    a[1] = lf[1]+rt[1]-MIN;
    a[2] = lf[2]+rt[2]-MIN;
     delete lf;
     delete rt;
    return a;
}
void fill(int id,int l,int r){
    if (l==r) {
		if (str[l-1]=='(') {
		    tree[id][0] = 0;
		    tree[id][1]= 1;
		    tree[id][2] =0;

		}
		else{

		 tree[id][0] = 0;
		 tree[id][1]=0;
		 tree[id][2] =1;
		}
		return;
	}
	int mid = (l+r)/2;
	fill(2*id,l,mid);
	fill(2*id+1,mid+1,r);
	int MIN = min(tree[2*id][1],tree[2*id+1][2]);
	tree[id][0] = tree[2*id][0] + tree[2*id+1][0] + 2*MIN;
	tree[id][1] = tree[2*id][1] + tree[2*id+1][1] -MIN;
	tree[id][2] = tree[2*id][2] + tree[2*id+1][2] - MIN;

}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    cin>>str;
    sz = str.size();
    n = sz;

   // int** tree = new int*[2*n];

    char tmp;
    int MIN,l,r;
    // for(int i=0;i<n;i++)
    // {
    //       // tree[n+i] = new int[3];

    //         if(i<sz)
    //         {
    //             if(str[i]=='(')
    //             {
    //                 tree[n+i][0] = 0;
    //                 tree[n+i][1] = 1;
    //                 tree[n+i][2] = 0;
    //             }
    //             else if(str[i]==')')
    //             {
    //                 tree[n+i][0] = 0;
    //                 tree[n+i][1] = 0;
    //                 tree[n+i][2] = 1;

    //             }
    //         }
    //         else
    //         {
    //             tree[n+i][0]= 0;
    //             tree[n+i][1] = 0;
    //             tree[n+i][2] = 0;
    //         }

    // }
    fill(1,1,n);
    // for(int i=n-1;i>=1;i--)
    // {
    //     MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     tree[i] =new int[3];
    //     tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
    //     tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
    //     tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    // }
    // for(int i=1;i<2*n;i++)
    // {
    //     //MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;

        int * ans = query(1,n,l,r,1);
        cout<<ans[0]<<endl;
        delete ans;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MAX 10000009
int tree[MAX][3];
int* query(int ts,int te,int qs,int qe,int pos)
{
    if(qs<=ts && qe>=te)
    {
        return tree[pos];
    }
    if(qs>te || qe<ts)
    {
        int* a = new int[3];
        a[0]=0;
        a[1]= 0;
        a[2] =0;
        return a;
    }
    int mid = ts + (te-ts)/2;

    int* lf =  query(ts,mid,qs,qe,2*pos);
    int* rt = query(mid+1,te,qs,qe,2*pos+1);
    int MIN = min(lf[1],rt[2]);
    int* ret =  new int[3];
    ret[0] = lf[0]+rt[0]+ 2*MIN;
    ret[1] = lf[1]+rt[1]-MIN;
    ret[2] = lf[2]+rt[2]-MIN;
    // delete lf;
    // delete rt;
    return ret;
}

int main()
{
    int n,N,sz;
    string str;
    cin>>str;
    sz = str.size();
    n = pow(2, (int)ceil(log2(sz)));
    memset(tree, 0, sizeof tree);
    char tmp;
    int MIN,l,r;
    for(int i=0;i<sz;i++)
    {

            if(str[i]=='(')
                tree[n+i][1] = 1;
            else if(str[i]==')')
                tree[n+i][2] = 1;

    }

    for(int i=n-1;i>=1;i--)
    {
        MIN = min(tree[2*i][1],tree[2*i+1][2]);
        tree[i][0] = tree[2*i][0]+tree[2*i+1][0] + 2*MIN;
        tree[i][1] = tree[2*i][1]+tree[2*i+1][1] - MIN;
        tree[i][2] = tree[2*i][2]+tree[2*i+1][2] - MIN;

    }
    //     for(int i=0;i<=2*n;i++)
    // {
    //     MIN = min(tree[2*i][1],tree[2*i+1][2]);
    //     cout<<i<<" "<<tree[i][0] <<endl;

    // }
    cin>>N;
    while(N--)
    {
        cin>>l>>r;
        int * ans = query(1,n,l,r,1);
        cout<<ans[0]<<endl;
        //delete ans;
    }

    return 0;
}


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

int tree[MAX][3];
    string str;

int  * solve(int id,int l, int r, int u, int v) {
       // cout<<l<<" "<<r<< " "<<id<<endl;

	if (u>r || v<l) return new int[3]{0,0,0};
	if (u<=l && r<=v) return tree[id];
	int mid = (l+r)/2;
	int *a ;
	a =solve(2*id,l,mid,u,v);
	int *b =solve(2*id+1,mid+1,r,u,v);
	int MIN = min(a[1],b[2]);
	return new int[3]{a[0]+b[0]+2*MIN,a[1]+b[1]-MIN,a[2]+b[2]-MIN};
}
void fill(int id,int l,int r){
    if (l==r) {
		if (str[l-1]=='(') {
		    tree[id][0] = 0;
		    tree[id][1]= 1;
		    tree[id][2] =0;

		}
		else{

		 tree[id][0] = 0;
		 tree[id][1]=0;
		 tree[id][2] =1;
		}
		return;
	}
	int mid = (l+r)/2;
	fill(2*id,l,mid);
	fill(2*id+1,mid+1,r);
	int MIN = min(tree[2*id][1],tree[2*id+1][2]);
	tree[id][0] = tree[2*id][0] + tree[2*id+1][0] + 2*MIN;
	tree[id][1] = tree[2*id][1] + tree[2*id+1][1] -MIN;
	tree[id][2] = tree[2*id][2] + tree[2*id+1][2] - MIN;

}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);

    int n,N,sz;
    cin>>str;
    sz = str.size();
    n = sz;

   // int** tree = new int*[2*n];

    char tmp;
    int MIN,l,r;

    fill(1,1,n);

    cin>>N;
    while(N--)
    {
        cin>>l>>r;

        int * ans = solve(1,1,n,l,r);
        cout<<ans[0]<<endl;
        //delete ans;
    }

    return 0;
}


#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
		string str;
		int num,l,r;
		cin >> str;
		cin >> num;
		stack<char> st;
		while (num-->0) {
//			System.out.println("1");
			cin >> l ;
			cin >> r;
//			System.out.println(l+"\t"+r);
			int len = (r - l) + 1;
			for (int i=l-1 ; i<r;i++) {
				if (str[i] == ')' && !st.empty() && (char)st.top() == '(' ) {
					st.pop();
				} else {
					st.push(str[i]);
				}
			}
			cout << len - st.size();

			while (!st.empty())
			st.pop();

		}
	return 0;
}


//#include<iostream>
//#include<stdio.h>
//#include<stack>
//#include<algorithm>
//using namespace std;
//
///* run this program using the console pauser or add your own getch, system("pause") or input loop */
//
//int main(int argc, char** argv) {
//		string str;
//		int num,l,r;
//		cin >> str;
//		cin >> num;
//		int str_len = str.length();
//		int res[str_len][str_len];
//		stack<char> st;
//
//		for (int i=0;i<str_len;i++) {
//			for (int j=i;j<str_len;j++) {
//				if (str[j] == ')' && !st.empty() && (char)st.top() == '(' ) {
//					st.pop();
//				} else {
//					st.push(str[j]);
//				}
//				res[i][j]= j - i - st.size() + 1;
//			}
//			while (!st.empty()) {
//				st.pop();
//			}
//		}
//
//		while (num-->0) {
//			cin >> l;
//			cin >> r;
//			cout << res[l-1][r-1] << "\n";
//		}
//
//	return 0;
//}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define MAXN 1111111
using namespace std;
struct Node
{
    int l,r,all;
    Node()
    {
        l=r=all=0;
    }
    Node(int a,int b,int c)
    {
        l=a,r=b,all=c;
    }
};
Node sum[MAXN<<2];
char str[MAXN];
void pushup(int rt)
{
    int t=min(sum[rt<<1].l,sum[rt<<1|1].r);
    sum[rt].all=sum[rt<<1].all+sum[rt<<1|1].all+t;
    sum[rt].l=sum[rt<<1].l+sum[rt<<1|1].l-t;
    sum[rt].r=sum[rt<<1].r+sum[rt<<1|1].r-t;
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        if(str[l]=='(')
            sum[rt].l++;
        else if(str[l]==')')
            sum[rt].r++;
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}
Node query(int l,int r,int L,int R,int rt)
{
    if(l>=L&&R>=r)
        return sum[rt];
    Node cnt1,cnt2;
    int mid=(l+r)>>1;
    if(L<=mid)
        cnt1=query(l,mid,L,R,rt<<1);
    if(R>mid)
        cnt2=query(mid+1,r,L,R,rt<<1|1);
    int t=min(cnt1.l,cnt2.r);
    return Node(cnt1.l+cnt2.l-t,cnt1.r+cnt2.r-t,cnt1.all+cnt2.all+t);
}
int main()
{
    int q,l,r;
    scanf("%s",str+1);
    scanf("%d",&q);
    int n=strlen(str+1);
    build(1,n,1);
//    for (int i=1;i<=2*n;i++) {
//    	cout  << sum[i].l << "\t" << sum[i].r << "\t" << sum[i].all << "\n";
//	}

    while(q--)
    {
        scanf("%d %d",&l,&r);
        printf("%d\n",2*query(1,n,l,r,1).all);
    }
    return 0;
}


#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
		string str;
		int num,l,r;
		cin >> str;
		cin >> num;
		stack<char> st;
		while (num-->0) {
//			System.out.println("1");
			cin >> l ;
			cin >> r;
//			System.out.println(l+"\t"+r);
			int len = (r - l) + 1;
			for (int i=l-1 ; i<r;i++) {
				if (str[i] == ')' && !st.empty() && (char)st.top() == '(' ) {
					st.pop();
				} else {
					st.push(str[i]);
				}
			}
			cout << len - st.size() << "\n";

			while (!st.empty())
			st.pop();

		}
	return 0;
}


//#include<iostream>
//#include<stdio.h>
//#include<stack>
//#include<algorithm>
//using namespace std;
//
///* run this program using the console pauser or add your own getch, system("pause") or input loop */
//
//int main(int argc, char** argv) {
//		string str;
//		int num,l,r;
//		cin >> str;
//		cin >> num;
//		int str_len = str.length();
//		int res[str_len][str_len];
//		stack<char> st;
//
//		for (int i=0;i<str_len;i++) {
//			for (int j=i;j<str_len;j++) {
//				if (str[j] == ')' && !st.empty() && (char)st.top() == '(' ) {
//					st.pop();
//				} else {
//					st.push(str[j]);
//				}
//				res[i][j]= j - i - st.size() + 1;
//			}
//			while (!st.empty()) {
//				st.pop();
//			}
//		}
//
//		while (num-->0) {
//			cin >> l;
//			cin >> r;
//			cout << res[l-1][r-1] << "\n";
//		}
//
//	return 0;
//}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define MAXN 1111111
using namespace std;
struct Node
{
    int l,r,all;
    Node()
    {
        l=r=all=0;
    }
    Node(int a,int b,int c)
    {
        l=a,r=b,all=c;
    }
};
Node sum[MAXN<<2];
char str[MAXN];
void pushup(int rt)
{
    int t=min(sum[rt<<1].l,sum[rt<<1|1].r);
    sum[rt].all=sum[rt<<1].all+sum[rt<<1|1].all+t;
    sum[rt].l=sum[rt<<1].l+sum[rt<<1|1].l-t;
    sum[rt].r=sum[rt<<1].r+sum[rt<<1|1].r-t;
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        if(str[l]=='(')
            sum[rt].l++;
        else if(str[l]==')')
            sum[rt].r++;
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}
Node query(int l,int r,int L,int R,int rt)
{
    if(l>=L&&R>=r)
        return sum[rt];
    Node cnt1,cnt2;
    int mid=(l+r)>>1;
    if(L<=mid)
        cnt1=query(l,mid,L,R,rt<<1);
    if(R>mid)
        cnt2=query(mid+1,r,L,R,rt<<1|1);
    int t=min(cnt1.l,cnt2.r);
    return Node(cnt1.l+cnt2.l-t,cnt1.r+cnt2.r-t,cnt1.all+cnt2.all+t);
}
int main()
{
    int q,l,r;
    scanf("%s",str+1);
    scanf("%d",&q);
    int n=strlen(str+1);
    build(1,n,1);
    for (int i=1;i<=2*n;i++) {
    	cout  << sum[i].l << "\t" << sum[i].r << "\t" << sum[i].all << "\n";
	}

    while(q--)
    {
        scanf("%d %d",&l,&r);
        printf("%d\n",2*query(1,n,l,r,1).all);
    }
    return 0;
}


#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
		string str;
		int num,l,r;
		cin >> str;
		cin >> num;
		int str_len = str.length();
		int res[str_len][str_len] ;
		stack<char> st;
//		for (int j=0;j<str_len;j++) {
//			if (str[j] == ')' && !st.empty() && (char)st.top() == '(' ) {
//				st.pop();
//			} else {
//				st.push(str[j]);
//			}
//			res[0][j]= j - st.size() + 1;
//		}
//
//		while (!st.empty()) {
//			st.pop();
//		}
		for (int i=0;i<str_len;i++) {
			for (int j=i;j<str_len;j++) {
				if (str[j] == ')' && !st.empty() && (char)st.top() == '(' ) {
					st.pop();
				} else {
					st.push(str[j]);
				}
				res[i][j]= j - i - st.size() + 1;
			}
			while (!st.empty()) {
				st.pop();
			}
		}

//
//		for (int i=0;i<str_len;i++) {
//			for (int j=0;j<str_len;j++) {
//				if (i > j) {
//					cout << 0 << "\t";
//				} else {
//					cout << res[i][j] << "\t";
//				}
//			}
//			cout << "\n";
//		}
//
		while (num-->0) {
//			System.out.println("1");
			cin >> l;
			cin >> r;
//			System.out.println(l+"\t"+r);
			cout << res[l-1][r-1] << "\n";
		}

//		while (num-->0) {
////			System.out.println("1");
//			cin >> l ;
//			cin >> r;
////			System.out.println(l+"\t"+r);
//			int len = (r - l) + 1;
//			for (int i=l-1 ; i<r;i++) {
//				if (str[i] == ')' && !st.empty() && (char)st.top() == '(' ) {
//					st.pop();
//				} else {
//					st.push(str[i]);
//				}
//			}
//			cout << len - st.size() << "\n";
//
//			while (!st.empty())
//			st.pop();
//
//		}
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {
	string str;
	int count;
	node() {
		str = "";
		count = 0;
	}
	node(string s, int c) {
		str = s;
		count = c;
	}
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
	if (lower == upper) {
		tree[index].str = bracket[lower];//count is initialized as 0
	}
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		buildSegment(lower, mid, left);
		buildSegment(mid + 1, upper, right);
		string str1 = tree[left].str;
		string str2 = tree[right].str;
		int length1 = tree[left].str.size();
		int length2 = tree[right].str.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
				//length2--;
			}
			else {
				str1 += str2[0];
				str2.erase(str2.begin());
			}
		}
		count += tree[left].count + tree[right].count;
		tree[index] = node(str1, count);
	}
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
	if (x > upper || y<lower || x>y)
		return node("",0);
	else if (x <= lower && y >= upper)
		return tree[index];
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		node leftSub = queryCount(lower, mid, x, y, left);
		node rightSub = queryCount(mid + 1, upper, x, y, right);
		string str1 = leftSub.str;
		string str2 = rightSub.str;
		int length1 = str1.size();
		int length2 = str2.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				str1 += str2[0];
				str2.erase(str2.begin());
			}
		}
		count += leftSub.count + rightSub.count;
		return node(str1, count);
	}
}
int main() {
    ios_base::sync_with_stdio(0);
	int a, b;
	cin >> bracket;
	cin >> test;
	int size = bracket.size();
	buildSegment(0, size-1);
	for (int i = 0; i < test; i++) {
		cin >> a >> b;
		node res = queryCount(0, size - 1, a - 1, b - 1);
		cout << res.count << endl;
	}
	//system("pause");
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {//each node has type )))...((...
  int open;
  int close;
  int count;
  node() {
    open = 0;
    close = 0;
    count = 0;
  }
  node(int o, int c,int co) {
    open = o;
    close = c;
    count = co;
  }
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
  if (lower == upper) {
    if (bracket[lower] == ')')
      tree[index].close = 1;
    else
      tree[index].open = 1;
  }

  else {
    int left = 2 * index + 1;
    int right = 2 * index + 2;
    int mid = (lower + upper) / 2;
    buildSegment(lower, mid, left);
    buildSegment(mid + 1, upper, right);
    int open = tree[left].open;
    int close = tree[right].close;
    int count = 0;
    if (open <= close) {
      count += 2*open;
      close -= open;
      open = 0;
    }
    else {
      count += 2 * close;
      open -= close;
      close = 0;
    }
    count += tree[left].count + tree[right].count;
    close += tree[left].close;
    open += tree[right].open;
    tree[index] = node(open, close, count);
  }
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
  if (x > upper || y<lower || x>y)
    return node(0,0,0);
  else if (x <= lower && y >= upper)
    return tree[index];
  else {
    int left = 2 * index + 1;
    int right = 2 * index + 2;

    int mid = (lower + upper) / 2;
    node leftSub = queryCount(lower, mid, x, y, left);
    node rightSub = queryCount(mid + 1, upper, x, y, right);
    int open = leftSub.open;
    int close = rightSub.close;
    int count = 0;
    if (open <= close) {
      count += 2*open;
      close -= open;
      open = 0;
    }
    else {
      count += 2 * close;
      open -= close;
      close = 0;
    }
    count += leftSub.count + rightSub.count;
    close += leftSub.close;
    open += rightSub.open;
    return node(open, close, count);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  int a, b;
  cin >> bracket;

  cin >> test;
  int size = bracket.size();
  buildSegment(0, size-1);
  for (int i = 0; i < test; i++) {
    cin >> a >> b;
    node res = queryCount(0, size - 1, a - 1, b - 1);
    cout << res.count << endl;
  }
  //system("pause");
  return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {
	string str;
	int count;
	node() {
		str = "";
		count = 0;
	}
	node(string s, int c) {
		str = s;
		count = c;
	}
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
	if (lower == upper) {
		tree[index].str = bracket[lower];//count is initialized as 0
	}
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		buildSegment(lower, mid, left);
		buildSegment(mid + 1, upper, right);
		string str1 = tree[left].str;
		string str2 = tree[right].str;
		int length1 = tree[left].str.size();
		int length2 = tree[right].str.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
				length2--;
			}
			else {
				str1 += str2[0];
				str2.erase(str2.begin());
			}
		}
		count += tree[left].count + tree[right].count;
		tree[index] = node(str1, count);
	}
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
	if (x > upper || y<lower || x>y)
		return node("",0);
	else if (x <= lower && y >= upper)
		return tree[index];
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		node leftSub = queryCount(lower, mid, x, y, left);
		node rightSub = queryCount(mid + 1, upper, x, y, right);
		string str1 = leftSub.str;
		string str2 = rightSub.str;
		int length1 = str1.size();
		int length2 = str2.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				str1 += str2[0];
				str2.erase(str2.begin());
			}
		}
		count += leftSub.count + rightSub.count;
		return node(str1, count);
	}
}
int main() {
	int a, b;
	cin >> bracket;
	cin >> test;
	int size = bracket.size();
	buildSegment(0, size-1);
	for (int i = 0; i < test; i++) {
		cin >> a >> b;
		node res = queryCount(0, size - 1, a - 1, b - 1);
		cout << res.count << endl;
	}
	//system("pause");
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {
	int open;
	int close;
	int count;
	node() {
		open = 0;
		close = 0;
		count = 0;
	}
	node(int o, int c,int co) {
		open = o;
		close = c;
		count = co;
	}
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
	if (lower == upper) {
		if (bracket[lower] == ')')
			tree[index].close = 1;
		else
			tree[index].open = 1;
	}
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		buildSegment(lower, mid, left);
		buildSegment(mid + 1, upper, right);
		int open = tree[left].open;
		int close = tree[right].close;
		int count = 0;
		if (open <= close) {
			count += 2*open;
			open = 0;
			close -= open;
		}
		else {
			count += 2 * close;
			open -= close;
			close = 0;
		}
		count += tree[left].count + tree[right].count;
		close += tree[left].close;
		open += tree[right].open;
		tree[index] = node(open, close, count);
	}
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
	if (x > upper || y<lower || x>y)
		return node(0,0,0);
	else if (x <= lower && y >= upper)
		return tree[index];
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		node leftSub = queryCount(lower, mid, x, y, left);
		node rightSub = queryCount(mid + 1, upper, x, y, right);
		int open = leftSub.open;
		int close = rightSub.close;
		int count = 0;
		if (open <= close) {
			count += 2*open;
			open = 0;
			close -= open;
		}
		else {
			count += 2 * close;
			open -= close;
			close = 0;
		}
		count += leftSub.count + rightSub.count;
		close += leftSub.close;
		open += rightSub.open;
		return node(open, close, count);
	}
}
int main() {
	ios_base::sync_with_stdio(0);
	int a, b;
	cin >> bracket;
	cin >> test;
	int size = bracket.size();
	buildSegment(0, size-1);
	for (int i = 0; i < test; i++) {
		cin >> a >> b;
		node res = queryCount(0, size - 1, a - 1, b - 1);
		cout << res.count << endl;
	}
	//system("pause");
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {
	string str;
	int count;
	node() {
		str = "";
		count = 0;
	}
	node(string s, int c) {
		str = s;
		count = c;
	}
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
	if (lower == upper) {
		tree[index].str = bracket[lower];//count is initialized as 0
	}
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		buildSegment(lower, mid, left);
		buildSegment(mid + 1, upper, right);
		string str1 = tree[left].str;
		string str2 = tree[right].str;
		int length1 = tree[left].str.size();
		int length2 = tree[right].str.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				/*str1 += str2[0];
				str2.erase(str2.begin());*/
				break;
			}
		}
		str1 += str2;
		count += tree[left].count + tree[right].count;
		tree[index] = node(str1, count);
	}
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
	if (x > upper || y<lower || x>y)
		return node("",0);
	else if (x <= lower && y >= upper)
		return tree[index];
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		node leftSub = queryCount(lower, mid, x, y, left);
		node rightSub = queryCount(mid + 1, upper, x, y, right);
		string str1 = leftSub.str;
		string str2 = rightSub.str;
		int length1 = str1.size();
		int length2 = str2.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				/*str1 += str2[0];
				str2.erase(str2.begin());*/
				break;
			}
		}
		str1 += str2;
		count += leftSub.count + rightSub.count;
		return node(str1, count);
	}
}
int main() {
    ios_base::sync_with_stdio(0);
	int a, b;
	cin >> bracket;
	cin >> test;
	int size = bracket.size();
	buildSegment(0, size-1);
	for (int i = 0; i < test; i++) {
		cin >> a >> b;
		node res = queryCount(0, size - 1, a - 1, b - 1);
		cout << res.count << endl;
	}
	//system("pause");
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {
	string str;
	int count;
	node() {
		str = "";
		count = 0;
	}
	node(string s, int c) {
		str = s;
		count = c;
	}
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
	if (lower == upper) {
		tree[index].str = bracket[lower];//count is initialized as 0
	}
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		buildSegment(lower, mid, left);
		buildSegment(mid + 1, upper, right);
		string str1 = tree[left].str;
		string str2 = tree[right].str;
		int length1 = tree[left].str.size();
		int length2 = tree[right].str.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				str1 += str2[0];
				str2.erase(str2.begin());
			}
		}
		count += tree[left].count + tree[right].count;
		tree[index] = node(str1, count);
	}
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
	if (x > upper || y<lower || x>y)
		return node("",0);
	else if (x <= lower && y >= upper)
		return tree[index];
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		node leftSub = queryCount(lower, mid, x, y, left);
		node rightSub = queryCount(mid + 1, upper, x, y, right);
		string str1 = leftSub.str;
		string str2 = rightSub.str;
		int length1 = str1.size();
		int length2 = str2.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				str1 += str2[0];
				str2.erase(str2.begin());
			}
		}
		count += leftSub.count + rightSub.count;
		return node(str1, count);
	}
}
int main() {
	int a, b;
	cin >> bracket;
	cin >> test;
	int size = bracket.size();
	buildSegment(0, size-1);
	for (int i = 0; i < test; i++) {
		cin >> a >> b;
		node res = queryCount(0, size - 1, a - 1, b - 1);
		cout << res.count << endl;
	}
	//system("pause");
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {
	string str;
	int count;
	node() {
		str = "";
		count = 0;
	}
	node(string s, int c) {
		str = s;
		count = c;
	}
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
	if (lower == upper) {
		tree[index].str = bracket[lower];//count is initialized as 0
	}
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		buildSegment(lower, mid, left);
		buildSegment(mid + 1, upper, right);
		string str1 = tree[left].str;
		string str2 = tree[right].str;
		int length1 = tree[left].str.size();
		int length2 = tree[right].str.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				/*str1 += str2[0];
				str2.erase(str2.begin());*/
				break;
			}
		}
		str1 += str2;
		count += tree[left].count + tree[right].count;
		tree[index] = node(str1, count);
	}
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
	if (x > upper || y<lower || x>y)
		return node("",0);
	else if (x <= lower && y >= upper)
		return tree[index];
	else {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int mid = (lower + upper) / 2;
		node leftSub = queryCount(lower, mid, x, y, left);
		node rightSub = queryCount(mid + 1, upper, x, y, right);
		string str1 = leftSub.str;
		string str2 = rightSub.str;
		int length1 = str1.size();
		int length2 = str2.size();
		int count = 0;
		for (int i = 0; i < length2; i++) {
			if (!str1.empty() && str1[length1 - 1] == '(' && str2[0] == ')') {
				count += 2;
				str1.erase(str1.end() - 1);
				str2.erase(str2.begin());
				length1--;
			}
			else {
				/*str1 += str2[0];
				str2.erase(str2.begin());*/
				break;
			}
		}
		str1 += str2;
		count += leftSub.count + rightSub.count;
		return node(str1, count);
	}
}
int main() {
	int a, b;
	cin >> bracket;
	cin >> test;
	int size = bracket.size();
	buildSegment(0, size-1);
	for (int i = 0; i < test; i++) {
		cin >> a >> b;
		node res = queryCount(0, size - 1, a - 1, b - 1);
		cout << res.count << endl;
	}
	//system("pause");
	return 0;
}


#include <iostream>
#include <string>
using namespace std;
string bracket;
int test;
struct node {//each node has type )))...((...
  int open;
  int close;
  int count;
  node() {
    open = 0;
    close = 0;
    count = 0;
  }
  node(int o, int c,int co) {
    open = o;
    close = c;
    count = co;
  }
};
node tree[4000003];

void buildSegment(int lower, int upper, int index=0) {
  if (lower == upper) {
    if (bracket[lower] == ')')
      tree[index].close = 1;
    else
      tree[index].open = 1;
  }

  else {
    int left = 2 * index + 1;
    int right = 2 * index + 2;
    int mid = (lower + upper) / 2;
    buildSegment(lower, mid, left);
    buildSegment(mid + 1, upper, right);
    int open = tree[left].open;
    int close = tree[right].close;
    int count = 0;
    if (open <= close) {
      count += 2*open;
      close -= open;
      open = 0;
    }
    else {
      count += 2 * close;
      open -= close;
      close = 0;
    }
    count += tree[left].count + tree[right].count;
    close += tree[left].close;
    open += tree[right].open;
    tree[index] = node(open, close, count);
  }
}
node queryCount(int lower, int upper, int x, int y, int index = 0) {
  if (x > upper || y<lower || x>y)
    return node(0,0,0);
  else if (x <= lower && y >= upper)
    return tree[index];
  else {
    int left = 2 * index + 1;
    int right = 2 * index + 2;

    int mid = (lower + upper) / 2;
    node leftSub = queryCount(lower, mid, x, y, left);
    node rightSub = queryCount(mid + 1, upper, x, y, right);
    int open = leftSub.open;
    int close = rightSub.close;
    int count = 0;
    if (open <= close) {
      count += 2*open;
      close -= open;
      open = 0;
    }
    else {
      count += 2 * close;
      open -= close;
      close = 0;
    }
    count += leftSub.count + rightSub.count;
    close += leftSub.close;
    open += rightSub.open;
    return node(open, close, count);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  int a, b;
  cin >> bracket;

  cin >> test;
  int size = bracket.size();
  buildSegment(0, size-1);
  for(int i=0;i<15;i++){
    cout<<tree[i].count<<" "<<tree[i].open<<" "<<tree[i].close<<endl;
  }
  cout<<endl;
  for (int i = 0; i < test; i++) {
    cin >> a >> b;
    node res = queryCount(0, size - 1, a - 1, b - 1);
    cout << res.count << endl;
  }
  //system("pause");
  return 0;
}


#include <iostream>
#include<bits/stdc++.h>
#define lop(i,l,n) for(int i = l;i <= n;++i)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define lsc(x) scanf("%I64d",&x)
#define maximum (long long int)1000000000
using namespace std;
char s[1000100];
struct node
{
	int valid;
	int open;
	int close;
	node()
	{

	}
	node(int v,int o ,int c)
	{
		valid=v;
		open=o;
		close=c;
	}

};
node seg[4*1000100];
int n;
void build(int id=1,int l=0,int r=n)
{
	if(r-l<2)
	{
		seg[id]=node(0,s[l]=='(',s[l]==')');
		return;
	}
	int mid=(l+r)/2;
	build(id<<2,l,mid);
	build((id<<2)+1,mid,r);
	seg[id].valid=seg[id<<2].valid+min(seg[(id<<2)+1].close,seg[id<<2].open)*2+seg[(id<<2)+1].valid;
	seg[id].open=seg[(id<<2)+1].open+max(0,seg[id<<2].open-seg[(id<<2)+1].close);
	seg[id].close=seg[(id<<2)].close+max(0,seg[(id<<2)+1].close-seg[(id<<2)].open);

}
node query(int x,int y,int id=1,int l=0,int r=n)
{
	if(r<=x||l>=y) return node(0,0,0);
	if(l>=x&&r<=y)return seg[id];
	int mid=(l+r)/2;
	node n1= query(x,y,id<<2,l,mid);
    node n2=query(x,y,(id<<2)+1,mid,r);
    return node(n1.valid+min(n2.close,n1.open)*2+n2.valid,n2.open+max(0,n1.open-n2.close),n1.close+max(0,n2.close-n1.open));

}
int main()
{
      scanf("%s",s);
      n=(int)strlen(s);
      int q;
      sc(q);

     build();

      while(q--)
      {
    	  int x,y;
    	  scc(x,y);
    	  printf("%d\n",query(x-1,y).valid);
      }
}


#include <iostream>
#include<bits/stdc++.h>
#define lop(i,l,n) for(int i = l;i <= n;++i)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define lsc(x) scanf("%I64d",&x)
#define maximum (long long int)1000000000
using namespace std;
int arr[4000000];
struct node
{
	int valid;
	int open;
	int close;
	node()
	{

	}
	node(int v,int o ,int c)
	{
		valid=v;
		open=o;
		close=c;
	}

};
node seg[1000000];
string s;
void build(int id=1,int l=0,int r=s.length())
{
	if(r-l<2)
	{
		seg[id]=node(0,s[l]=='(',s[l]==')');
		return;
	}
	int mid=(l+r)/2;
	build(id<<2,l,mid);
	build((id<<2)+1,mid,r);
	seg[id].valid=seg[id<<2].valid+min(seg[(id<<2)+1].close,seg[id<<2].open)*2+seg[(id<<2)+1].valid;
	seg[id].open=seg[(id<<2)+1].open+max(0,seg[id<<2].open-seg[(id<<2)+1].close);
	seg[id].close=seg[(id<<2)].close+max(0,seg[(id<<2)+1].close-seg[(id<<2)].open);

}
node query(int x,int y,int id=1,int l=0,int r=s.length())
{
	if(r<=x||l>=y) return node(0,0,0);
	if(l>=x&&r<=y)return seg[id];
	int mid=(l+r)/2;
	node n1= query(x,y,id<<2,l,mid);
    node n2=query(x,y,(id<<2)+1,mid,r);
    return node(n1.valid+min(n2.close,n1.open)*2+n2.valid,n2.open+max(0,n1.open-n2.close),n1.close+max(0,n2.close-n1.open));

}
int main()
{
      cin>>s;
      int q;
      sc(q);

     build();

      while(q--)
      {
    	  int x,y;
    	  scc(x,y);
    	  printf("%d\n",query(x-1,y).valid);
      }
}


#include <iostream>
#include<bits/stdc++.h>
#define lop(i,l,n) for(int i = l;i <= n;++i)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define lsc(x) scanf("%I64d",&x)
#define maximum (long long int)1000000000
using namespace std;
char s[1000100];
struct node
{
	int valid;
	int open;
	int close;
	node()
	{

	}
	node(int v,int o ,int c)
	{
		valid=v;
		open=o;
		close=c;
	}

};
node seg[4*1000100];
int n;
void build(int id=1,int l=0,int r=n)
{
	if(r-l<2)
	{
		seg[id]=node(0,s[l]=='(',s[l]==')');
		return;
	}
	int mid=(l+r)/2;
	build(id<<1,l,mid);
	build((id<<1)+1,mid,r);
	seg[id].valid=seg[id<<1].valid+min(seg[(id<<1)+1].close,seg[id<<1].open)*2+seg[(id<<1)+1].valid;
	seg[id].open=seg[(id<<1)+1].open+max(0,seg[id<<1].open-seg[(id<<1)+1].close);
	seg[id].close=seg[(id<<1)].close+max(0,seg[(id<<1)+1].close-seg[(id<<1)].open);

}
node query(int x,int y,int id=1,int l=0,int r=n)
{
	if(r<=x||l>=y) return node(0,0,0);
	if(l>=x&&r<=y)return seg[id];
	int mid=(l+r)/2;
	node n1= query(x,y,id<<1,l,mid);
    node n2=query(x,y,(id<<1)+1,mid,r);
    return node(n1.valid+min(n2.close,n1.open)*2+n2.valid,n2.open+max(0,n1.open-n2.close),n1.close+max(0,n2.close-n1.open));

}
int main()
{
      scanf("%s",s);
      n=(int)strlen(s);
      int q;
      sc(q);

     build();

      while(q--)
      {
    	  int x,y;
    	  scc(x,y);
    	  printf("%d\n",query(x-1,y).valid);
      }
}


#include <iostream>
#include<bits/stdc++.h>
#define lop(i,l,n) for(int i = l;i <= n;++i)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define lsc(x) scanf("%I64d",&x)
#define maximum (long long int)1000000000
using namespace std;

struct node
{
	int valid;
	int open;
	int close;
	node()
	{

	}
	node(int v,int o ,int c)
	{
		valid=v;
		open=o;
		close=c;
	}

};
node seg[4*1000100];
string s;
void build(int id=1,int l=0,int r=s.length())
{
	if(r-l<2)
	{
		seg[id]=node(0,s[l]=='(',s[l]==')');
		return;
	}
	int mid=(l+r)/2;
	build(id<<2,l,mid);
	build((id<<2)+1,mid,r);
	seg[id].valid=seg[id<<2].valid+min(seg[(id<<2)+1].close,seg[id<<2].open)*2+seg[(id<<2)+1].valid;
	seg[id].open=seg[(id<<2)+1].open+max(0,seg[id<<2].open-seg[(id<<2)+1].close);
	seg[id].close=seg[(id<<2)].close+max(0,seg[(id<<2)+1].close-seg[(id<<2)].open);

}
node query(int x,int y,int id=1,int l=0,int r=s.length())
{
	if(r<=x||l>=y) return node(0,0,0);
	if(l>=x&&r<=y)return seg[id];
	int mid=(l+r)/2;
	node n1= query(x,y,id<<2,l,mid);
    node n2=query(x,y,(id<<2)+1,mid,r);
    return node(n1.valid+min(n2.close,n1.open)*2+n2.valid,n2.open+max(0,n1.open-n2.close),n1.close+max(0,n2.close-n1.open));

}
int main()
{
      cin>>s;
      int q;
      sc(q);

     build();

      while(q--)
      {
    	  int x,y;
    	  scc(x,y);
    	  printf("%d\n",query(x-1,y).valid);
      }
}


#include <iostream>
#include<bits/stdc++.h>
#define lop(i,l,n) for(int i = l;i <= n;++i)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define lsc(x) scanf("%I64d",&x)
#define maximum (long long int)1000000000
using namespace std;

struct node
{
	int valid;
	int open;
	int close;
	node()
	{

	}
	node(int v,int o ,int c)
	{
		valid=v;
		open=o;
		close=c;
	}

};
node seg[4*1000000+10];
string s;
void build(int id=1,int l=0,int r=s.length())
{
	if(r-l<2)
	{
		seg[id]=node(0,s[l]=='(',s[l]==')');
		return;
	}
	int mid=(l+r)/2;
	build(id<<2,l,mid);
	build((id<<2)+1,mid,r);
	seg[id].valid=seg[id<<2].valid+min(seg[(id<<2)+1].close,seg[id<<2].open)*2+seg[(id<<2)+1].valid;
	seg[id].open=seg[(id<<2)+1].open+max(0,seg[id<<2].open-seg[(id<<2)+1].close);
	seg[id].close=seg[(id<<2)].close+max(0,seg[(id<<2)+1].close-seg[(id<<2)].open);

}
node query(int x,int y,int id=1,int l=0,int r=s.length())
{
	if(r<=x||l>=y) return node(0,0,0);
	if(l>=x&&r<=y)return seg[id];
	int mid=(l+r)/2;
	node n1= query(x,y,id<<2,l,mid);
    node n2=query(x,y,(id<<2)+1,mid,r);
    return node(n1.valid+min(n2.close,n1.open)*2+n2.valid,n2.open+max(0,n1.open-n2.close),n1.close+max(0,n2.close-n1.open));

}
int main()
{
      cin>>s;
      int q;
      sc(q);

     build();

      while(q--)
      {
    	  int x,y;
    	  scc(x,y);
    	  printf("%d\n",query(x-1,y).valid);
      }
}


#include <iostream>
#include<bits/stdc++.h>
#define lop(i,l,n) for(int i = l;i <= n;++i)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define lsc(x) scanf("%I64d",&x)
#define maximum (long long int)1000000000
using namespace std;
int arr[4000000];
struct node
{
	int valid;
	int open;
	int close;
	node()
	{

	}
	node(int v,int o ,int c)
	{
		valid=v;
		open=o;
		close=c;
	}

};
node seg[4*1000000];
string s;
void build(int id=1,int l=0,int r=s.length())
{
	if(r-l<2)
	{
		seg[id]=node(0,s[l]=='(',s[l]==')');
		return;
	}
	int mid=(l+r)/2;
	build(id<<2,l,mid);
	build((id<<2)+1,mid,r);
	seg[id].valid=seg[id<<2].valid+min(seg[(id<<2)+1].close,seg[id<<2].open)*2+seg[(id<<2)+1].valid;
	seg[id].open=seg[(id<<2)+1].open+max(0,seg[id<<2].open-seg[(id<<2)+1].close);
	seg[id].close=seg[(id<<2)].close+max(0,seg[(id<<2)+1].close-seg[(id<<2)].open);

}
node query(int x,int y,int id=1,int l=0,int r=s.length())
{
	if(r<=x||l>=y) return node(0,0,0);
	if(l>=x&&r<=y)return seg[id];
	int mid=(l+r)/2;
	node n1= query(x,y,id<<2,l,mid);
    node n2=query(x,y,(id<<2)+1,mid,r);
    return node(n1.valid+min(n2.close,n1.open)*2+n2.valid,n2.open+max(0,n1.open-n2.close),n1.close+max(0,n2.close-n1.open));

}
int main()
{
      cin>>s;
      int q;
      sc(q);

     build();

      while(q--)
      {
    	  int x,y;
    	  scc(x,y);
    	  printf("%d\n",query(x-1,y).valid);
      }
}


#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int ans[4*1000000+2];
int op[4*1000000+2];
int cl[4*1000000+2];
string s;
struct node
{
    int v,o,c;
    node(int valid,int open,int closed)
    {
        v=valid;
        o=open;
        c=closed;
    }

};
void build(int id,int l,int r)
{
    if(r-l<2)
    {
        if(s[l]=='(')
        {
            op[id]=1;
        }
        else
        {
            cl[id]=1;
        }
        return;
    }
    int mid=(l+r)/2;
    build(id<<1,l,mid);
    build((id<<1)+1,mid,r);
    int re=min(op[id<<1],cl[(id<<1)+1]);
    ans[id]=ans[id<<1]+ans[(id<<1)+1]+re;
    op[id]=op[id<<1]+op[(id<<1)+1]-re;
    cl[id]=cl[id<<1]+cl[(id<<1)+1]-re;

    return;

}
node answer(int id,int l,int r,int x,int y)
{
    if(x>=r||y<=l)return node(0,0,0);
    if(x<=l&&r<=y) return node(ans[id],op[id],cl[id]);
    int mid=(l+r)/2;
    node n1=answer(id<<1,l,mid,x,y);
    node n2=answer((id<<1)+1,mid,r,x,y);
    int re=min(n1.o,n2.c);
    return node(n1.v+n2.v+re,n1.o+n2.o-re,n1.c+n2.c-re);

}

int main() {
cin>>s;
build(1,0,s.length());
int q;
int l,r;
scanf("%d",&q);
for(int i=0;i<q;++i)
{
    scanf("%d%d",&l,&r);
    printf("%d\n",answer(1,0,s.length(),l-1,r).v<<1);
}
}