#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 1001000
using namespace std;

char s[N];
int st[N];
int l[N],r[N],L[N],R[N],suml[N],sumr[N];
int main()
{

    scanf("%s",s+1);
    s[0]='.';
    int n=strlen(s)-1;
    int top=0;
    memset(l,0,sizeof(l));
    memset(r,0,sizeof(r));
    memset(suml,0,sizeof(suml));
    memset(sumr,0,sizeof(sumr));
    for (int i=1;i<=n;++i)
    {
        if (s[i]=='(')
        {
            st[++top]=i;
        }
        else
        {
            if (top)
            {
                r[st[top]]=i;
                l[i]=st[top];
                suml[st[top]]++;
                sumr[i]++;
                top--;
            }
        }
    }
    for (int i=1;i<=n;++i)
    {
        suml[i]=suml[i-1]+suml[i];
        sumr[i]=sumr[i-1]+sumr[i];

    }

    L[0]=1;
    for (int i=1;i<=n;++i)
    {
        if (r[i])
        {
            L[i]=i;
        }
        else
        {
            L[i]=L[i-1];
        }
    }

    for (int i=1;i<=n;++i)
    {
        if (L[i]==i)
            L[i]--;
    }

    R[0]=1;
    for (int i=1;i<=n;++i)
    {
        if (l[i])
        {
            R[i]=i;
        }
        else
        {
            R[i]=R[i-1];
        }
    }

    /*
    L[n+1]=n;
    for (int i=n;i>=1;--i)
    {
        if (r[i])
        {
            L[i]=i;
        }
        else
        {
            L[i]=L[i+1];
        }
    }
*/

/*
    R[0]=1;
    for (int i=0;i<=n;++i)
    {
        if (l[i])
        {
            R[i]=i;
        }
        else
        {
            R[i]=R[i-1];
        }
    }*/
/*
    for (int i=1;i<=n;++i)
        printf("%d ",L[i]);
    puts("");
    for (int i=1;i<=n;++i)
        printf("%d ",R[i]);
    puts("");*/
   // printf("%d\n",sumr[10]);
    int q;
    scanf("%d",&q);
    for (int i=0;i<q;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
      //  printf("%d %d %d %d\n",a,b,L[a],R[b]);
        if (s[a]=='(')
            a--;
      //  printf("%d\n",(sumr[b]-suml[L[a]])*2);
        printf("%d\n",(sumr[b]-suml[a])*2);

    }
    return 0;
}

/*2017-08-04 21:00:54.429*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 1001000
using namespace std;

char s[N];
int l[N],r[N],L[N],R[N];

int q[1<<22];
int M;

int Query(int s,int t)
{
    int ans=1000000000;
    for (s=s+M-1,t=t+M+1;s^t^1;s>>=1,t>>=1)
    {
        if (~s&1)	ans=min(ans,q[s^1]);
        if (t&1)	ans=min(ans,q[t^1]);
    }
	return ans;
}

int main()
{
    scanf("%s",s+1);
    s[0]='.';
    int n=strlen(s)-1;
    memset(l,0,sizeof(l));
    memset(r,0,sizeof(r));

    for (int i=1;i<=n;++i)
    {
        l[i]=l[i-1];
        r[i]=r[i-1];
        if (s[i]=='(')
        {
            l[i]++;
        }
        else
        {
            if (l[i])
            {
                r[i]++;
                l[i]--;
            }
        }
    }
    M=1;
	while (M<=n+2)	M<<=1;
	memset(q,0x3f,sizeof(q));
	for (int i=1;i<=n;++i)	q[i+M]=l[i];
	for (int i=M-1;i>=1;--i)
	{
		q[i]=min(q[i<<1],q[(i<<1)^1]);
	}
    int Q;
    scanf("%d",&Q);
    for (int i=0;i<Q;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",(r[b]-r[a-1]-max(0,l[a-1]-Query(a,b)))*2);
    }
    return 0;
}

/*2017-08-05 21:58:00.483*/


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
#define N 280000
int qr[2005][2005];
int num[2005][2005];
int ql[2005][2005];
char s[1000005];
int main()
{
    int n,m,i,j,k,len,mod,top,a,b,l,r,top2,ans;
    scanf("%s",&s);
    len=strlen(s);
    mod=sqrt(len)+1;
    for(i=0; i*mod<len; i++)
    {
        top=0;
        ans=0;
        top2=0;
        for(j=i*mod; j<len; j++)
        {
            if(s[j]==')')
            {
                if(top)
                    ans++;
                else
                {
                    top2++;
                }
                top=max(0,top-1);
            }
            else
            {
                top++;
            }
            if(j%mod==0)
            {
             //   printf("[%d %d][%d %d]=%d\n ",i*mod,j,i,j,ans);
                num[i][j/mod]=ans;
                qr[i][j/mod]=top;
                ql[i][j/mod]=top2;
            }
        }
    }
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d%d",&l,&r);
        l--;
        r--;
        if(r-l<=mod)
        {
            top=0;
            ans=0;
            for(i=l; i<=r; i++)
            {
                if(s[i]==')')
                {
                    if(top)
                        ans++;
                    top=max(0,top-1);
                }
                else
                {
                    top++;
                }
            }
            printf("%d\n",ans*2);
        }
        else
        {
            a=l+(mod-l%mod)%mod;
            b=r-r%mod;
          //  printf("[%d %d]=%d\n",a,b,mod);
            ans=num[a/mod][b/mod];
           // printf("ans=%d\n",ans);
            top=qr[a/mod][b/mod];
            top2=ql[a/mod][b/mod];
            for(i=b+1; i<=r; i++)
            {
                if(s[i]==')')
                {
                    if(top)
                        ans++;
                    else
                    {
                        top2++;
                    }
                    top=max(0,top-1);
                }
                else
                {
                    top++;
                }
            }
            for(i=a-1; i>=l; i--)
            {
                if(s[i]=='(')
                {
                    if(top2)
                        ans++;
                    top2=max(0,top2-1);
                }
                else
                {
                    top2++;
                }
            }
            printf("%d\n",ans*2);
        }
    }
    return 0;
}

/*2017-08-04 20:43:48.152*/


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

struct point {
    int cnt, op, cl;
    point (int cn, int o, int c) {
        cnt = cn;
        op = o;
        cl = c;
    }
    point () {}
};

class tree {
private:
    int z;
    vector <point> a;
public:
    tree (char *l, char *r) {
        int n = r - l + 1;
        int lg = ceil (log (n) / log (2));
        z = 1<<(lg);
        a.resize (2 * z);
        for (int i = 0; i < n; i++)
            a[i + z] = point (0, l[i] == '(', l[i] == ')');
        for (int i = n + z; i < a.size(); i++)
            a[i] = point (0, 0, 0);
        for (int i = z - 1; i > 0; i--) {
            int F = 2 * i;
            int S = F + 1;
            int tmp = min (a[F].op, a[S].cl);
            a[i].cnt = a[F].cnt + a[S].cnt + 2 * tmp;
            a[i].op = a[F].op + a[S].op - tmp;
            a[i].cl = a[F].cl + a[S].cl - tmp;
        }
        z--;
    }
    int ans (int l, int r) const {
        if (l == r)
            return 0;
        l += z;
        r += z;
        int ans = 0, opened = 0, closed = 0;
        while (l < r) {
            if (l % 2) {
                ans += a[l].cnt;
                opened += a[l].op;
                l++;
            }
            if (!(r % 2) && l != r) {
                ans += a[r].cnt;
                closed += a[r].cl;
                r--;
            }
            if (l != r) {
                l /= 2;
                r /= 2;
            }
        }
        int tmp = min (opened, a[l].cl);
        ans += 2 * tmp;
        opened -= tmp;
        tmp = min (closed, a[l].op);
        ans += 2 * tmp;
        closed -= tmp;
        return a[l].cnt + ans + 2 * min (opened, closed);
    }
};

int main () {
    string s;
    cin >> s;
    tree q(&s[0], &s[s.size() - 1]);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        cout << q.ans (l, r) << endl;
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

struct point {
    int cnt, op, cl;
    point (int cn, int o, int c) {
        cnt = cn;
        op = o;
        cl = c;
    }
    point () {
        cnt = 0;
        cl = 0;
        op = 0;
    }
};

class tree {
private:
    int z;
    vector <point> a;
public:
    tree (char *l, char *r) {
        int n = r - l + 1;
        int lg = ceil (log (n) / log (2));
        z = 1<<(lg);
        a.resize (2 * z);
        for (int i = 0; i < n; i++)
            a[i + z] = point (0, l[i] == '(', l[i] == ')');
        z--;
        for (int i = z; i > 0; i--) {
            int F = 2 * i;
            int S = F + 1;
            int tmp = min (a[F].op, a[S].cl);
            a[i].cnt = a[F].cnt + a[S].cnt + 2 * tmp;
            a[i].op = a[F].op + a[S].op - tmp;
            a[i].cl = a[F].cl + a[S].cl - tmp;
        }
    }
    int ans (int l, int r) const {
        if (l == r)
            return 0;
        l += z;
        r += z;
        int ans = 0, opened = 0, closed = 0;
        while (l < r) {
            if (l % 2) {
                ans += a[l].cnt;
                int tmp = min (opened, a[l].cl);
                ans += 2 * tmp;
                opened -= tmp;
                opened += a[l].op;
                l++;
            }
            if (!(r % 2) && l != r) {
                ans += a[r].cnt;
                int tmp = min (closed, a[r].op);
                ans += 2 * tmp;
                closed -= tmp;
                closed += a[r].cl;
                r--;
            }
            if (l != r) {
                l /= 2;
                r /= 2;
            }
        }
        int tmp = min (opened, a[l].cl);
        ans += 2 * tmp;
        opened -= tmp;
        tmp = min (closed, a[l].op);
        ans += 2 * tmp;
        closed -= tmp;
        return a[l].cnt + ans + 2 * min (opened, closed);
    }
};

int main () {
    string s;
    cin >> s;
    tree q(&s[0], &s[s.size() - 1]);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        cout << q.ans (l, r) << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out1.out", "wt", stdout);
#endif
}
//
#define Max 1000000
#define IDX (1<<21)
struct node{
    int o, c, n;
    node(){}
    node(int o, int c, int n): n(n), o(o), c(c) {}
};
node ST[IDX];
int S = 0, E = Max-1;
int fr, to;
//
void insert(int i, char c, int s = S, int e = E, int p = 1){
    if(s == e)
    {
        if(c == '(')
            ST[p] = node(1, 0, 0);
        else
            ST[p] = node(0, 1, 0);
        return;
    }

    int m = (s+e)/2;
    if(i <= m)
        insert(i, c, s, m, 2*p);
    else
        insert(i, c, m+1, e, 2*p+1);

    ST[p].c = ST[2*p].c;
    ST[p].o = ST[2*p+1].o;

    int diff = ST[2*p].o - ST[2*p+1].c;
    if(diff > 0)
        ST[p].o += diff;
    else
        ST[p].c -= diff;

    ST[p].n = e-s+1 - ST[p].c - ST[p].o;
}
node query(int s = S, int e = E, int p = 1){
    if(fr > e || to < s)        return node(0, 0, 0);
    if(fr <= s && e <= to)      return ST[p];

    int m = (s+e)/2;
    if(to <= m)
        return query(s, m, 2*p);
    if(m < fr)
        return query(m+1, e, 2*p+1);

    node q1 = query(s, m, 2*p);
    node q2 = query(m+1, e, 2*p+1);

    node q;
    q.c = q1.c;
    q.o = q2.o;

    int diff = q1.o - q2.c;
    if(diff > 0)
        q.o += diff;
    else
        q.c -= diff;

    q.n = e-s+1 - q.c - q.o;
    return q;
}
//
int main()
{
    read_file(false);

    char c;
    int n = 0;
    while( ( c = getchar() ) != '\n')
        insert(n++, c);

    int m;      scanf("%d", &m);
    while(m--)
    {
        scanf("%d %d", &fr, &to);
        fr--, to--;
        printf("%d\n", to-fr+1 - query().o - query().c );
    }
}


#include <bits/stdc++.h>
using namespace std;
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out1.out", "wt", stdout);
#endif
}
//
#define Max 1000000
#define IDX (1<<21)
struct node{
    int o, c, n;
    node(){}
    node(int o, int c, int n): n(n), o(o), c(c) {}
};
node ST[IDX];
int S = 0, E = Max-1;
int fr, to;
//
void insert(int i, char c, int s = S, int e = E, int p = 1){
    if(s == e)
    {
        if(c == '(')
            ST[p] = node(1, 0, 0);
        else
            ST[p] = node(0, 1, 0);
        return;
    }

    int m = (s+e)/2;
    if(i <= m)
        insert(i, c, s, m, 2*p);
    else
        insert(i, c, m+1, e, 2*p+1);

    ST[p].c = ST[2*p].c;
    ST[p].o = ST[2*p+1].o;

    int diff = ST[2*p].o - ST[2*p+1].c;
    if(diff > 0)        ST[p].o += diff;
    else                ST[p].c -= diff;

    ST[p].n = e-s+1 - ST[p].c - ST[p].o;
    return;

    int t = min(ST[2*p].o, ST[2*p+1].c);
    ST[p].n = ST[2*p].n + ST[2*p+1].n + 2 * t;
    ST[p].o = ST[2*p].o + ST[2*p+1].o - t;
    ST[p].c = ST[2*p].c + ST[2*p+1].c - t;
}
node query(int s = S, int e = E, int p = 1){
    if(fr > e || to < s)        return node(0, 0, 0);
    if(fr <= s && e <= to)      return ST[p];

    int m = (s+e)/2;
    if(to <= m)
        return query(s, m, 2*p);
    if(m < fr)
        return query(m+1, e, 2*p+1);

    node q1 = query(s, m, 2*p);
    node q2 = query(m+1, e, 2*p+1);
    node q;

    int t = min(q1.o, q2.c);
    q.n = q1.n + q2.n + 2 * t;
    q.o = q1.o + q2.o - t;
    q.c = q1.c + q2.c - t;
    return q;
}
//
int main()
{
    read_file(false);

    char c;
    int n = 0;
    while( ( c = getchar() ) != '\n')
        insert(n++, c);

    int m;      scanf("%d", &m);
    while(m--)
    {
        scanf("%d %d", &fr, &to);
        fr--, to--;
        printf("%d\n", query().n);
    }
}


