#include <bits/stdc++.h>
using namespace std;
ifstream in("luffpar.in");
ofstream out("luffpar.out");
struct arbore
{
int sum;
int mn;
int mx;
bool lazy;
};
const int nx=200002;
arbore arb[3*nx],x;
char s[nx];
int v[nx];
int nrop,op,i,j,n;
arbore combine (arbore left, arbore right)
{
arbore c;
c.lazy=0;
c.sum=right.sum+left.sum;
c.mn=min(left.mn,left.sum+right.mn);
c.mx=max(left.mx,left.sum+right.mx);
return c;
}
void build (int nod, int st, int dr)
{
if(st==dr)
{
arb[nod].sum=v[st];
arb[nod].mn=arb[nod].mx=v[st];
}
else if(st<dr)
{
int m=(st+dr)>>1;
int nod1=nod<<1;
int nod2=nod1|1;
build(nod1,st,m);
build(nod2,m+1,dr);
arb[nod]=combine(arb[nod1],arb[nod2]);
}
}
arbore change (arbore a)
{
arbore newa;
newa.sum=a.sum*(-1);
newa.mx=a.mn*(-1);
newa.mn=a.mx*(-1);
newa.lazy=1;
return newa;
}
void update (int nod, int st , int dr, int a, int b)
{
if(st>dr)
return;
int m=(st+dr)>>1;
int nod1=nod<<1;
int nod2=nod1|1;
if(arb[nod].lazy)
{
if(st!=dr)
{
arb[nod1]=change(arb[nod1]);
arb[nod2]=change(arb[nod2]);
}
arb[nod].lazy=0;
}
if(a<=st && b>=dr)
{
arb[nod]=change(arb[nod]);
return;
}
if(a<=m)
update(nod1,st,m,a,b);
if(b>=m+1)
update(nod2,m+1,dr,a,b);
arb[nod]=combine(arb[nod1],arb[nod2]);
}
arbore query (int nod, int st , int dr, int a, int b)
{
arbore val1{0,0,0,0}, val2={0,0,0,0};
arbore val;
if(st<=dr)
{
int m=(st+dr)>>1;
int nod1=nod<<1;
int nod2=nod1|1;
if(arb[nod].lazy)
{
if(st!=dr)
{
arb[nod1]=change(arb[nod1]);
arb[nod2]=change(arb[nod2]);
}
arb[nod].lazy=0;
}
if(a<=st && b>=dr)
return arb[nod];
if(a<=m)
val1=query(nod1,st,m,a,b);
if(b>=m+1)
val2=query(nod2,m+1,dr,a,b);
arb[nod]=combine(arb[nod1],arb[nod2]);
}
val=combine(val1,val2);
return val;
}
int main()
{
in>>n;
in.get();
in>>s;
for(i=0; i<n; i++)
{
if(s[i]=='(')
v[i+1]=1;
else
v[i+1]=-1;
}
build(1,1,n);
for(in>>nrop;nrop;nrop--)
{
in>>op>>i>>j;
if(op==2)
{
x=query(1,1,n,i,j);
out<<(x.sum==0 && x.mn==0)<<'\n';
}
else
{
update(1,1,n,i,j);
}
}
return 0;
}