← Home
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)
}