#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 50010
#define Lson root*2
#define Rson root*2+1
#define Max(a,b)(a>b?a:b)
int ac[maxn];
struct ndoe
{//lsum表示左区间的连续,rsum表示在右区间的连续,sum表示中间区间的连续;
int L,R;
int lsum,rsum,sum;
int Mid()
{
return (R+L)/2;
}
int len()
{
return (R-L+1);
}
} a[maxn*4];
void BuildTree(int root,int L,int R)
{
a[root].L=L,a[root].R=R;
a[root].lsum = a[root].rsum = a[root].sum = a[root].len();
if(L==R) return ;
BuildTree(Lson,L,a[root].Mid());
BuildTree(Rson,a[root].Mid()+1,R);
}
void pushup(int root)
{
a[root].lsum = a[Lson].lsum, a[root].rsum = a[Rson].rsum;//左区间的连续 最大为子节点的最大连续,右区间同理;
if(a[Lson].lsum == a[Lson].len()) //如果子节点的最大连续等于其长度,则说明其最大连续可以加上右区间的左连续;
a[root].lsum = a[Lson].lsum + a[Rson].lsum;
if(a[Rson].rsum == a[Rson].len())
a[root].rsum = a[Rson].rsum + a[Lson].rsum;
a[root].sum = Max(a[root].lsum, Max(a[root].rsum, a[Lson].rsum+a[Rson].lsum));//中间区间的最大为三个数的最大值(左连续,右连续,子节点左区间的右连续+右区间的左连续)
}
void update(int root, int k, int e)
{
if( a[root].L == a[root].R )
{
a[root].lsum = a[root].rsum = a[root].sum = e;
return ;
}
if(k <= a[root].Mid())
update(Lson, k, e);
else
update(Rson, k, e);
pushup(root);
}
int Query(int root,int k)
{
if(a[root].sum ==0 )
return 0;
if(k < a[root].L +a[root].lsum) //判断其是否在左区间;K < 左端点 + 左连续;
return a[root].lsum;
if(k > a[root].R - a[root].rsum) //判断其是否在右区间; k > 右端点 - 右连续;
return a[root].rsum;
if(k > (a[Lson].R - a[Lson].rsum) && k < (a[Rson].L + a[Rson].lsum)) //判断是否在中间; 右端点 - 右连续 < K < 左端点 + 左连续;
return a[Rson].lsum + a[Lson].rsum;
if(k<=a[root].Mid())
return Query(Lson,k);
else
return Query(Rson,k);
}
int main()
{
int n,m,k,w;
char str[10];
while(~scanf("%d%d",&n,&m))
{
k=0;
BuildTree(1,1,n);
while(m--)
{
scanf("%s",str);
if(str[0]=='D')
{
scanf("%d",&w);
ac[k]=w;
update(1,w,0);
k++;
}
if(str[0]=='R')
{
k--;
w = ac[k];
update(1,w,1);
}
if(str[0] == 'Q')
{
scanf("%d",&w);
printf("%d\n",Query(1,w));
}
}
}
return 0;
}