#include <bits/stdc++.h>
using namespace std;
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out1.out", "wt", stdout);
#endif
}
//
#define Max 1000000
#define IDX (1<<21)
struct node{
    int o, c, n;
    node(){}
    node(int o, int c, int n): n(n), o(o), c(c) {}
};
node ST[IDX];
int S = 0, E = Max-1;
int fr, to;
//
void insert(int i, char c, int s = S, int e = E, int p = 1){
    if(s == e)
    {
        if(c == '(')
            ST[p] = node(1, 0, 0);
        else
            ST[p] = node(0, 1, 0);
        return;
    }

    int m = (s+e)/2;
    if(i <= m)
        insert(i, c, s, m, 2*p);
    else
        insert(i, c, m+1, e, 2*p+1);

    ST[p].c = ST[2*p].c;
    ST[p].o = ST[2*p+1].o;

    int diff = ST[2*p].o - ST[2*p+1].c;
    if(diff > 0)
        ST[p].o += diff;
    else
        ST[p].c -= diff;

    //ST[p].n = e-s+1 - ST[p].c - ST[p].o;
    ST[p].n = ST[2*p].n + ST[2*p+1].n + 2 * min(ST[2*p].o , ST[2*p+1].c);
}
node query(int s = S, int e = E, int p = 1){
    if(fr > e || to < s)        return node(0, 0, 0);
    if(fr <= s && e <= to)      return ST[p];

    int m = (s+e)/2;
    if(to <= m)
        return query(s, m, 2*p);
    if(m < fr)
        return query(m+1, e, 2*p+1);

    node q1 = query(s, m, 2*p);
    node q2 = query(m+1, e, 2*p+1);

    node q;
    q.c = q1.c;
    q.o = q2.o;

    int diff = q1.o - q2.c;
    if(diff > 0)
        q.o += diff;
    else
        q.c -= diff;

    //q.n = e-s+1 - q.c - q.o;
    q.n = q1.n + q2.n + 2 * min(q1.o, q2.c);
    return q;
}
//
int main()
{
    read_file(false);

    char c;
    int n = 0;
    while( ( c = getchar() ) != '\n')
        insert(n++, c);

    int m;      scanf("%d", &m);
    while(m--)
    {
        scanf("%d %d", &fr, &to);
        fr--, to--;
        //printf("%d\n", to-fr+1 - query().o - query().c );
        printf("%d\n", query().n);
    }
}


#include <bits/stdc++.h>
using namespace std;
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out1.out", "wt", stdout);
#endif
}
//
#define Max 1000000
#define IDX (1<<21)
struct node{
    int o, c, n;
    node(){}
    node(int o, int c, int n): n(n), o(o), c(c) {}
};
node ST[IDX];
int S = 0, E = Max-1;
int fr, to;
//
void insert(int i, char c, int s = S, int e = E, int p = 1){
    if(s == e)
    {
        if(c == '(')
            ST[p] = node(1, 0, 0);
        else
            ST[p] = node(0, 1, 0);
        return;
    }

    int m = (s+e)/2;
    if(i <= m)
        insert(i, c, s, m, 2*p);
    else
        insert(i, c, m+1, e, 2*p+1);

    int t = min(ST[2*p].o, ST[2*p+1].c);
    ST[p].n = ST[2*p].n + ST[2*p+1].n + 2 * t;
    ST[p].o = ST[2*p].o + ST[2*p+1].o - t;
    ST[p].c = ST[2*p].c + ST[2*p+1].c - t;
}
node query(int s = S, int e = E, int p = 1){
    if(fr > e || to < s)        return node(0, 0, 0);
    if(fr <= s && e <= to)      return ST[p];

    int m = (s+e)/2;
    if(to <= m)
        return query(s, m, 2*p);
    if(m < fr)
        return query(m+1, e, 2*p+1);

    node q1 = query(s, m, 2*p);
    node q2 = query(m+1, e, 2*p+1);
    node q;

    int t = min(q1.o, q2.c);
    q.n = q1.n + q2.n + 2 * t;
    q.o = q1.o + q2.o - t;
    q.c = q1.c + q2.c - t;
    return q;
}
//
int main()
{
    read_file(false);

    char c;
    int n = 0;
    while( ( c = getchar() ) != '\n')
        insert(n++, c);

    int m;      scanf("%d", &m);
    while(m--)
    {
        scanf("%d %d", &fr, &to);
        fr--, to--;
        printf("%d\n", query().n);
    }
}


