// gpt
#include <bits/stdc++.h>
using namespace std;
const int MX = 2000000000;
const int N = 200000 + 5;
array<int, 2> id[N];
using U64 = unsigned long long;
static inline U64 key0(int v) { return (0ULL << 31) | (unsigned int)v; }
static inline U64 key1(int v) { return (1ULL << 31) | (unsigned int)v; }
struct TNode {
U64 key;
int l, r;
unsigned int pr;
int cnt, sz;
};
struct SegNode {
int lef, rig;
int rt;
};
vector<TNode> tr(1);
vector<SegNode> seg(2); // seg[1] is root
int C = 2;
static unsigned int rng_state = 712367821u;
static inline unsigned int rng32() {
rng_state ^= rng_state << 13;
rng_state ^= rng_state >> 17;
rng_state ^= rng_state << 5;
return rng_state;
}
static inline int getsz(int u) {
return u ? tr[u].sz : 0;
}
static inline void pull(int u) {
tr[u].sz = tr[u].cnt + getsz(tr[u].l) + getsz(tr[u].r);
}
int newTreapNode(U64 key) {
tr.push_back({key, 0, 0, rng32(), 1, 1});
return (int)tr.size() - 1;
}
void rotateLeft(int &u) {
int v = tr[u].r;
tr[u].r = tr[v].l;
tr[v].l = u;
pull(u);
pull(v);
u = v;
}
void rotateRight(int &u) {
int v = tr[u].l;
tr[u].l = tr[v].r;
tr[v].r = u;
pull(u);
pull(v);
u = v;
}
void insertKey(int &u, U64 key) {
if (!u) {
u = newTreapNode(key);
return;
}
if (tr[u].key == key) {
tr[u].cnt++;
pull(u);
return;
}
if (key < tr[u].key) {
insertKey(tr[u].l, key);
if (tr[tr[u].l].pr > tr[u].pr) rotateRight(u);
} else {
insertKey(tr[u].r, key);
if (tr[tr[u].r].pr > tr[u].pr) rotateLeft(u);
}
pull(u);
}
void eraseKey(int &u, U64 key) {
if (!u) return;
if (tr[u].key == key) {
if (tr[u].cnt > 1) {
tr[u].cnt--;
pull(u);
return;
}
if (!tr[u].l || !tr[u].r) {
u = tr[u].l ? tr[u].l : tr[u].r;
return;
}
if (tr[tr[u].l].pr > tr[tr[u].r].pr) {
rotateRight(u);
eraseKey(tr[u].r, key);
} else {
rotateLeft(u);
eraseKey(tr[u].l, key);
}
if (u) pull(u);
return;
}
if (key < tr[u].key) eraseKey(tr[u].l, key);
else eraseKey(tr[u].r, key);
if (u) pull(u);
}
int countLess(int u, U64 key) {
if (!u) return 0;
if (key <= tr[u].key) return countLess(tr[u].l, key);
return getsz(tr[u].l) + tr[u].cnt + countLess(tr[u].r, key);
}
int newSegNode() {
seg.push_back({0, 0, 0});
return C++;
}
void update(int u, int l, int r, int x, int v, int t) {
if (t == 1) {
insertKey(seg[u].rt, key0(v));
insertKey(seg[u].rt, key1(v - x + 1));
} else {
eraseKey(seg[u].rt, key0(v));
eraseKey(seg[u].rt, key1(v - x + 1));
}
if (l == r) return;
int m = l + ((r - l) >> 1);
if (x <= m) {
if (!seg[u].lef) seg[u].lef = newSegNode();
update(seg[u].lef, l, m, x, v, t);
} else {
if (!seg[u].rig) seg[u].rig = newSegNode();
update(seg[u].rig, m + 1, r, x, v, t);
}
}
int get(int u, int l, int r, int x, int y, int v, int t) {
if (!u || y < l || r < x) return 0;
if (x <= l && r <= y) {
if (t == 0) {
int totalType0 = countLess(seg[u].rt, key1(0));
return totalType0 - countLess(seg[u].rt, key0(v));
} else {
return getsz(seg[u].rt) - countLess(seg[u].rt, key1(v));
}
}
int m = l + ((r - l) >> 1);
return get(seg[u].lef, l, m, x, y, v, t)
+ get(seg[u].rig, m + 1, r, x, y, v, t);
}
void add(int l, int r) {
update(1, 0, MX, l, r, 1);
}
void remove(int l, int r) {
update(1, 0, MX, l, r, 0);
}
int cnt(int l, int r) {
if (l < 0) return 0;
return get(1, 0, MX, 0, l, r, 0);
}
int cnt_sz(int l, int r, int k) {
if (l > r) return 0;
return get(1, 0, MX, l, r, k, 1);
}
void solve() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int q, t;
cin >> q >> t;
int ID = 1;
int last = 0;
while (q--) {
int tip;
cin >> tip;
if (tip == 1) {
int a, b;
cin >> a >> b;
int l = a ^ (t * last);
int r = b ^ (t * last);
if (l > r) swap(l, r);
add(l, r);
id[ID++] = {l, r};
} else if (tip == 2) {
int rem;
cin >> rem;
int l = id[rem][0];
int r = id[rem][1];
remove(l, r);
} else {
int a, b, k;
cin >> a >> b >> k;
int l = a ^ (t * last);
int r = b ^ (t * last);
if (l > r) swap(l, r);
if (r - l + 1 < k) {
last = 0;
cout << last << '\n';
continue;
}
last = cnt(l - 1, l + k - 1) + cnt_sz(l, r - k + 1, k);
cout << last << '\n';
}
}
}
int main() {
solve();
return 0;
}