#include <bits/stdc++.h>
using namespace std;
template<typename T> void umax(T &a, const T b) { a = max(a, b); }
template<typename T> void umin(T &a, const T b) { a = min(a, b); }
constexpr int MAXN = 3e5 + 10;
int head[MAXN], to[MAXN*2], nxt[MAXN*2], w[MAXN*2], ne;
int in[MAXN], out[MAXN], W[MAXN], TIME;
void add_edge(int u, int v, int weight) {
to[ne] = v;
w[ne] = weight;
nxt[ne] = head[u];
head[u] = ne++;
}
struct SegmentTree {
#define L (node<<1)
#define R (node<<1|1)
#define MID (l+r>>1)
int N;
vector<int64_t> seg;
SegmentTree(int N) : N(N) { seg.resize(N*4); }
};
void dfs(int v, int p=-1, int weight = 0) {
in[v] = TIME++;
W[v] = weight;
for (int e = head[v], u; ~e; e = nxt[e]) {
u = to[e]; if (u == p) continue;
dfs(u, v, weight^w[e]);
}
out[v] = TIME;
}
struct Trie {
struct TrieNode {
TrieNode *p0 = nullptr, *p1 = nullptr;
set<int> indices;
void add_idx(int idx) { indices.insert(idx); }
};
TrieNode *head;
Trie() { head = new TrieNode(); }
void insert(int num, int idx) {
TrieNode *curr = head;
for (int i = 30; ~i; --i) {
curr->add_idx(idx);
if ((num>>i)&1) {
if (!curr->p1) curr->p1 = new TrieNode();
curr = curr->p1;
} else {
if (!curr->p0) curr->p0 = new TrieNode();
curr = curr->p0;
}
}
curr->add_idx(idx);
}
bool check(int num, int len, int left, int right) {
TrieNode *curr = head;
for (int i = 30; ~i && len; --i, --len) {
if ((num>>i)&1) {
if (!curr->p1) return false;
curr = curr->p1;
} else {
if (!curr->p0) return false;
curr = curr->p0;
}
}
auto it = curr->indices.lower_bound(left);
if (it == curr->indices.end()) return false;
return left <= *it && *it <= right;
}
};
int main() {
cin.tie()->sync_with_stdio(false);
memset(head, -1, sizeof head);
int Q; cin >> Q;
int N = 1;
vector<array<int, 3>> queries(Q);
for (auto &q : queries) {
string s; cin >> s;
if (s == "Add") {
int x, y; cin >> x >> y;
add_edge(--x, N, y);
add_edge(N, x, y);
q = {1, x, N};
N++;
} else {
int a, b; cin >> a >> b;
q = {2, --a, --b};
}
}
Trie trie;
dfs(0);
for (auto q : queries) {
if (q[0] == 1) {
trie.insert(W[q[2]], in[q[2]]);
} else {
int ans = W[q[1]];
int target = 0;
for (int i = 30, j = 1; ~i; --i, ++j) {
int test = target;
if (!((ans>>i)&1)) test |= (1<<i);
if (trie.check(test, j, in[q[2]], out[q[2]]-1)) target = test;
else target = test ^ (1<<i);
}
cout << (ans^target) << endl;
}
}
return 0;
}