#include <bits/stdc++.h>
using namespace std;
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out1.out", "wt", stdout);
#endif
}
//
#define Max 1000000
#define IDX (1<<21)
struct node{
    int o, c, n;
    node(){}
    node(int o, int c, int n): n(n), o(o), c(c) {}
};
node ST[IDX];
int S = 0, E = Max-1;
int fr, to;
//
void insert(int i, char c, int s = S, int e = E, int p = 1){
    if(s == e)
    {
        if(c == '(')
            ST[p] = node(1, 0, 0);
        else
            ST[p] = node(0, 1, 0);
        return;
    }

    int m = (s+e)/2;
    if(i <= m)
        insert(i, c, s, m, 2*p);
    else
        insert(i, c, m+1, e, 2*p+1);

    ST[p].c = ST[2*p].c;
    ST[p].o = ST[2*p+1].o;

    int diff = ST[2*p].o - ST[2*p+1].c;
    if(diff > 0)
        ST[p].o += diff;
    else
        ST[p].c -= diff;

    ST[p].n = e-s+1 - ST[p].c - ST[p].o;
}
node query(int s = S, int e = E, int p = 1){
    if(fr > e || to < s)        return node(0, 0, 0);
    if(fr <= s && e <= to)      return ST[p];

    int m = (s+e)/2;
    if(to <= m)
        return query(s, m, 2*p);
    if(m < fr)
        return query(m+1, e, 2*p+1);

    node q1 = query(s, m, 2*p);
    node q2 = query(m+1, e, 2*p+1);

    node q;
    q.c = q1.c;
    q.o = q2.o;

    int diff = q1.o - q2.c;
    if(diff > 0)
        q.o += diff;
    else
        q.c -= diff;

    q.n = e-s+1 - q.c - q.o;
    return q;
}
//
int main()
{
    read_file(false);

    char c;
    int n = 0;
    while( ( c = getchar() ) != '\n')
        insert(n++, c);

    int m;      cin>>m;
    while(m--)
    {
        cin>>fr>>to;
        fr--, to--;
        cout<< to-fr+1 - query().o - query().c <<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;
#define mx 1000010
#define ll long long
char ch[mx];

struct node{

    int open,close,correct;
};
node tree[mx*4];

int tree2[mx*4];

void build(int node,int b,int e)
{
    if(b==e)
    {
        if(ch[b-1]=='(')
            tree[node].open = 1;
        if(ch[b-1]==')')
            tree[node].close = 1;
        return;
    }

    int left = node*2;
    int right = node*2+1;
    int mid  = (b+e)/2;

    build(left,b,mid);
    build(right,mid+1,e);

    int x = tree[left].open;
    int y = tree[right].close;
    int z = min(x,y);

    tree[node].correct = tree[left].correct+tree[right].correct+z;
    tree[node].open = tree[left].open+tree[right].open-z;
    tree[node].close =  tree[left].close+tree[right].close-z;
}

ll query(ll node,ll b,ll e,ll i,ll j)
{
    ll lopen=0LL,lclose=0LL,lcorrect=0LL,ropen=0LL,rclose=0LL,rcorrect=0LL,x=0LL,y=0LL,z=0LL,r3,r4,p;
    if(b>j||e<i)
    {
       // printf("node %lld %lld\n",node,0LL);
        return 0LL;
    }

    if(b>=i&&e<=j)
    {
        x = 1000000+tree[node].correct;
        y = x*1000000+tree[node].open;
        z = y*1000000+tree[node].close;
      //  printf("node %lld %lld\n",node,z);
        return z;
    }

    ll left = node*2;
    ll right = node*2+1;
    ll mid = (b+e)/2;

    ll r1 = query(left,b,mid,i,j);
    r3 = r1;
    //printf("yy node %lld r1 = %lld\n",node,r1);

    lcorrect = (r1/1000000000000)%1000000;
    if(r1>0)
        r1 = r1-1000000000000000000-(lcorrect*1000000000000);
    lopen = (r1/1000000)%1000000;
    if(r1>1000000000000)
        r1  = r1-1000000000000-(lopen*1000000);
    lclose = r1%1000000;

    ll r2 = query(right,mid+1,e,i,j);
    r4 = r2;
    //printf("node %lld r2 = %lld\n",node,r2);
    rcorrect = (r2/1000000000000)%1000000;
    if(r2>0)
        r2 = r2-1000000000000000000-(rcorrect*1000000000000);
    ropen = (r2/1000000)%1000000;
    if(r2>1000000000000)
        r2  = r2-1000000000000-(ropen*1000000);
    rclose = r2%1000000;
        z = min(lopen,rclose);
        p = z;
       x = 1000000+lcorrect+rcorrect+z;
       y = (x*1000000)+lopen+ropen-z;
       z = (y*1000000)+lclose+rclose-z;

    //printf("r1 %lld %lld %lld %lld %lld\n",node,r3,lcorrect,lopen,lclose);
    // printf("r2  %lld %lld %lld %lld %lld\n",node,r4,rcorrect,ropen,rclose);
     //printf("min %lld\n",p);

    return z;
}

int main()
{
    ll n,m,i,j,y;
    ll x,a,b;

    scanf("%s",&ch);

    n = strlen(ch);

    build(1,1,n);

   // for(i=1;i<=30;i++)
 //   {
   //     printf("%d %d %d %d\n",i,tree[i].correct,tree[i].open,tree[i].close);
   // }

   // printf("\n\n");

    scanf("%lld",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%lld %lld",&a,&b);
        x = query(1,1,n,a,b);
        printf("%lld\n",((x/1000000000000)%1000000)*2);
    }

    return 0;
}


#include <bits/stdc++.h>
#define FILL(x,y) memset(x,y,sizeof(x))
#define MX 5000005
#define NND (ND<<1)
#define MID (BEG+END)/2
using namespace std;

int open[MX],clos[MX],cnt[MX];
string s;
class info{
    public:
    int open,clos,cnt;
    info(int X=0,int Y=0,int Z=0):open(X),clos(Y),cnt(Z){
    }
};
void init(int ND,int BEG,int END){
    if(BEG==END){
        s[BEG]=='('?open[ND]++:clos[ND]++;
        return;
    }
    init(NND,BEG,MID);
    init(NND+1,MID+1,END);
    int minc=min(open[NND],clos[NND+1]);
    cnt[ND]=cnt[NND]+cnt[NND+1]+2*minc;
    open[ND]=open[NND]+open[NND+1]-minc;
    clos[ND]=clos[NND]+clos[NND+1]-minc;
}
info q(int ND,int BEG,int END,int L,int R){

    info a1,a2;
    if(END<L or BEG>R){
        return info(0,0,0);
    }
    if(L<=BEG and END<=R){
        return (info(open[ND],clos[ND],cnt[ND]));
    }
    a1=q(NND,BEG,MID,L,R);
    a2=q(NND+1,MID+1,END,L,R);
    int minc=min(a1.open,a2.clos);

    return info(a1.open+a2.open-minc,a1.clos+a2.clos-minc,
                            a1.cnt+a2.cnt+2*minc);
}
int main(){
    cin>>s;
    init(1,0,(int)s.length()-1);
    int m,l,r;cin>>m;
    while(m--){
        cin>>l>>r;
        cout<<q(1,0,s.length()-1,l-1,r-1).cnt<<"\n";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef struct node{
	int ans;
	int l_un;
	int r_un;
}node;
node constructSTUtil(string str,int s,int e,node* st,int i){
	if(s==e){
	st[i].ans=0;
	if(str[s]=='(')
	{
		st[i].l_un=1;st[i].r_un=0;
	}
	else
	{
		st[i].l_un=0;st[i].r_un=1;
	}
	return st[i];
	}
	int mid=(s+e)/2;
	node p1=constructSTUtil(str,s,mid,st,2*i+1);
	node p2=constructSTUtil(str,mid+1,e,st,2*i+2);
	int paired=min(p1.l_un,p2.r_un);
	st[i].ans=p1.ans+p2.ans+2*paired;
	st[i].l_un=p1.l_un-paired+p2.l_un;
	st[i].r_un=p2.r_un-paired+p1.r_un;
	return st[i];
}
node* constructST(string str,int n)
{
	int x=(int)ceil(log2(n));
	int sz=2*(int)pow(2,x)-1;
	node *st=new node[sz];
	constructSTUtil(str,0,n-1,st,0);
	/*for(int i=0;i<sz;i++)
		cout<<i<<" "<<st[i].l_un<<" "<<st[i].ans<<" "<<st[i].r_un<<endl;*/
	return st;
}
node RQ(node* st,int s,int e,int l,int r,int i)
{
	if(s>=l && e<=r)
	{
		return st[i];
	}
	if(s>r || e<l)
	{

node dum;
dum.ans=0;
dum.l_un=0;
dum.r_un=0;
		return dum;
	}
	int mid=(s+e)/2;
	node p1=RQ(st,s,mid,l,r,2*i+1);
	node p2=RQ(st,mid+1,e,l,r,2*i+2);
	node ret;
	int paired=min(p1.l_un,p2.r_un);
	ret.ans=p1.ans+p2.ans+2*paired;
	ret.l_un=p1.l_un-paired+p2.l_un;
	ret.r_un=p2.r_un-paired+p1.r_un;
	return ret;
}
int main()
{
	string str;
	cin>>str;
	int n=str.size();
	node *st=constructST(str,n);
	int q;cin>>q;
	while(q--)
	{
	int l,r;
	cin>>l>>r;
	node an=RQ(st,0,n-1,l-1,r-1,0);
	cout<<an.ans<<endl;
	}
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int n, m, ns;
vector<pair<int, int> > qr;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, v, id;
    Q(int _l, int _r, int _v, int _id) {
        l = _l; r = _r; id = _id; v = _v;
    }
};
vector<Q> qs;
vector<int> bitp;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(
            lower_bound(bitp.begin(), bitp.end(), qr[i].second) - bitp.begin() + 1, 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(lower_bound(
            bitp.begin(), bitp.end(), qr[i].second) - bitp.begin() + 1, -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    ns = n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    qr.push_back(MP(0, 0));
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            qr.push_back(MP(i, last));
            bitp.push_back(last);
        }
    }
    n = qr.size() - 1;
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        int id1 = lower_bound(qr.begin(), qr.end(), MP(l, 0)) - qr.begin();
        int id2 = lower_bound(qr.begin(), qr.end(), MP(r + 1, 0)) - qr.begin() - 1;
        if (id1 > id2 || id1 == n + 1) continue;
        qs.push_back(Q(id1, id2, l, i));
    }
    ns = bitp.size();
    int L = sqrt(ns);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(ns);
    for (int i = 0; i < qs.size(); i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        int h = lower_bound(bitp.begin(), bitp.end(), qs[i].v) - bitp.begin();
        ans[qs[i].id] = 2 * (tot - bit.sum(h));
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int n, m, ns;
vector<pair<int, int> > qr;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, v, id;
    Q(int _l, int _r, int _v, int _id) {
        l = _l; r = _r; id = _id; v = _v;
    }
};
vector<Q> qs;
vector<int> bitp;
unordered_map<int, int> bitm;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(bitm[qr[i].second], 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(bitm[qr[i].second], -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    ns = n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    qr.push_back(MP(0, 0));
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            qr.push_back(MP(i, last));
            bitp.push_back(last);
        }
    }
    n = qr.size() - 1;
    auto comp = [](const pair<int, int> &p1,
            const pair<int, int> &p2) {return p1.first < p2.first;};
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        int id1 = lower_bound(qr.begin(), qr.end(), MP(l, 0), comp) - qr.begin();
        int id2 = lower_bound(qr.begin(), qr.end(), MP(r + 1, 0), comp) - qr.begin() - 1;
        if (id1 > id2 || id1 == n + 1) continue;
        qs.push_back(Q(id1, id2, l, i));
    }
    ns = bitp.size();
    sort(bitp.begin(), bitp.end());
    for (int i = 0; i < bitp.size(); i++) {
        bitm[bitp[i]] = i + 1;
    }
    int L = sqrt(ns);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(ns);
    for (int i = 0; i < qs.size(); i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        int h = lower_bound(bitp.begin(), bitp.end(), qs[i].v) - bitp.begin();
        // Print(qs[i].l, qs[i].r, qs[i].id, bitp[h], qs[i].v);
        ans[qs[i].id] = 2 * (tot - bit.sum(h));
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

int n, m, tot;
char s[1000005];
vector<pair<int, int> > pr;

struct BIT {
    vector<int> s;
    int n;

    BIT(int _n) {
        n = _n;
        s = vector<int>(n + 1);
    }

    void del(int i) {
        for (; i <= n; i += i & (-i))
            s[i]--;
    }

    void add(int i) {
        for (; i <= n; i += i & (-i))
            s[i]++;
    }

    int q(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i))
            sum += s[i];
        return sum;
    }
};

struct Q {
    int l, r, id;
    Q() = default;
    Q(int _l, int _r, int _id) {
        l = _l; r = _r; id = _id;
    }
    bool operator<(const Q &rhs) {
        return l < rhs.l;
    }
};

vector<Q> qs;

int main() {
    scanf("%s", s + 1);
    vector<int> stk;
    for (char *c = s + 1; *c != '\0'; n++, c++) {
        if (*c == '(') stk.push_back(n + 1);
        else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            pr.push_back(MP(n + 1, last));
            tot++;
        }
    }
    sort(pr.begin(), pr.end(), [](const pair<int, int> &p1, const pair<int, int> &p2){
        return p1.second < p2.second;
    });
    BIT bit(n);
    for (auto p : pr)
        bit.add(p.first);
    scanf("%d", &m);
    vector<int> ans(m);
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        qs.push_back(Q(l, r, i));
    }
    sort(qs.begin(), qs.end());
    int p2 = 0, t = pr.size();
    for (int i = 0; i < m; i++) {
        for (; p2 < t && pr[p2].second < qs[i].l; p2++) {
            bit.del(pr[p2].first);
        }
        ans[qs[i].id] = 2 * (bit.q(qs[i].r) - bit.q(qs[i].l - 1));
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int n, m, ns;
vector<pair<int, int> > qr;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, v, id;
    Q(int _l, int _r, int _v, int _id) {
        l = _l; r = _r; id = _id; v = _v;
    }
};
vector<Q> qs;
vector<int> bitp;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(
            lower_bound(bitp.begin(), bitp.end(), qr[i].second) - bitp.begin() + 1, 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(lower_bound(bitp.begin(), bitp.end(), qr[i].second) - bitp.begin() + 1, -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    ns = n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    qr.push_back(MP(0, 0));
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            qr.push_back(MP(i, last));
            bitp.push_back(last);
        }
    }
    n = qr.size() - 1;
    auto comp = [](const pair<int, int> &p1,
            const pair<int, int> &p2) {return p1.first < p2.first;};
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        int id1 = lower_bound(qr.begin(), qr.end(), MP(l, 0), comp) - qr.begin();
        int id2 = lower_bound(qr.begin(), qr.end(), MP(r + 1, 0), comp) - qr.begin() - 1;
        if (id1 > id2 || id1 == n + 1) continue;
        qs.push_back(Q(id1, id2, l, i));
    }
    ns = bitp.size();
    sort(bitp.begin(), bitp.end());
    int L = sqrt(ns);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(ns);
    for (int i = 0; i < qs.size(); i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        int h = lower_bound(bitp.begin(), bitp.end(), qs[i].v) - bitp.begin();
        // Print(qs[i].l, qs[i].r, qs[i].id, bitp[h], qs[i].v);
        ans[qs[i].id] = 2 * (tot - bit.sum(h));
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int n, m, ns;
vector<pair<int, int> > qr;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, v, id;
    Q(int _l, int _r, int _v, int _id) {
        l = _l; r = _r; id = _id; v = _v;
    }
};
vector<Q> qs;
vector<int> bitp;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(
            lower_bound(bitp.begin(), bitp.end(), qr[i].second) - bitp.begin() + 1, 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(lower_bound(bitp.begin(), bitp.end(), qr[i].second) - bitp.begin() + 1, -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    ns = n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    qr.push_back(MP(0, 0));
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            qr.push_back(MP(i, last));
            bitp.push_back(last);
        }
    }
    n = qr.size() - 1;
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        int id1 = lower_bound(qr.begin(), qr.end(), MP(l, 0)) - qr.begin();
        int id2 = lower_bound(qr.begin(), qr.end(), MP(r + 1, 0)) - qr.begin() - 1;
        if (id1 > id2 || id1 == n + 1) continue;
        qs.push_back(Q(id1, id2, l, i));
    }
    ns = bitp.size();
    sort(bitp.begin(), bitp.end());
    int L = sqrt(ns);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(ns);
    for (int i = 0; i < qs.size(); i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        int h = lower_bound(bitp.begin(), bitp.end(), qs[i].v) - bitp.begin();
        // Print(qs[i].l, qs[i].r, qs[i].id, bitp[h], qs[i].v);
        ans[qs[i].id] = 2 * (tot - bit.sum(h));
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int n, m, ns;
vector<pair<int, int> > qr;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, id;
    Q(int _l, int _r, int _id) {
        l = _l; r = _r; id = _id;
    }
};
vector<Q> qs;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(qr[i].second, 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(qr[i].second, -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    ns = n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    qr.push_back(MP(0, 0));
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            qr.push_back(MP(i, last));
        }
    }
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        qs.push_back(Q(l, r, i));
    }
    n = qr.size() - 1;
    int L = sqrt(n);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(ns);
    for (int i = 0; i < m; i++) {
        int id1 = lower_bound(qr.begin(), qr.end(), MP(qs[i].l, 0)) - qr.begin();
        int id2 = lower_bound(qr.begin(), qr.end(), MP(qs[i].r + 1, 0)) - qr.begin() - 1;
        if (id1 > id2 || id1 == n + 1)
            ans[qs[i].id] = 0;
        else {
            while (cl < id1) {
                remove(cl++, bit);
            }
            while (cl > id1) {
                add(--cl, bit);
            }
            while (cr < id2) {
                add(++cr, bit);
            }
            while (cr > id2) {
                remove(cr--, bit);
            }
            ans[qs[i].id] = 2 * (tot - bit.sum(qs[i].l - 1));
        }
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int n, m, ns;
vector<pair<int, int> > qr;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, v, id;
    Q(int _l, int _r, int _v, int _id) {
        l = _l; r = _r; id = _id; v = _v;
    }
};
vector<Q> qs;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(qr[i].second, 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n) {
        bit.add(qr[i].second, -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    ns = n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    qr.push_back(MP(0, 0));
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            qr.push_back(MP(i, last));
        }
    }
    n = qr.size() - 1;
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        int id1 = lower_bound(qr.begin(), qr.end(), MP(l, 0)) - qr.begin();
        int id2 = lower_bound(qr.begin(), qr.end(), MP(r + 1, 0)) - qr.begin() - 1;
        if (id1 > id2 || id1 == n + 1) continue;
        qs.push_back(Q(id1, id2, l, i));
    }
    int L = sqrt(n);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(ns);
    for (int i = 0; i < qs.size(); i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        ans[qs[i].id] = 2 * (tot - bit.sum(qs[i].v - 1));
    }
    for (int val : ans)
        printf("%d\n", val);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int pt[1000005];
