//n(n<=5e4+10)个格子,每个格子的初始值为1 //m(m<=5e4+10)个询问 //D l r 将区间l,r的所有点翻倍 //D l r 问区间l,r中格子中最多的数 //线段树维护三个值,ss(区间的所有值之和),ma(区间中的最大值) //mm(区间需要乘2的多少次方) #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 5e4+10 ; #define left v<<1 #define right v<<1|1 typedef long long ll ; struct Tree { int l , r ; int mm; ll ss ; ll ma ; }tree[maxn<<2] ; void push_up(int v) { tree[v].ma = max(tree[left].ma , tree[right].ma) ; tree[v].ss = tree[left].ss + tree[right].ss ; } void push_down(int v) { if(tree[v].mm){ ll tmp = ((ll)1)<<tree[v].mm ; tree[left].ss *= tmp ; tree[left].ma *= tmp ; tree[left].mm += tree[v].mm ; tree[right].ss *= tmp ; tree[right].ma *= tmp ; tree[right].mm += tree[v].mm ; tree[v].mm = 0 ; } } void build(int l , int r , int v) { tree[v].l = l ; tree[v].r = r; tree[v].mm = 0 ; if(l == r){ tree[v].ma = tree[v].ss = 1; return ; } int mid = (l + r) >> 1 ; build(l , mid , left) ; build(mid+1,r,right) ; push_up(v) ; } void update(int l , int r , int v) { if(l <= tree[v].l && tree[v].r <= r){ tree[v].ss *= 2 ; tree[v].ma *= 2 ; tree[v].mm++; return ; } push_down(v) ; int mid = (tree[v].l + tree[v].r) >> 1 ; if(l <= mid)update(l,r,left) ; if(r > mid)update(l,r,right) ; push_up(v) ; } struct node { ll pp ,ss , xx ; }; node query(ll x , int v) { if(tree[v].l == tree[v].r) return node{tree[v].l , tree[v].ss , x} ; push_down(v) ; node ans ; if(tree[left].ss >= x) ans = query(x , left) ; else ans = query(x-tree[left].ss , right) ; push_up(v) ; return ans ; } void add(int pos , ll x , int v) { if(tree[v].l == tree[v].r){ tree[v].ma += x ; tree[v].ss += x ; return ; } push_down(v) ; int mid = (tree[v].l + tree[v].r) >> 1 ; if(pos <= mid)add(pos , x , left) ; else add(pos , x , right) ; push_up(v) ; } ll get_ans(int l , int r , int v) { if(l <= tree[v].l && tree[v].r <= r) return tree[v].ma ; push_down(v) ; int mid = (tree[v].l + tree[v].r) >> 1 ; ll ans = 0 ; if(l <= mid)ans = max(ans , get_ans(l,r,left)) ; if(r > mid) ans = max(ans , get_ans(l,r,right)) ; push_up(v) ; return ans ; } int main() { int t ; int cas = 0 ; scanf("%d" , &t) ; while(t--) { int n , m ; scanf("%d%d" , &n , &m) ; build(1,n,1) ; char ch[5] ; ll l , r ; printf("Case #%d:\n" , ++cas) ; while(m--) { scanf("%s%lld%lld" , ch , &l , &r) ; node p1 = query(l,1) ; node p2 = query(r,1) ; if(ch[0] == 'D'){ if(p1.pp == p2.pp) add(p1.pp,r-l+1,1) ; else{ add(p1.pp,p1.ss-p1.xx+1,1) ; add(p2.pp,p2.xx,1) ; update(p1.pp+1,p2.pp-1,1) ; } } else { if(p1.pp == p2.pp) printf("%lld\n" , r-l+1) ; else{ ll ans = max(p1.ss-p1.xx+1,p2.xx) ; ans = max(ans , get_ans(p1.pp+1,p2.pp-1,1)) ; printf("%lld\n" , ans) ; } } } } return 0 ; }