package main
import (
"io"
"os"
"strconv"
)
type FastScanner struct {
data []byte
idx int
n int
}
func (fs *FastScanner) NextInt() int {
for fs.idx < fs.n {
c := fs.data[fs.idx]
if (c >= '0' && c <= '9') || c == '-' {
break
}
fs.idx++
}
sign := 1
if fs.idx < fs.n && fs.data[fs.idx] == '-' {
sign = -1
fs.idx++
}
val := 0
for fs.idx < fs.n {
c := fs.data[fs.idx]
if c < '0' || c > '9' {
break
}
val = val*10 + int(c-'0')
fs.idx++
}
return sign * val
}
type Interval struct {
l int
r int
}
type MaxHeap struct {
a []Interval
}
func better(x, y Interval) bool {
lx := x.r - x.l
ly := y.r - y.l
if lx != ly {
return lx > ly
}
if x.r != y.r {
return x.r > y.r
}
return x.l > y.l
}
func (h *MaxHeap) Push(v Interval) {
h.a = append(h.a, v)
i := len(h.a) - 1
for i > 0 {
p := (i - 1) >> 1
if !better(h.a[i], h.a[p]) {
break
}
h.a[i], h.a[p] = h.a[p], h.a[i]
i = p
}
}
func (h *MaxHeap) Pop() Interval {
v := h.a[0]
last := h.a[len(h.a)-1]
h.a = h.a[:len(h.a)-1]
if len(h.a) == 0 {
return v
}
h.a[0] = last
i := 0
for {
l := i*2 + 1
if l >= len(h.a) {
break
}
r := l + 1
j := l
if r < len(h.a) && better(h.a[r], h.a[l]) {
j = r
}
if !better(h.a[j], h.a[i]) {
break
}
h.a[i], h.a[j] = h.a[j], h.a[i]
i = j
}
return v
}
type Node struct {
key int
prio uint32
size int
left *Node
right *Node
}
func sz(t *Node) int {
if t == nil {
return 0
}
return t.size
}
func upd(t *Node) {
if t != nil {
t.size = 1 + sz(t.left) + sz(t.right)
}
}
func rotateRight(t *Node) *Node {
x := t.left
t.left = x.right
x.right = t
upd(t)
upd(x)
return x
}
func rotateLeft(t *Node) *Node {
x := t.right
t.right = x.left
x.left = t
upd(t)
upd(x)
return x
}
var seed uint64 = 88172645463393265
func rnd() uint32 {
seed += 0x9e3779b97f4a7c15
z := seed
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9
z = (z ^ (z >> 27)) * 0x94d049bb133111eb
z ^= z >> 31
return uint32(z)
}
func insert(t *Node, key int) *Node {
if t == nil {
return &Node{key: key, prio: rnd(), size: 1}
}
if key < t.key {
t.left = insert(t.left, key)
if t.left.prio > t.prio {
t = rotateRight(t)
}
} else if key > t.key {
t.right = insert(t.right, key)
if t.right.prio > t.prio {
t = rotateLeft(t)
}
}
upd(t)
return t
}
func erase(t *Node, key int) *Node {
if t == nil {
return nil
}
if key < t.key {
t.left = erase(t.left, key)
} else if key > t.key {
t.right = erase(t.right, key)
} else {
if t.left == nil {
return t.right
}
if t.right == nil {
return t.left
}
if t.left.prio > t.right.prio {
t = rotateRight(t)
t.right = erase(t.right, key)
} else {
t = rotateLeft(t)
t.left = erase(t.left, key)
}
}
upd(t)
return t
}
func countLE(t *Node, x int) int {
if t == nil {
return 0
}
if x < t.key {
return countLE(t.left, x)
}
return sz(t.left) + 1 + countLE(t.right, x)
}
func predecessor(t *Node, key int) int {
res := 0
for t != nil {
if t.key < key {
res = t.key
t = t.right
} else {
t = t.left
}
}
return res
}
func successor(t *Node, key int, n int) int {
res := n + 1
for t != nil {
if t.key > key {
res = t.key
t = t.left
} else {
t = t.right
}
}
return res
}
func enc(l, r int) uint64 {
return uint64(uint32(l))<<32 | uint64(uint32(r))
}
func main() {
data, _ := io.ReadAll(os.Stdin)
fs := FastScanner{data: data, n: len(data)}
n := fs.NextInt()
q := fs.NextInt()
var root *Node
h := MaxHeap{}
active := make(map[uint64]struct{}, q*3+1)
pos := make(map[int]int, q+1)
addInterval := func(l, r int) {
if l > r {
return
}
active[enc(l, r)] = struct{}{}
h.Push(Interval{l: l, r: r})
}
removeInterval := func(l, r int) {
if l > r {
return
}
delete(active, enc(l, r))
}
addInterval(1, n)
out := make([]byte, 0, q*4)
for t := 0; t < q; t++ {
x := fs.NextInt()
if x == 0 {
i := fs.NextInt()
j := fs.NextInt()
ans := countLE(root, j) - countLE(root, i-1)
out = strconv.AppendInt(out, int64(ans), 10)
out = append(out, '\n')
continue
}
if p, ok := pos[x]; ok {
delete(pos, x)
a := predecessor(root, p)
b := successor(root, p, n)
removeInterval(a+1, p-1)
removeInterval(p+1, b-1)
root = erase(root, p)
addInterval(a+1, b-1)
} else {
var iv Interval
for {
iv = h.Pop()
k := enc(iv.l, iv.r)
if _, ok := active[k]; ok {
delete(active, k)
break
}
}
m := (iv.l + iv.r + 1) / 2
root = insert(root, m)
pos[x] = m
addInterval(iv.l, m-1)
addInterval(m+1, iv.r)
}
}
os.Stdout.Write(out)
}