int n, m;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, id;
    Q(int _l, int _r, int _id) {
        l = _l; r = _r; id = _id;
    }
};
vector<Q> qs;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n && pt[i] > 0) {
        bit.add(pt[i], 1);
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n && pt[i] > 0) {
        bit.add(pt[i], -1);
    }
}

int main() {
    scanf("%s", s + 1);
    n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            pt[i] = last;
        }
    }
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        qs.push_back(Q(l, r, i));
    }
    int L = sqrt(n);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(n);
    for (int i = 0; i < m; i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        ans[qs[i].id] = bit.sum(qs[i].r) - bit.sum(qs[i].l - 1);
        // Print(i, qs[i].id, qs[i].l, qs[i].r, ans[qs[i].id]);
    }
    for (int i = 0; i < m; i++)
        printf("%d\n", ans[i] * 2);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void Print()
{
    cout << endl;
}

template<typename T1, typename ... T>
void Print(const T1 &t1, const T& ... t)
{
    cout << t1 << " ";
    Print(t...);
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" <<p.first << ", " << p.second << ")";
    return os;
}

#define MP(a, b) (make_pair((a), (b)))
#define MT(args...) (make_tuple(args))

LL gcd(LL a, LL b) {
    if (b) {
        LL r = a % b;
        a = b, b = r;
    }
    return a;
}

tuple<LL, LL, LL> extend_gcd(LL a, LL b) {
    if (b == 0)
        return make_tuple(a, 1, 0);
    else {
        LL g, nx, ny;
        std::tie(g, nx, ny) = extend_gcd(b, a % b);
        return make_tuple(g, ny, nx - (a / b) * ny);
    }
}

LL fastpow(LL a, LL e, LL mod) {
    if (e == 0) return 1;
    if (e == 1) return a % mod;
    LL t = fastpow(a, e / 2, mod);
    t = t * t % mod;
    if (e & 1)
        return t * a % mod;
    else
        return t % mod;
}

const double PI = 3.14159265358979323846;
const int MOD = (int)1e9 + 7;

char s[1000005];
int pt[1000005];
int n, m;

struct BIT {
    int n;
    vector<int> s;

    BIT(int _n) {
        n = _n; s = vector<int>(n + 1);
    }

    void add(int i, int v) {
        for (; i <= n; i += i & (-i))
            s[i] += v;
    }

    int sum(int i) {
        int sum = 0;
        for (; i > 0; i -= i & (-i)) {
            sum += s[i];
        }
        return sum;
    }
};

struct Q {
    int l, r, id;
    Q(int _l, int _r, int _id) {
        l = _l; r = _r; id = _id;
    }
};
vector<Q> qs;
int tot = 0;

void add(int i, BIT &bit) {
    if (i > 0 && i <= n && pt[i] > 0) {
        bit.add(pt[i], 1);
        tot++;
    }
}

void remove(int i, BIT &bit) {
    if (i > 0 && i <= n && pt[i] > 0) {
        bit.add(pt[i], -1);
        tot--;
    }
}

int main() {
    scanf("%s", s + 1);
    n = strlen(s + 1);
    scanf("%d", &m);
    vector<int> stk;
    for (int i = 1; i <= n; i++) {
        int f = (s[i] == '(') ? 0 : 1;
        if (f == 0) {
            stk.push_back(i);
        }else {
            if (stk.empty()) continue;
            int last = stk.back(); stk.pop_back();
            pt[i] = last;
        }
    }
    for (int i = 0; i < m; i++) {
        int l, r; scanf("%d %d", &l, &r);
        qs.push_back(Q(l, r, i));
    }
    int L = sqrt(n);
    sort(qs.begin(), qs.end(),
        [&](const Q &q1, const Q &q2) {
            if (q1.l / L == q2.l / L) return q1.r > q2.r;
            return q1.l / L < q2.l / L;
        });
    int cl = 0, cr = 0; vector<int> ans(m);
    BIT bit(n);
    for (int i = 0; i < m; i++) {
        while (cl < qs[i].l) {
            remove(cl++, bit);
        }
        while (cl > qs[i].l) {
            add(--cl, bit);
        }
        while (cr < qs[i].r) {
            add(++cr, bit);
        }
        while (cr > qs[i].r) {
            remove(cr--, bit);
        }
        ans[qs[i].id] = tot - bit.sum(qs[i].l - 1);
        // Print(i, qs[i].id, qs[i].l, qs[i].r, ans[qs[i].id]);
    }
    for (int i = 0; i < m; i++)
        printf("%d\n", ans[i] * 2);
}


