// fast map
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template <typename T>
using o_set = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
const int MX = 2e9;
const int N = 2e5 + 5;
array<int, 2> id[N];
/// 🔥 fast hash
struct chash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
unordered_map<int, int, chash> lef, rig;
unordered_map<int, o_set<int>, chash> mst, mst2;
int C = 2;
void update(int u, int l, int r, int x, int v, int t) {
if (t == 1) {
mst[u].insert(v);
mst2[u].insert(v - x + 1);
} else {
auto it = mst[u].lower_bound(v - 1);
if (it != mst[u].end()) mst[u].erase(it);
auto it2 = mst2[u].lower_bound(v - x + 1 - 1);
if (it2 != mst2[u].end()) mst2[u].erase(it2);
}
if (l == r) return;
int m = (l + r) >> 1;
if (x <= m) {
if (!lef[u]) lef[u] = C++;
update(lef[u], l, m, x, v, t);
} else {
if (!rig[u]) rig[u] = C++;
update(rig[u], m + 1, r, x, v, t);
}
}
bool cross(int l1, int r1, int l2, int r2) {
return !(r1 < l2 || r2 < l1);
}
int get(int u, int l, int r, int x, int y, int v, int t) {
if (!u || y < l || x > r) return 0;
if (x <= l && r <= y) {
if (!t) {
auto it = mst[u].lower_bound(v - 1);
if (it == mst[u].end()) return 0;
int idx = mst[u].order_of_key(*it);
return mst[u].size() - idx;
} else {
auto it = mst2[u].lower_bound(v - 1);
if (it == mst2[u].end()) return 0;
int idx = mst2[u].order_of_key(*it);
return mst2[u].size() - idx;
}
}
int m = (l + r) >> 1;
int res = 0;
if (cross(l, m, x, y)) {
if (!lef[u]) lef[u] = C++;
res += get(lef[u], l, m, x, y, v, t);
}
if (cross(m + 1, r, x, y)) {
if (!rig[u]) rig[u] = C++;
res += get(rig[u], m + 1, r, x, y, v, t);
}
return res;
}
void add(int l, int r) {
update(1, 1, MX, l, r, 1);
}
void remove(int l, int r) {
update(1, 1, MX, l, r, 0);
}
int cnt(int l, int r) {
return get(1, 1, MX, 1, l, r, 0);
}
int cnt_sz(int l, int r, int k) {
return get(1, 1, MX, l, r, k, 1);
}
void solve() {
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};
continue;
}
if (tip == 2) {
int rem;
cin >> rem;
int l = id[rem][0];
int r = id[rem][1];
remove(l, r);
continue;
}
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 << 0 << '\n';
continue;
}
last = cnt(l - 1, l + k - 1) + cnt_sz(l, r - k + 1, k);
cout << last << '\n';
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
/// 🚀 prevent rehash
lef.reserve(1 << 20);
rig.reserve(1 << 20);
mst.reserve(1 << 20);
mst2.reserve(1 << 20);
lef.max_load_factor(0.7);
rig.max_load_factor(0.7);
mst.max_load_factor(0.7);
mst2.max_load_factor(0.7);
solve();
}