#include <bits/stdc++.h>
using namespace std;
struct node {
  int l;
  int r;
  int ans;
  int x;
  int y;
} tree[1000100 * 4];
char s[1000100];
int a[1000100], n;
void build(int v, int l, int r) {
  tree[v].l = l;
  tree[v].r = r;
  if (l == r) {
    tree[v].ans = 0;
    if (s[l - 1] == '(')
      tree[v].x++;
    else
      tree[v].y++;
    return;
  }
  int mid = (l + r) >> 1;
  build(v << 1, l, mid);
  build(v << 1 | 1, mid + 1, r);
  int cha = min(tree[v << 1].x, tree[v << 1 | 1].y);
  tree[v].ans = tree[v << 1].ans + tree[v << 1 | 1].ans + 2 * cha;
  tree[v].x = tree[v << 1].x - cha + tree[v << 1 | 1].x;
  tree[v].y = tree[v << 1].y + tree[v << 1 | 1].y - cha;
}
node myUnion(node tree1, node tree2) {
  node p;
  int m = min(tree1.x, tree2.y);
  p.ans = tree1.ans + tree2.ans + 2 * m;
  p.x = tree1.x + tree2.x - m;
  p.y = tree1.y + tree2.y - m;
  return p;
}
node query(int v, int l, int r) {
  if (l == tree[v].l && r == tree[v].r) return tree[v];
  int mid = (tree[v].l + tree[v].r) >> 1;
  if (l <= mid && r <= mid)
    return query(2 * v, l, r);
  else if (l > mid)
    return query(2 * v + 1, l, r);
  else
    return myUnion(query(2 * v, l, mid), query(2 * v + 1, mid + 1, r));
}
int main() {
  scanf("%s", s);
  int len = strlen(s);
  build(1, 1, len);
  int t;
  scanf("%d", &t);
  while (t--) {
    int l, r;
    scanf("%d%d", &l, &r);
    printf("%d\n", query(1, l, r).ans);
  }
  return 0;
}