#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
int const N = 1000020;
char s[N];
int q , t[N*4][2] , a[N*4];
int n[N*4][2];
void build(int node , int start , int end)
{
	if(start == end){
		if(s[start-1] == '(')
			t[node][0] = 1;
		else
			t[node][1] = -1;
	}
	else
	{
		int mid = (start + end)/2;
		build(node * 2 , start , mid);
		build(node*2+1,mid+1,end);
		a[node] = a[node*2]+a[node*2+1];
		if(t[node*2][0] > 0 && t[node*2+1][1] < 0)
			a[node] += min(t[node*2][0] , -t[node*2+1][1]);
		t[node][0] = t[node*2][0] - min(t[node*2][0] , -t[node*2+1][1]) + t[node*2+1][0];
		t[node][1] = t[node*2][1] + t[node*2+1][1] + min(t[node*2][0] , -t[node*2+1][1]);
	}
}
int get(int node , int start , int end , int l , int r)
{
	if(start > r || end < l){n[node][0] = 0;n[node][1] = 0;return 0;}
	if(start >= l && end <= r){n[node][0] = t[node][0] ;n[node][1] = t[node][1] ;return a[node];}
	int mid = (start + end)/2;
	int re = get(node*2,start,mid,l,r) + get(node*2+1,mid+1,end,l,r);
	if(n[node*2][0] > 0 && n[node*2+1][1] < 0)
		re += min(n[node*2][0] , -n[node*2+1][1]);
	n[node][0] = n[node*2][0] - min(n[node*2][0] , -n[node*2+1][1]) + n[node*2+1][0];
	n[node][1] = n[node*2][1] + n[node*2+1][1] + min(n[node*2][0] , -n[node*2+1][1]);
	return re ;
}
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r" , stdin);
	#endif
	scanf("%s%d",s,&q);
	int len = strlen(s);
	build(1,1,len);
	while(q--)
	{
		int l ,r ;
		scanf("%d%d",&l,&r);
	//	memset(n,0,sizeof n);
		printf("%d\n", get(1,1,len,l,r)*2);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
int const N = 1000020;
char s[N];
int q , t[N*4][2] , a[N*4];
int n[N*4][2];
void build(int node , int start , int end)
{
	if(start == end){
		if(s[start-1] == '(')
			t[node][0] = 1;
		else
			t[node][1] = -1;
	}
	else
	{
		int mid = (start + end)/2;
		build(node * 2 , start , mid);
		build(node*2+1,mid+1,end);
		a[node] = a[node*2]+a[node*2+1];
		if(t[node*2][0] > 0 && t[node*2+1][1] < 0)
			a[node] += min(t[node*2][0] , -t[node*2+1][1]);
		t[node][0] = t[node*2][0] - min(t[node*2][0] , -t[node*2+1][1]) + t[node*2+1][0];
		t[node][1] = t[node*2][1] + t[node*2+1][1] + min(t[node*2][0] , -t[node*2+1][1]);
	}
}
int get(int node , int start , int end , int l , int r)
{
	if(start > r || end < l){return 0;}
	if(start >= l && end <= r){n[node][0] = t[node][0] ;n[node][1] = t[node][1] ;return a[node];}
	int mid = (start + end)/2;
	int re = get(node*2,start,mid,l,r) + get(node*2+1,mid+1,end,l,r);
	if(n[node*2][0] > 0 && n[node*2+1][1] < 0)
		re += min(n[node*2][0] , -n[node*2+1][1]);
	n[node][0] = n[node*2][0] - min(n[node*2][0] , -n[node*2+1][1]) + n[node*2+1][0];
	n[node][1] = n[node*2][1] + n[node*2+1][1] + min(n[node*2][0] , -n[node*2+1][1]);
	return re ;
}
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r" , stdin);
	#endif
	scanf("%s%d",s,&q);
	int len = strlen(s);
	build(1,1,len);
	while(q--)
	{
		int l ,r ;
		scanf("%d%d",&l,&r);
		memset(n,0,sizeof n);
		printf("%d\n", get(1,1,len,l,r)*2);
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct node { int o_l=0,o_r=0,full=0; node(){} };;
node st[5000000];
string s;
node combine(node l,node r)
{
    node t;
    int x=min(l.o_r,r.o_l);
    t.full=l.full+r.full+x;
    t.o_l=l.o_l+r.o_l-x;
    t.o_r=l.o_r+r.o_r-x;
    return t;
}
node build(int L,int R,int p)
{
    if(L==R)
    {
        node t;
        if(s[L-1]=='(')
            t.o_l=0,t.o_r=1,t.full=0;
        if(s[L-1]==')')
            t.o_l=1,t.o_r=0,t.full=0;
        return st[p]=t;
    }
    return st[p]=combine(build(L,(L+R)/2,p*2),build((L+R)/2+1,R,p*2+1));
}
node query(int L,int R,int p,int l,int r)
{
    if(L>=l&&R<=r)
        return st[p];
    if(l>R||r<L)
        return node();
    return combine(query(L,(L+R)/2,p*2,l,r),query((L+R)/2+1,R,p*2+1,l,r));
}
int main()
{
    int n,l,r;
    node t;
    cin>>s;
    cin>>n;
    t=build(1,s.length(),1);
    while(n--)
    {
        cin>>l>>r;
        cout<<query(1,s.length(),1,l,r).full*2<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5 ;
const double eps = 1e-9 ;
const int MAX_N = 1e6 + 5 ;
const int inf = 2e9 ;
const long long Inf = (long long)1e18 ;
const long long M = (long long)1e9+7 ;
#define     ll      long long
#define     ull     unsigned long long
#define        ignore    continue
#define        exit    break
int Int() {
    int x;
    scanf("%d",&x);
    return x;
}
ll Long() {
    ll x;
    scanf("%lld",&x);
    return x;
}
void Char(char* ch) {
    scanf("%s",ch);
}
template<typename t>inline t abs(t a) { if(a>=0) return a; return -a;}
template<typename t>inline t gcd(t a , t b) {return !b ? a : gcd(b , a % b);}
template<typename t>inline t lcm(t a , t b) {return a * ( b /gcd(a , b));}
template<typename T>inline T modpow(T b, T p, T Mod) {
    T res  = 1;
    while(p > 0) {
        if(p&1) {
            res *= b ;
            res %= Mod ;
        }
        b *= b;
        b %= Mod;
        p >>= 1;
    }
    return res ;
}

template<typename T> inline T ModInv(T b, T Mod) {return modpow(b, Mod - 2, Mod );}

template<typename T> inline T pwr(T b, T p) {
    T res  = 1;
    while(p > 0) {
        if(p&1) {
            res *= b ;
        }
        b *= b;
        p >>= 1;
    }
    return res ;
}
int e1 , e2 , d1 ;
template < typename T >inline void extgcd(T a , T b){
    if(!b) {e1 = 1 , e2 = 0 , d1 = a ; return ;}
    extgcd(b , a % b) ;
    T x1 = e2 ;
    T y1 = e1 - (a / b) * e2 ;
    e1 = x1 ;
    e2 = y1 ;
}

/*primes in range 1 - n
1 - 100(1e2) -> 25 pimes
1 - 1000(1e3) -> 168 primes
1 - 10000(1e4) -> 1229 primes
1 - 100000(1e5) -> 9592 primes
1 - 1000000(1e6) -> 78498 primes
1 - 10000000(1e7) -> 664579 primes
large primes ->
104729 1299709 15485863 179424673 2147483647 32416190071 112272535095293 48112959837082048697
*/
/*
PRIMES vs Range
100(1e2) primes -> 541 (5e2 + 41)
1000(1e3) primes -> 7919(7e3 + 9e2 + 19)
10000(1e4) primes -> 104729(1e5 + 4e3 + 7e2 + 29)
100000(1e5) primes -> 1299709(1e6 + 2e5 + 9e4 + 9e3 + 7e2 + 9)
1000000(1e6) primes -> 15485863(1e7 + 5e6 + 4e5 + 8e4 + 5e3 + 8e2 + 63)
*/
/*
std::vector<int> primes;
bitset < MAX_N > bs;
ll sieve_size = MAX_N ;

void sieve(ll n){
    bs.set() ;
    int cnt = 0 ;
    bs[0] = bs[1] = 0 ;
    for(ll i = 2 ; i <= n ; i++)if(bs[i]){
        primes.push_back((int)i);
        for(ll j = i * i ; j <= n ; j += i) bs[j] = 0;
    }
}

// LINEAR SIEVE -> O(N) COMPLEXITY

bool is_composite[MAX_N] ;
std::vector< int > pm;

void linear_sieve(){
    for(int i = 2 ; i < MAX_N ; i++){
        if(!is_composite[i])pm.pb(i) ;
        for(int j = 0 ; j < (int)pm.size() and i * pm[j] < MAX_N ; j++){
            is_composite[i * pm[j]] = 1 ;
            if(i % pm[j] == 0)break ;
        }
    }
}

bool isprime(ll n){
    if(n <= sieve_size)return bs[n] ;
    for(int i = 0 ; i < (int)primes.size() ; i++){
        if(n % primes[i] == 0)return false ;
    }
    return true ;
}

int numDiffPf[MAX_N] ;

void DiffPF(){
    for(int i = 2 ; i < MAX_N ; i++){
        if(numDiffPf[i] == 0){
            for(int j = i ; j < MAX_N ; j += i)numDiffPf[j]++;
        }
    }
}
//Minimum Prime Factor

std::vector< int > factor;
void minFactor(ll n){
    factor.assign((int)n + 1 , 0) ;
    for(ll i = 2 ; i <= n ; i++){
        if(factor[i] != 0) continue ;
        for(ll j = i * i ; j <= n ; j += i){
            if(factor[j] == 0)factor[j] = i ;
        }
    }
}

int Phi[MAX_N] ;

void EulerPHI(){
    for(int i = 1 ; i < MAX_N ; i++)Phi[i] = i ;
        for(int i = 2 ; i < MAX_N ; i++)
            if(Phi[i] == i)
                for(int j = i ; j < MAX_N ; j += i)
                    Phi[j] = (Phi[j]/i) * (i - 1) ;
}

int F(int x){
    return 0 ;
}
pair < int , int > floydCycle(int x0){
    int tor = F(x0) , hare = F(F(x0)) ;
    while(tor != hare){tor = F(tor) , hare = F(F(hare));}
    int mu = 0 ; hare = x0 ;
    while(tor != hare){tor = F(tor) , hare = F(hare); mu++ ;}
    int lambda = 1 ; hare = F(tor) ;
    while(tor != hare){hare = F(hare) ; lambda++;}
    return {mu , lambda} ;
}
*/
template <typename T>inline vector< T > Unique(vector< T > v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()),v.end());
    return v;
}
#define rep(i, begin, end) for (__typeof(end) i = (begin) ; i != (end) + 1 - 2 * ((begin) > (end)) ; i += 1 - 2 * ((begin) > (end)))
///error///
#define error(args...) {vector<string>_v=split(#args,',');err(_v.begin(),args);cout<<endl;}
vector<string> split(const string &s,char c) {
    vector<string>v;
    stringstream ss(s);
    string x;
    while(getline(ss,x,c))
        v.emplace_back(x);
    return move(v);
}

void err(vector<string>::iterator it) {}
template<typename T,typename... Args>
void err(vector<string>::iterator it,T a,Args...args) {
    cout<<it->substr((*it)[0]==' ',it->length())<< " = " << a << " ";
    err(++it,args...);
}
///This DEBUGGER-tool need c++11///
#define     Int                 Int()
#define     Long                Long()
#define     pii                 pair<int,int>
#define     ff                  first
#define     ss                  second
#define     pb                  push_back
#define     eb                  emplace_back
#define     all(x)              x.begin(),x.end()
#define     mem(a)              memset(a,0,sizeof a)
#define     memn(a)             memset(a,-1,sizeof a)

char s[N] ;
struct bracket{
    int t , o ,c ;
    bracket(){
        t = o = c = 0 ;
    }
    bracket(int u , int v , int w){
        t = u , o = v , c = w ;
    }
}tree[N << 2] ;

void build(int i , int b , int e){
    if(b == e){
        if(s[b] == '(')tree[i].o = 1 ;
        else tree[i].c = 1 ;
        return ;
    }
    int mid = (b + e) >> 1 ;
    build(i << 1 , b , mid) ;
    build(i << 1 | 1 , mid + 1 , e) ;
    int tmp = min(tree[i << 1].o , tree[i << 1 | 1].c) ;
    tree[i].t = tree[i << 1].t + tree[i << 1 | 1].t + tmp ;
    tree[i].o = tree[i << 1].o + tree[i << 1 | 1].o - tmp ;
    tree[i].c = tree[i << 1].c + tree[i << 1 | 1].c - tmp ;
}

bracket ask(int i , int b , int e , int l , int r){
    if(b > r or e < l)return {0 ,0 ,0} ;
    if(l <= b and e <= r){
        return tree[i] ;
    }
    int mid = (b + e) >> 1 ;
    bracket u = ask(i << 1 , b , mid , l , r) ;
    bracket v = ask(i << 1 | 1 , mid + 1 , e , l , r) ;
    int tmp = min(u.o , v.c) ;
    bracket f ;
    f.t = u.t + v.t + tmp ;
    f.o = u.o + v.o - tmp ;
    f.c = u.c + v.c - tmp ;
    return f ;
}

int main() {
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t = 1 , tc = 0 ;
    while(t--) {
        scanf("%s", s + 1) ;
        int n = strlen(s + 1) ;
        build(1 , 1 , n) ;
        int q = Int ;
        while(q--){
            int l = Int , r = Int ;
            bracket res = ask(1 , 1 , n , l , r) ;
            printf("%d\n",res.t << 1);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 6;
vector<int> tree[N << 2];
char ch[N];
int couple[N];
void match() {
    stack<int>st;
    for (int i = 0; ch[i]; i++) {
        if (ch[i] == '(')
            st.push(i + 1);
        else {
            if (st.size() > 0) {
                couple[i + 1] = st.top();
                couple[st.top()] = i + 1;
                st.pop();
            }
        }
    }
}
void build(int i, int l, int r) {
    if (l == r) {
        tree[i] .push_back(couple[l]);
        return;
    }
    int mid = (l + r) >> 1;
    build(i * 2, l, mid);
    build(i * 2 + 1, mid + 1, r);
    merge(tree[i<<1].begin(),tree[i<<1].end(),tree[i<<1|1].begin(),tree[i<<1|1].end(),back_inserter(tree[i]));

}
int query(int i, int l, int r, int x, int y) {
    if (x > r or l > y) return 0;
    if (x <= l and r <= y) {
        int u = lower_bound(tree[i].begin(),tree[i].end(),x)-tree[i].begin();
        int v = tree[i].size()-(upper_bound(tree[i].begin(),tree[i].end(),y)-tree[i].begin());
        return tree[i].size()-(u+v);
    }
    int mid = (l + r) >> 1;
    return query(i * 2, l, mid, x, y)+query(i * 2 + 1, mid + 1, r, x, y);
}
int main() {
    scanf("%s", ch);
    int t = strlen(ch);
    match();
    build(1, 1, t);
    int q;
    cin >> q;
    while (q--) {
        int l, r;
        scanf("%d%d", &l, &r);
        int p = query(1, 1, t, l, r);
        printf("%d\n", p);
    }
}


#include<bits/stdc++.h>
using namespace std;
struct node
{
    int open;
    int close;
    int sol;
};
string s;
int n;
vector<node> seg(4000001);
void build(int start, int end, int root = 1)
{
    if(start == end)
    {
        node temp;
        if(s[start] == ')')
        {
            temp.close = 1;
            temp.open = 0;
        }
        else
        {
            temp.close = 0;
            temp.open = 1;
        }
        temp.sol = 0;
        seg[root] = temp;
        return;
    }
    int mid = (start+end)/2;
    build(start, mid, root*2);
    build(mid+1, end, root*2+1);
    int temp = min(seg[root*2].open, seg[root*2+1].close);
    seg[root].sol = seg[root*2].sol + seg[root*2+1].sol + 2*temp;
    seg[root].open = seg[root*2].open + seg[root*2+1].open - temp;
    seg[root].close = seg[root*2].close + seg[root*2+1].close - temp;
}

node q(int l, int r, int ql, int qr, int root = 1)
{
    if(qr < l or ql > r)
    {
        node temp;
        temp.close = 0;
        temp.open = 0;
        temp.sol = 0;
        return temp;
    }
    if(l >= ql and r <= qr)
    {
        return seg[root];
    }
    int mid = (l+r)/2;
    node left = q(l, mid, ql, qr, root*2);
    node right = q(mid+1, r, ql, qr, root*2+1);
    node temp;
    int t = min(left.open, right.close);
    temp.sol = left.sol + right.sol + 2*t;
    temp.open = left.open + right.open - t;
    temp.close = left.close + right.close - t;
    return temp;
}

int main()
{
    cin >> s;
    n = s.size();
    build(0, n-1);
    int m;
    cin >> m;
    while(m--)
    {
        int l, r;
        cin >> l >> r;
        l--;r--;
        node temp = q(0, n-1, l, r);
        cout << temp.sol << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
// #include <bits/stdtr1c++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;

/// Typedef
typedef long long           ll;
typedef unsigned long       ul;
typedef unsigned long long  ull;
typedef vector<int>         vi;
typedef vector<vi>          vvi;
typedef vector<ll>          vll;
typedef pair<int,int>       pii;
typedef pair<ll,ll>         pll;

#define pb                  push_back
#define ppb                 pop_back
#define MP                  make_pair
#define ff                  first
#define ss                  second
#define sf                  scanf
#define pf                  printf
#define loop(i, y)          for(int i=0; i<int(y); i++)
#define FOR(i, x, y)        for(int i=int(x); i<int(y); i++)
#define ROF(i, x, y)        for(int i=int(x); i>=int(y); i--)
#define all(c)              c.begin(), c.end()
#define sz(c)               int(c.size())
#define clr(x, y)           memset(x, y, sizeof(x))
#define si(x)               scanf("%d", &x)
#define sii(x, y)           scanf("%d %d", &x, &y)
#define siii(x, y, z)       scanf("%d %d %d", &x, &y, &z)
#define sl(x)               scanf("%lld", &x)
#define sll(x, y)           scanf("%lld %lld", &x, &y)
#define slll(x, y, z)       scanf("%lld %lld %lld", &x, &y, &z)
#define FastIO              ios_base::sync_with_stdio(false)
///START
/// Constants
#define MAX 1000005
#define MOD 1000000009
#define base 1000000007
#define eps 1e-9
int tree[4*MAX],Open_B[4*MAX],Close_B[4*MAX];
string str;
typedef pair<int,int> pii;
typedef pair<int,pair<int,int> > info;
void build(int id,int st,int ed){
    if(st==ed){
        if(str[st]=='(') Open_B[id]=1;
        else             Close_B[id]=1;
        return;
    }
    int mid = (st+ed)>>1;
    int left = id<<1;
    int right = left|1;
    build(left,st,mid);
    build(right,mid+1,ed);
    int len     = min(Open_B[left],Close_B[right]);    //length of the correct bracket sequence
    tree[id]    = tree[left] + tree[right] + 2*len;      //add the the length
    Open_B[id]  = Open_B[left] + Open_B[right] - len;  //eliminate the  opening bracket belong to correct bracket sequence
    Close_B[id] = Close_B[left] + Close_B[right] - len;//eliminate the  closing bracket belong to correct bracket sequence
}
info query(int id,int st,int ed,int l,int r){
    if(st>ed || st>r || ed<l)   return info(0,pii(0,0));
    if(st>=l && ed<=r) return info(tree[id],pii(Open_B[id],Close_B[id]));
    int mid = (st+ed)>>1;
    int left = id<<1;
    int right = left|1;
    if(r<=mid) return query(left,st,mid,l,r);
    if(l>mid)  return query(right,mid+1,ed,l,r);
    info p,q;
    p = query(left,st,mid,l,mid);
    q = query(right,mid+1,ed,mid+1,r);
    int len = min(p.ss.ff , q.ss.ss) , t,o,c;
    t    = p.ff + q.ff + 2*len;      //add the the length
    o    = p.ss.ff + q.ss.ff - len;  //eliminate the  opening bracket belong to correct bracket sequence
    c    = p.ss.ss + q.ss.ss - len;  //eliminate the  closing bracket belong to correct bracket sequence
    return info(t,pii(o,c));
}
int main(){
    #ifdef VAMP
        clock_t tStart = clock();
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
    string str1;
    str1="0";
    cin>>str;
    str1+=str;
    str=str1;
    build(1,1,sz(str));
    int q;
    si(q);
    while(q--){
        int x,y;
        sii(x,y);
        info val;
        val=query(1,1,sz(str),x,y);
        int ans = val.ff;
        printf("%d\n",ans);
    }
    #ifdef VAMP
        printf("\n>>Runtime: %.10fs\n", (double) (clock() - tStart) / CLOCKS_PER_SEC);
    #endif
    return 0;
}


//Segment tree approach to Range-sum and update query problem.
//arr and tree are 1-indexed

#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define lol         1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define SIZE		1000005
using namespace std;

void MOD(ll &x)
{
	if (x >= lol) x -= lol;
	if (x < 0) x += lol;
}

typedef struct segtree
{
    int maxcorrseq;
    int opennum;
    int closenum;
}segtree;

char arr[SIZE+5];
segtree tree[4*SIZE+5];
int n, q;

void build(int node, int start, int end)
{
	if(start>end) return;

	if(start==end)
	{
	    tree[node].maxcorrseq = 0;
	    tree[node].opennum = (arr[start]=='(')?1:0;
	    tree[node].closenum = 1 - tree[node].opennum;
	}

	else
	{
		int mid = (start+end)/2;
		build(2*node, start, mid);
		build(2*node+1, mid+1, end);

        int temp = min(tree[2*node].opennum, tree[2*node+1].closenum);

		tree[node].maxcorrseq = tree[2*node].maxcorrseq + tree[2*node+1].maxcorrseq + 2*temp;
		tree[node].opennum = tree[2*node].opennum + tree[2*node+1].opennum - temp;
		tree[node].closenum = tree[2*node].closenum + tree[2*node+1].closenum - temp;

	}
}

segtree query(int node, int start, int end, int l, int r)
{
    segtree ans;
    ans.maxcorrseq = 0;
    ans.opennum = 0;
    ans.closenum = 0;
	if(r<start || end<l) return ans;
	if(l<=start && end<=r) return tree[node];

	int mid = (start+end)/2;
	segtree p1 = query(2*node, start, mid, l, r);
	segtree p2 = query(2*node+1, mid+1, end, l, r);

	int temp = min(p1.opennum, p2.closenum);

    ans.maxcorrseq = p1.maxcorrseq + p2.maxcorrseq + 2*temp;
    ans.opennum = p1.opennum + p2.opennum - temp;
    ans.closenum = p1.closenum + p2.closenum - temp;

	return ans;
}

void solve()
{
    string s;
    cin>>s;
    n = s.length();
	rep(i,1,n+1) arr[i] = s[i-1];
	build(1,1,n);
	cin>>q;
	rep(i,1,q+1)
	{
		int x, y;
		cin>>x>>y;
		segtree ans = query(1,1,n,x,y);
		cout<<ans.maxcorrseq<<endl;
	}

}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
//	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


//Segment tree approach to Range-sum and update query problem.
//arr and tree are 1-indexed

#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define lol         1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define SIZE		1000005
using namespace std;

void MOD(ll &x)
{
	if (x >= lol) x -= lol;
	if (x < 0) x += lol;
}

typedef struct segtree
{
    int maxcorrseq;
    int opennum;
    int closenum;
}segtree;

char arr[SIZE+5];
segtree tree[4*SIZE+5];
int n, q;

void build(int node, int start, int end)
{
	if(start>end) return;

	if(start==end)
	{
	    tree[node].maxcorrseq = 0;
	    tree[node].opennum = (arr[start]=='(')?1:0;
	    tree[node].closenum = 1 - tree[node].opennum;
	}

	else
	{
		int mid = (start+end)/2;
		build(2*node, start, mid);
		build(2*node+1, mid+1, end);

        int temp = min(tree[2*node].opennum, tree[2*node+1].closenum);

		tree[node].maxcorrseq = tree[2*node].maxcorrseq + tree[2*node+1].maxcorrseq + temp;
		tree[node].opennum = tree[2*node].opennum + tree[2*node+1].opennum - temp;
		tree[node].closenum = tree[2*node].closenum + tree[2*node+1].closenum - temp;

	}
}

segtree query(int node, int start, int end, int l, int r)
{
    segtree ans;
    ans.maxcorrseq = 0;
    ans.opennum = 0;
    ans.closenum = 0;
	if(r<start || end<l) return ans;
	if(l<=start && end<=r) return tree[node];

	int mid = (start+end)/2;
	segtree p1 = query(2*node, start, mid, l, r);
	segtree p2 = query(2*node+1, mid+1, end, l, r);

	int temp = min(p1.opennum, p2.closenum);

    ans.maxcorrseq = p1.maxcorrseq + p2.maxcorrseq + temp;
    ans.opennum = p1.opennum + p2.opennum - temp;
    ans.closenum = p1.closenum + p2.closenum - temp;

	return ans;
}

void solve()
{
    string s;
    cin>>s;
    n = s.length();
	rep(i,1,n+1) arr[i] = s[i-1];
	build(1,1,n);
	cin>>q;
	rep(i,1,q+1)
	{
		int x, y;
		cin>>x>>y;
		segtree ans = query(1,1,n,x,y);
		cout<<2*ans.maxcorrseq<<endl;
	}

}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
//	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxm=1e6+5;
struct Node{
    int cnt;//已经匹配的合法括号个数
    int l,r;//还未匹配的左括号和右括号个数
}a[maxm<<2];
int n,m;
char s[maxm];
void pushup(int node){
    int temp=min(a[node*2].l,a[node*2+1].r);
    a[node].cnt=a[node*2].cnt+a[node*2+1].cnt+temp;
    a[node].l=a[node*2].l+a[node*2+1].l-temp;
    a[node].r=a[node*2].r+a[node*2+1].r-temp;
}
void build(int l,int r,int node){
    if(l==r){
        if(s[l]=='(')a[node].l=1;
        else a[node].r=1;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,node*2);
    build(mid+1,r,node*2+1);
    pushup(node);
}
Node ask(int st,int ed,int l,int r,int node){
    if(st<=l&&ed>=r){
        return a[node];
    }
    int mid=(l+r)/2;
    Node lc={0,0,0},rc={0,0,0},res={0,0,0};
    if(st<=mid){
        lc=ask(st,ed,l,mid,node*2);
    }
    if(ed>=mid+1){
        rc=ask(st,ed,mid+1,r,node*2+1);
    }
    int temp=min(lc.l,rc.r);
    res.cnt=lc.cnt+rc.cnt+temp;
    res.l=lc.l+rc.l-temp;
    res.r=lc.r+rc.r-temp;
    return res;
}
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    build(1,n,1);
    scanf("%d",&m);
    while(m--){
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",ask(l,r,1,n,1).cnt*2);
    }
    return 0;
}


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

using namespace std;
typedef long long ll;
const int N = 200001, M = 1001;
const ll mod = 1e9+7;
const int INF = 1 << 30;

struct node {
    int open, close, correct;
    node() {
        open = close = correct = 0;
    }
    node(int l, int r, int c) {
        open = l;
        close = r;
        correct = c;
    }
};

node combine (node l, node r) {
    int match = min(l.open, r.close);
    int nOpen = l.open + r.open - match;
    int nClose = l.close + r.close - match;
    int correct = l.correct + r.correct + match;
    return node(nOpen, nClose, correct);
}

struct segmentTree {

    int size;
    string s;
    vector <node> tree;

    void init(int n, string ss) {
        s = ss;
        size = 1;
        while (size < n) size *= 2;
        tree.resize(2 * size, {});
        build(0, 0, size);
    }

    void build(int x, int lx, int rx) {
        if (rx - lx == 1) {
            if (lx < (int) s.size()) {
                s[lx] == '(' ? tree[x] = node(1,0,0) : tree[x] = node(0,1,0);
            }
            return;
        }
        int m = (lx + rx) / 2;
        build(2 * x + 1, lx, m);
        build(2 * x + 2, m, rx);
        tree[x] = combine(tree[2 * x + 1], tree[2 * x + 2]);
    }

    node query(int l, int r, int x, int lx, int rx) {
        if (l >= rx || r <= lx) return node(0,0,0);
        if (lx >= l && rx <= r) {
            return tree[x];
        }
        int m = (lx + rx) / 2;
        return combine(query(l, r, 2 * x + 1, lx, m), query(l, r, 2 * x + 2, m, rx));
    }

    node query(int l, int r) {
        return query(l, r, 0, 0, size);
    }

};

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

    string s;
    cin >> s;
    segmentTree sg;
    sg.init(s.size(), s);
    int n;
    cin >> n;
    while (n--) {
        int l, r;
        cin >> l >> r;
        l--;
        cout << sg.query(l, r).correct * 2 << endl;
    }

    return 0;
}


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

string s;

struct Node {
    int valueOptimal;
    int open;
    int close;

};

Node IT[4000005];
Node operator+(const Node& left, const Node& right) {
    Node result;
    int tmp = min(left.open, right.close);
    result.valueOptimal = left.valueOptimal + right.valueOptimal + tmp;
    result.open = left.open + right.open - tmp;
    result.close = left.close + right.close - tmp;
    return result;
}

struct ITtree {
    void build (int id, int l, int r) {
        if(l == r) {
            if(s[l] == '(') {
                IT[id].valueOptimal = 0;
                IT[id].open = 1;
                IT[id].close = 0;
            } else {
                IT[id].valueOptimal = 0;
                IT[id].open = 0;
                IT[id].close = 1;
            }
            return;
        }
        int mid = (l+r)/2;
        build(2*id, l, mid);
        build(2*id+1, mid+1, r);
        IT[id] = IT[2*id] + IT[2*id+1];
    }

    Node answerQuery(int id, int l, int r, int u, int v) {
        if(v < l || r < u) {
            Node a;
            a.valueOptimal=0;
            a.open=0;
            a.close=0;
            return a;
        }
        if(u <= l && r <= v) {
            return IT[id];
        }
        int mid = (l + r) / 2;
        return answerQuery(2*id, l, mid, u, v) + answerQuery(2*id+1, mid +1, r, u, v);
    }
};
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    ITtree it;
    cin >> s;
    it.build(1, 0, s.size()-1);
    int m;
    cin >> m;
    while (m--)
    {
        int l, r;
        cin >> l >> r;
        cout << 2*it.answerQuery(1,0,s.size()-1,l-1,r-1).valueOptimal << endl;
    }

    return 0;
}


#include <bits/stdc++.h>
#define int long long
#define pii pair<int,pair<int,int>>
#define x first
#define y second.first
#define z second.second
using namespace std;
string s;
pii t[4000006];
void build(int v,int i,int j){
    if(i==j){
        t[v].x=0;
        if(s[i]=='(')
            t[v].y++;
        else t[v].z++;
        return;
    }
    int mid=(i+j)/2;
    build(v*2,i,mid);
    build(v*2+1,mid+1,j);
    int p=min(t[v*2].y,t[v*2+1].z);
    t[v].x=t[v*2].x+t[v*2+1].x+2*p;
    t[v].y=t[v*2].y+t[v*2+1].y-p;
    t[v].z=t[v*2].z+t[v*2+1].z-p;
}
pii get(int v,int i,int j,int l,int r){
    if(l>r)
        return {0,{0,0}};
    if(l==i && r==j)
        return t[v];
    int mid=(i+j)/2;
    pii g1=get(v*2,i,mid,l,min(mid,r));
    pii g2=get(v*2+1,mid+1,j,max(mid+1,l),r);
    pii pas={0,{0,0}};
    int p=min(g1.y,g2.z);
    pas.x=g1.x+g2.x+2*p;
    pas.y=g1.y+g2.y-p;
    pas.z=g1.z+g2.z-p;
    return pas;
}
main(){
cin>>s;
int n=s.size();
s='0'+s;
build(1,1,n);
int Q;
cin>>Q;
while(Q--){
   int l,r;
   cin>>l>>r;
   pii ans=get(1,1,n,l,r);
   cout<<ans.x<<endl;
}
return 0;
}


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

template<typename Abel> struct BIT {
    const Abel UNITY_SUM = 0;
    vector<Abel> dat;
    BIT(int n) : dat(n, UNITY_SUM) { }  // [0, n)
    inline void add(int i, Abel x) {
        while (i < (int)dat.size()) { dat[i] += x; i |= i + 1; }
    }
    inline Abel sum(int i) {    // [0, i]
        Abel res = UNITY_SUM;
        while (i >= 0) { res += dat[i]; i = (i & (i + 1)) - 1; }
        return res;
    }
    inline Abel sum(int a, int b) { return sum(b - 1) - sum(a - 1); }   // [a, b)
    Abel operator[](int i) { return sum(i, i + 1); }
    friend ostream& operator<<(ostream& os, BIT<Abel> &bit) {
        for (int i = 0; i < (int)bit.dat.size(); i++) os << bit[i] << " ";
        return os;
    }
};

int main() {
    string s; cin >> s;
    int n = s.size();
    int q; cin >> q;
    vector<int> l(q), r(q);
    for (int i = 0; i < q; i++) cin >> l[i] >> r[i], l[i]--;
    vector<vector<int>> qids(n + 1);
    for (int i = 0; i < q; i++) qids[r[i] - 1].emplace_back(i);
    vector<int> st;
    BIT<int> bit(n);
    vector<int> ans(q);
    for (int i = 0; i < (int)s.size(); i++)  {
        if (s[i] == '(') {
            st.emplace_back(i);
        } else if (s[i] == ')' && !st.empty()) {
            bit.add(st.back(), 1); st.pop_back();
        }
        for (int id: qids[i]) ans[id] = bit.sum(l[id], r[id]) * 2;
    }
    for (int x: ans) cout << x << endl;
    return 0;
}


#include <algorithm>
#include <iostream>
#include <vector>
#include <tuple>
#include <functional>
using namespace std;

template<typename Monoid>
struct SegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;
    const F f;
    const Monoid M1;
    int sz;
    vector<Monoid> dat;
    SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1), sz(1) {
        while (sz < n) sz <<= 1;
        dat.assign(sz * 2, M1);
    }
    void set(int k, const Monoid &x) { dat[k + sz] = x; }
    void build() {
        for (int k = sz - 1; k > 0; k--) {
            dat[k] = f(dat[2 * k], dat[2 * k + 1]);
        }
    }
    void update(int k, const Monoid &x) {
        dat[k += sz] = x;
        while (k >>= 1) dat[k] = f(dat[2 * k], dat[2 * k + 1]);
    }
    Monoid get(int a, int b) {  // [a, b)
        Monoid L = M1, R = M1;
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1) L = f(L, dat[a++]);
            if (b & 1) R = f(dat[--b], R);
        }
        return f(L, R);
    }
    Monoid operator[](const int &k) const { return dat[k + sz]; }
    friend ostream& operator<<(ostream& os, SegmentTree<Monoid> &seg) {
        for (int i = 0; i < seg.sz; i++) os << seg[i] << " ";
        return os;
    }
};

