import java.util.*;
import java.io.*;
public class Main {
static class node
{
int head;
int tail;
// use more variables if you want more information
// these default values should be identity_element
node(){}
node(int head, int tail){
this.head = head;
this.tail = tail;
}
void merge( node l,node r){ // store the thing you wanna query
// mn = Math.min(l.mn,r.mn);
// freq = 0;
// if(l.mn == mn) freq += l.freq;
// if(r.mn == mn) freq += r.freq;
head = l.head + r.head;
tail = l.tail + r.tail;
// if we wanted the maximum, then we would do
// like v = max(l.v,r.v)
}
}
// example: add on a range: identity transformation = 0
// old += new
// if old is identity which is 0, then 0 + new which new
static class update
{
int no_of_flip = 0; // 4
// use more variables if you want more information
// these default values should be identity_transformation
update(){}
update(int val){
no_of_flip = val; // 5
}
// combine the current my_update with the other my_update (see keynotes)
void combine(update other,int tl,int tr){
no_of_flip += other.no_of_flip; // 6
// you can be sure that the "other" is newer than current
}
// store the correct information in the my_node x
void apply(node x,int tl,int tr){
// int temp_head = x.head;
int temp_tail = x.tail;
if(no_of_flip % 2 != 0)
{
x.tail = x.head;
x.head = temp_tail;
}
}
}
static class segtree
{
int len;
node t[];
update u[];
boolean []lazy;
node identity_element;
update identity_transformation;
segtree(int l){
len = l;
t = new node[4 * len + 1];
u = new update[4 * len + 1];
lazy = new boolean[4 * len + 1];
identity_element = new node();
identity_transformation = new update();
}
void pushdown(int v, int tl, int tr){
if(!lazy[v]) return;
int tm = (tl + tr) >> 1;
apply(v<<1,tl,tm,u[v]);
apply(v<<1|1,tm+1,tr,u[v]);
u[v] = identity_transformation;
lazy[v] = false;
}
void apply( int v, int tl, int tr, update upd){
if(tl != tr){
lazy[v] = true;
u[v] = new update(0);
u[v].combine(upd,tl,tr);
}
upd.apply(t[v],tl,tr);
}
void build( int[] arr, int v, int tl, int tr){
if(tl == tr){
t[v] = new node(0,1);
return;
}
int tm = (tl + tr) >> 1;
build(arr,v<<1,tl,tm);
build(arr,v<<1|1,tm+1,tr);
t[v] = new node(0,0);
t[v].merge(t[v<<1],t[v<<1|1]);
}
node query( int v, int tl, int tr, int l, int r){
if(l > tr || r < tl){
return identity_element;
}
if(tl >= l && tr <= r){
return t[v];
}
pushdown(v,tl,tr);
int tm = (tl + tr) >> 1;
node a = query(v<<1,tl,tm,l,r);
node b = query(v<<1|1,tm+1,tr,l,r);
node ans = new node();
ans.merge(a,b);
return ans;
}
// rupd = range update
void rupd( int v, int tl, int tr, int l, int r, update upd){
if(l > tr || r < tl){
return;
}
if(tl >= l && tr <= r){
apply(v,tl,tr,upd);
return;
}
pushdown(v,tl,tr);
int tm = (tl + tr) >> 1;
rupd(v<<1,tl,tm,l,r,upd);
rupd(v<<1|1,tm+1,tr,l,r,upd);
t[v].merge(t[v<<1],t[v<<1|1]);
}
void build( int[] arr){
build(arr,1,0,len-1);
}
node query( int l, int r){
return query(1,0,len-1,l,r);
}
void rupd( int l, int r, update upd){
rupd(1,0,len-1,l,r,upd);
}
}
public static void main(String[] args) throws IOException {
try{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int q = sc.nextInt();
int [] arr = new int[n];
// int max = 0;
// for(int i = 0;i<n;i++)
// {
// arr[i] = sc.nextInt();
// max = Math.max(max, arr[i]);
// }
int ans = 0;
segtree s = new segtree(n);
s.build(arr);
while(q > 0)
{
int type,x,y;
type = sc.nextInt();
x = sc.nextInt();
y = sc.nextInt();
if(type == 0)
{
s.rupd(x, y , new update(1));
}
else if(type == 1){
System.out.println(s.query(x, y ).head);
}
q--;
}
// int []arr = new int[1000];
// arr[10] = 35;
// arr[13] = 3;
// s.build(arr);
// s.rupd(2, 5, new update(8));
// s.rupd(1,3,new update(-4));
// System.out.print(s.query(2, 4).mn44);
// System.out.print(ans);
// sc.close();
return;
}
catch(Exception e)
{
return;
}
}
}