#include <fstream>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
using namespace std;
const int nmax = int(3e5);
struct node {
multiset<int> s;
vector<int> upin, upout;
};
vector<node> a;
void updatein(int node,int l,int r,int x,int y, int z) {
if (r < x || l > y) return;
if (x <= l && r <= y) {
a[node].s.insert(z);
a[node].upin.push_back(z);
return;
}
int ls = node << 1;
int rs = ls + 1;
int mid = (l + r) >> 1;
updatein( ls, l, mid, x, y, z);
updatein( rs, mid + 1, r, x, y, z);
}
void updateout(int node,int l,int r,int x,int y, int z) {
if (r < x || l > y) return;
if (x <= l && r <= y) {
a[node].s.erase(z);
a[node].upout.push_back(z);
return;
}
int ls = node << 1;
int rs = ls + 1;
int mid = (l + r) >> 1;
updateout( ls, l, mid, x, y, z);
updateout( rs, mid + 1, r, x, y, z);
}
int query(int node,int l,int r,int x) {
if (l == r) {
return a[node].s.empty() ? 0 : (*a[node].s.begin());
}
int ls = node << 1;
int rs = ls + 1;
int mid = (l + r) >> 1;
if (!a[node].upin.empty() || !a[node].upout.empty()) {
for (int& x : a[node].upin) {
a[ls].upin.push_back(x);
a[rs].upin.push_back(x);
a[ls].s.insert(x);
a[rs].s.insert(x);
}
for (int& x : a[node].upout) {
a[ls].upout.push_back(x);
a[rs].upout.push_back(x);
a[ls].s.erase(x);
a[rs].s.erase(x);
}
a[node].upin.clear();
a[node].upout.clear();
}
if (x <= mid)
return query(ls, l, mid, x);
return query(rs, mid + 1, r, x);
}
int main() {
ifstream cin("invazia.in");
ofstream cout("invazia.out");
int N, M;
cin >> N >> M;
int p = 1;
while ( p <= N) {
p <<= 1;
}
p <<= 1;
a.resize(p);
char c;
int x, y, z;
vector< tuple<int,int,int> > st;
while (M--) {
cin >> c;
if (c == 'I') {
cin >> x >> y >> z;
st.push_back(make_tuple(x, y, z));
updatein(1, 1, N, x, y, z);
} else
if (c == 'E') {
tie(x, y, z) = st.back();
st.pop_back();
updateout(1, 1, N, x, y, z);
} else
if (c == 'R') {
cin >> x;
cout << query(1, 1, N, x) << "\n";
}
}
return 0;
}