int main() {
    string s; cin >> s;
    int n = s.size();
    struct T { int x, l, r; };
    auto f = [](const T &a, const T &b) {
        int add = min(a.l, b.r);
        return T{a.x + b.x + add * 2, a.l + b.l - add, a.r + b.r - add};
    };
    SegmentTree<T> seg(n, f, T{0, 0, 0});
    for (int i = 0; i < n; i++) {
        seg.set(i, T{0, s[i] == '(', s[i] == ')'});
    }
    seg.build();
    int q; cin >> q;
    while (q--) {
        int l, r; cin >> l >> r; l--;
        cout << seg.get(l, r).x << endl;
    }
    return 0;
}


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

template<typename Abel> struct BIT {
    const Abel UNITY_SUM = 0;
    vector<Abel> dat;
    BIT(int n) : dat(n, UNITY_SUM) { }  // [0, n)
    inline void add(int i, Abel x) {
        while (i < (int)dat.size()) { dat[i] += x; i |= i + 1; }
    }
    inline Abel sum(int i) {    // [0, i]
        Abel res = UNITY_SUM;
        while (i >= 0) { res += dat[i]; i = (i & (i + 1)) - 1; }
        return res;
    }
    inline Abel sum(int a, int b) { return sum(b - 1) - sum(a - 1); }   // [a, b)
    Abel operator[](int i) { return sum(i, i + 1); }
    friend ostream& operator<<(ostream& os, BIT<Abel> &bit) {
        for (int i = 0; i < (int)bit.dat.size(); i++) os << bit[i] << " ";
        return os;
    }
};

