#include <bits/stdc++.h>
using namespace std;
struct Ftree {
  vector<int> data;
  int n;
  Ftree(int nsize) {
    n = nsize;
    data.resize(n, 0);
  }
  void add(int pos, int toAdd) {
    if (pos >= n) return;
    data[pos] += toAdd;
    add(pos + (pos & -pos), toAdd);
  }
  int get(int pos) {
    if (pos == 0) return 0;
    return data[pos] + get(pos - (pos & -pos));
  }
};
template <class C>
int getInd(vector<C>& base, C val) {
  return lower_bound(base.begin(), base.end(), val) - base.begin();
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, q;
  cin >> n >> q;
  struct Query {
    int ind, l, r;
  };
  vector<Query> queries(q);
  vector<int> bounds(1, 0);
  for (int i = 0; i < q; i++) {
    int ind, l = 0, r = 0;
    cin >> ind;
    if (ind == 0) {
      cin >> l >> r;
      l--;
      bounds.push_back(l);
      bounds.push_back(r);
    }
    queries[i] = {ind, l, r};
  }
  sort(bounds.begin(), bounds.end());
  bounds.resize(unique(bounds.begin(), bounds.end()) - bounds.begin());
  struct Segment {
    int l, r;
    bool operator<(Segment other) const {
      if (r - l != other.r - other.l) return r - l < other.r - other.l;
      return l < other.l;
    }
  };
  struct SegmentSetPred {
    bool operator()(Segment l, Segment r) const {
      if (l.l != r.l) return l.l < r.l;
      return l.r < r.r;
    };
  };
  set<Segment, SegmentSetPred> segments;
  priority_queue<Segment> front;
  map<int, int> placement;
  Ftree ft(bounds.size() + 1);
  segments.insert({0, n});
  front.push({0, n});
  for (Query cur : queries) {
    if (cur.ind == 0)
      cout << ft.get(getInd(bounds, cur.r)) - ft.get(getInd(bounds, cur.l))
           << '\n';
    else {
      int ind = cur.ind;
      if (placement.count(ind) == 0) placement[ind] = -1;
      if (placement[ind] == -1) {
        while (segments.count(front.top()) == 0) front.pop();
        Segment seg = front.top();
        front.pop();
        segments.erase(seg);
        int pos = (seg.l + seg.r) / 2;
        segments.insert({seg.l, pos});
        segments.insert({pos + 1, seg.r});
        front.push({seg.l, pos});
        front.push({pos + 1, seg.r});
        placement[ind] = pos;
        ft.add(getInd(bounds, pos + 1), 1);
      } else {
        int pos = placement[ind];
        placement[ind] = -1;
        Segment seg;
        auto it = segments.lower_bound({pos + 1, 0});
        seg.r = it->r;
        it--;
        seg.l = it->l;
        segments.erase(it);
        segments.erase(segments.lower_bound({pos + 1, 0}));
        segments.insert(seg);
        front.push(seg);
        ft.add(getInd(bounds, pos + 1), -1);
      }
    }
  }
  return 0;
}