int main() {
    string s; cin >> s;
    int n = s.length();
    int q; cin >> q;
    vector<int> ls(q), rs(q);
    for (int i = 0; i < q; i++) cin >> ls[i] >> rs[i], ls[i]--, rs[i]--;
    vector<vector<int>> ids(n);
    for (int i = 0; i < q; i++) ids[rs[i]].emplace_back(i);
    vector<int> st;
    BIT<int> bit(n);
    vector<int> ans(q);
    for (int r = 0; r < n; r++) {
        if (s[r] == '(') {
            st.emplace_back(r);
        } else if (s[r] == ')' && !st.empty()) {
            bit.add(st.back(), 1), st.pop_back();
        }
        for (int id: ids[r]) ans[id] = bit.sum(ls[id], rs[id] + 1) * 2;
    }
    for (int x: ans) cout << x << endl;
    return 0;
}


#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>
using namespace std;

template<typename Monoid>
struct SegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;
    const F f;
    const Monoid M1;
    int sz;
    vector<Monoid> dat;
    SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1), sz(1) {
        while (sz < n) sz <<= 1;
        dat.assign(sz * 2, M1);
    }
    void set(int k, const Monoid &x) { dat[k + sz] = x; }
    void build() {
        for (int k = sz - 1; k > 0; k--) {
            dat[k] = f(dat[2 * k], dat[2 * k + 1]);
        }
    }
    void update(int k, const Monoid &x) {
        dat[k += sz] = x;
        while (k >>= 1) dat[k] = f(dat[2 * k], dat[2 * k + 1]);
    }
    Monoid get(int a, int b) {  // [a, b)
        Monoid L = M1, R = M1;
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1) L = f(L, dat[a++]);
            if (b & 1) R = f(dat[--b], R);
        }
        return f(L, R);
    }
    Monoid operator[](const int &k) const { return dat[k + sz]; }
    friend ostream& operator<<(ostream& os, SegmentTree<Monoid> &seg) {
        for (int i = 0; i < seg.sz; i++) os << seg[i] << " ";
        return os;
    }
};

int main() {
    string s; cin >> s;
    int n = s.length();
    struct T { int x, l, r; };
    auto f = [](const T &a, const T &b) {
        int add = min(a.l, b.r);
        return T{a.x + b.x + add * 2, a.l + b.l - add, a.r + b.r - add};
    };
    SegmentTree<T> seg(n, f, T{0, 0, 0});
    for (int i = 0; i < n; i++) seg.set(i, T{0, s[i] == '(', s[i] == ')'});
    seg.build();
    int q; cin >> q;
    while (q--) {
        int l, r; cin >> l >> r; l--;
        cout << seg.get(l, r).x << endl;
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <bitset>
#include <unordered_map>

#define pb push_back
#define ll long long
#define mp make_pair
#define f first
#define s second
#define pii pair < int, int >
#define ull unsigned long long
#define pll pair < ll, ll >
#define forit(it, s) for(__typeof(s.begin()) it = s.begin(); it != s.end(); it ++)
#define all(s) s.begin(), s.end()
#define sz(a) (int)a.size()

const int inf = 100100;
const int maxn = (int) 1e6 + 10;
const int mod = (int) 1e9 + 7;
using namespace std;
struct node{
	int pref, suff, sum;

} t[4*maxn];
string s;
int n;

node merge(node a, node b) {
	node c;
	int x = min(a.suff, b.pref);
	c.sum = a.sum + b.sum + 2*x;
	c.pref = a.pref + b.pref-x;
	c.suff = a.suff - x + b.suff;
	return c;
}

node get(int v, int tl, int tr, int l, int r) {
	if(tl > r || tr < l) return {0, 0, 0};
	if(l <= tl && tr <= r) return t[v];
	int mid = (tl+tr)>>1;
	return merge(get(v*2, tl, mid, l, r), get(v*2+1, mid+1, tr, l, r));
}

void build(int v, int l, int r) {
	if(l == r) {
		if(s[l] == '(') t[v] = {0, 1, 0};
		else t[v] = {1, 0, 0};
	}else {
		int mid = (l + r)>>1;
		build(v*2, l, mid);
		build(v*2+1, mid+1, r);
		t[v] = merge(t[v*2], t[v*2+1]);
	}
}
void solve(){
	cin >> s;
	n = s.size();
	build(1, 0, n-1);
	int m;
	cin >> m;
	for(int i = 0; i < m; i++) {
		int l, r;
		cin >> l >> r;
		cout << get(1, 0, n-1, l-1, r-1).sum << "\n";
	}
}

int main () {
    int t=1;
    //scanf("%d", &t);
    for(int i=1; i <= t; i++){
      //printf("Case #%d\n", i);
      solve();
    }

    return 0;
}


#include <bits/stdc++.h>
#define lchild 2*node
#define rchild 2*node+1
#define mid (l+r)/2
#define pii pair<int, int>
#define mx 1000007
using namespace std;

string s;
struct
{
    int open, close;
} tree[4*mx];

void merge_node( int node )
{
    int mn= min(tree[lchild].open, tree[rchild].close);
    tree[node].open= tree[lchild].open+tree[rchild].open-mn;
    tree[node].close= tree[lchild].close+tree[rchild].close-mn;
}

void build( int node, int l, int r )
{
    if( l==r )
    {
        if( s[l-1]=='(' )
            tree[node].open= 1,
            tree[node].close= 0;
        else
            tree[node].open= 0,
            tree[node].close= 1;
        return;
    }

    build( lchild, l, mid );
    build( rchild, mid+1, r );

    merge_node(node);
}

pii query( int node, int l, int r, int i, int j )
{
    if( l>j or r<i )
        return pii(0,0);
    if( l>=i and r<=j )
        return pii(tree[node].open,tree[node].close);

    pii q1= query( lchild, l, mid, i, j );
    pii q2= query( rchild, mid+1, r, i, j );

    int mn= min(q1.first,q2.second);
    int retopen= q1.first+q2.first-mn;
    int retclose= q1.second+q2.second-mn;

    return pii(retopen,retclose);
}

int main()
{
    cin>>s;
    int n= s.size();

    build(1, 1, n);

    int q;
    scanf("%d", &q);

    while(q--)
    {
        int i,j;
        scanf("%d %d", &i, &j);

        pii ans= query( 1, 1, n, i, j );
        int out= j-i+1-ans.first-ans.second;

        printf("%d\n", out);
    }

}


//Be Name Khoda
//no comment...
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef long double ld;
const int MOD = (int)1e9 + 7;
const int MAXN = (int)1e6 + 7;
const ll inf = (ll)1e10;
const int infint = (int)1e9;
string s;
int seg[4 * MAXN], seg1[4 * MAXN], seg2[4 * MAXN];
struct outp{
	int ans, ope, clo;
};
void build(int node, int l, int r)
{
	if(r - l < 2)
	{
		seg[node] = 0;
		if(s[l] == '(')
			seg1[node] = 1;
		else
			seg2[node] = 1;
		return;
	}
	int mid = (l + r) >> 1;
	build(2 * node, l, mid);
	build(2 * node + 1, mid, r);
	seg[node] = seg[2 * node] + seg[2 * node + 1] + min(seg1[2 * node], seg2[2 * node + 1]);
	seg1[node] = seg1[2 * node] + seg1[2 * node + 1] - min(seg1[2 * node], seg2[2 * node + 1]);
	seg2[node] = seg2[2 * node] + seg2[2 * node + 1] - min(seg1[2 * node], seg2[2 * node + 1]);
}
outp get(int node, int l, int r, int st, int en)
{
	if(r <= st || l >= en)
	{
		outp cnt;
		cnt.ans = 0, cnt.clo = 0, cnt.ope = 0;
		return cnt;
	}
	if(st >= l && en <= r)
	{
		outp cnt;
		cnt.ans = seg[node], cnt.ope = seg1[node], cnt.clo = seg2[node];
		return cnt;
	}
	int mid = (st + en) >> 1;
	outp fir = get(2 * node, l, r, st, mid);
	outp sec = get(2 * node + 1, l, r, mid, en);
	outp now;
	now.ans = fir.ans + sec.ans + min(fir.ope, sec.clo);
	now.ope = fir.ope + sec.ope - min(fir.ope, sec.clo);
	now.clo = fir.clo + sec.clo - min(fir.ope, sec.clo);
	return now;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> s;
	build(1, 0, s.size());
	int m;
	cin >> m;
	for (int i = 0; i < m; i++)
	{
		int l, r;
		cin >> l >> r;
		l--;
		cout << 2 * get(1, l, r, 0, s.size()).ans << "\n";
	}
}


//Be Name Khoda
//no comment...
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef long double ld;
const int MOD = (int)1e9 + 7;
const int MAXN = (int)1e5 + 7;
const ll inf = (ll)1e10;
const int infint = (int)1e9;
string s;
int seg[4 * MAXN], seg1[4 * MAXN], seg2[4 * MAXN];
struct outp{
	int ans, ope, clo;
};
void build(int node, int l, int r)
{
	if(r - l < 2)
	{
		seg[node] = 0;
		if(s[l] == '(')
			seg1[node] = 1;
		else
			seg2[node] = 1;
		return;
	}
	int mid = (l + r) >> 1;
	build(2 * node, l, mid);
	build(2 * node + 1, mid, r);
	seg[node] = seg[2 * node] + seg[2 * node + 1] + min(seg1[2 * node], seg2[2 * node + 1]);
	seg1[node] = seg1[2 * node] + seg1[2 * node + 1] - min(seg1[2 * node], seg2[2 * node + 1]);
	seg2[node] = seg2[2 * node] + seg2[2 * node + 1] - min(seg1[2 * node], seg2[2 * node + 1]);
}
outp get(int node, int l, int r, int st, int en)
{
	if(r <= st || l >= en)
	{
		outp cnt;
		cnt.ans = 0, cnt.clo = 0, cnt.ope = 0;
		return cnt;
	}
	if(st >= l && en <= r)
	{
		outp cnt;
		cnt.ans = seg[node], cnt.ope = seg1[node], cnt.clo = seg2[node];
		return cnt;
	}
	int mid = (st + en) >> 1;
	outp fir = get(2 * node, l, r, st, mid);
	outp sec = get(2 * node + 1, l, r, mid, en);
	outp now;
	now.ans = fir.ans + sec.ans + min(fir.ope, sec.clo);
	now.ope = fir.ope + sec.ope - min(fir.ope, sec.clo);
	now.clo = fir.clo + sec.clo - min(fir.ope, sec.clo);
	return now;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> s;
	build(1, 0, s.size());
	int m;
	cin >> m;
	for (int i = 0; i < m; i++)
	{
		int l, r;
		cin >> l >> r;
		l--;
		cout << 2 * get(1, l, r, 0, s.size()).ans << "\n";
	}
}


#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>
#include <utility>
#include <cstdio>
#include <iomanip>
#include <iterator>
#include <vector>
#include <map>
#include <set>
#define fi first
#define se second
#define m_p make_pair
#define endl "\n"
using namespace std;
typedef long long ll;
const int NN=1000001;
int n,m,i,k,j,f,x,y,z,q,w,e,t1,tt,t2; string s;
int t[4*NN+1], f1[4*NN+1], f2[4*NN+1];

void modify(int v, int tl, int tr, int pos, int t1, int t2)
{
    if(tl==tr)
    {
        f1[v]=t1;
        f2[v]=t2;
    }
    else
    {
        int c=(tl+tr)>>1;
        if(pos<=c)modify(v*2,tl,c,pos,t1,t2);
        else modify(v*2+1,c+1,tr,pos,t1,t2);
        int q=min(f1[v*2],f2[v*2+1]);
        t[v]=t[v*2]+(q<<1)+t[v*2+1];
        f1[v]=f1[v*2]-q+f1[v*2+1];
        f2[v]=f2[v*2]-q+f2[v*2+1];
    }
}

void get(int v, int tl, int tr, int l, int r)
{
    if(l>r)return;
    if(tl==l && tr==r)
    {
        int q=min(t1,f2[v]);
        tt+=(t[v]+(q<<1));
        t1+=(f1[v]-q);
        t2+=(f2[v]-q);
        return;
    }
    int c=(tl+tr)>>1;
    get(v*2,tl,c,l,min(c,r));
    get(v*2+1,c+1,tr,max(l,c+1),r);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cin >> s; n=s.size();
    for(i=1; i<=n; i++)modify(1,1,n,i,1-abs(s[i-1]-'('),1-abs(s[i-1]-')'));
    cin >> m;
    for(i=1; i<=m; i++)
    {
        cin >> x >> y;
        t1=0; t2=0;
        tt=0; w=0;
        get(1,1,n,x,y);
        cout << tt << endl;
    }
    return 0;
}