#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 1e18, N = 2e5 + 5;
struct LCA {
vector<vector<int>> ancestor;
vector<int> level;
int LG;
LCA() {};
LCA(vector<vector<int>> &adj) {
int n = (int) adj.size();
LG = __lg(n) + 1;
ancestor.assign(LG, vector<int>(n));
level.assign(n, {});
build(1, 0, adj);
for (int i = 1; i < LG; ++i) {
for (int u = 1; u < n; ++u) {
ancestor[i][u] = ancestor[i - 1][ancestor[i - 1][u]];
}
}
}
void build(int u, int p, vector<vector<int>> &adj) {
for (auto v: adj[u]) {
if (v == p) continue;
level[v] = level[u] + 1;
ancestor[0][v] = u;
build(v, u, adj);
}
}
int KthAnc(int u, int k) {
for (int i = 0; k; ++i, k >>= 1) {
if (k & 1) u = ancestor[i][u];
}
return u;
}
int getLCA(int u, int v) {
if (level[u] > level[v]) swap(u, v);
int k = level[v] - level[u];
v = KthAnc(v, k);
if (v == u) return v;
for (int i = LG - 1; ~i; --i) {
if (ancestor[i][v] != ancestor[i][u]) {
v = ancestor[i][v];
u = ancestor[i][u];
}
}
return ancestor[0][u];
}
} T;
struct Trie_B {
struct Node {
int child[2]{};
int cnt = 0, isEnd = 0, minT = inf;
int &operator[](int x) { return child[x]; }
};
vector<pair<int, int>> val;
vector<Node> node;
Trie_B() { node.emplace_back(); }
int newNode() {
node.emplace_back();
return node.size() - 1;
}
int sz(int x) { return node[x].cnt; }
int M = 30;
void update(int x, int time, int op) { // op -> 1 add || op -> -1 erase
int cur = 0;
val.emplace_back(x, time);
for (int i = M - 1; i >= 0; --i) {
int c = x >> i & 1;
if (node[cur][c] == 0) node[cur][c] = newNode();
cur = node[cur][c];
node[cur].cnt += op;
node[cur].minT = min(time, node[cur].minT);
}
node[cur].isEnd += op;
}
int max_xor(int x, int timer) {
int cur = 0, res = 0;
for (int i = M - 1; i >= 0; --i) {
int cx = (x >> i) & 1;
int target = !cx;
int nxt = node[cur][target];
if (nxt != 0 and node[nxt].cnt > 0 and node[nxt].minT <= timer) {
res |= (1LL << i);
cur = nxt;
} else {
cur = node[cur][cx];
if (cur == 0 or node[cur].minT > timer)
return 0;
}
}
return res;
}
};
int answer[N];
vector<vector<int>> adj;
vector<int> timer, a, b;
vector<vector<array<int, 3>>> Q;
void dfs(int u, int p) {
for (auto v: adj[u]) {
if (v == p)continue;
a[v] ^= a[u];
dfs(v, u);
}
}
Trie_B go(int u, int p) {
Trie_B all;
all.update(a[u], timer[u], 1);
for (auto v: adj[u]) {
if (v == p)continue;
auto cur = go(v, u);
if (all.val.size() < cur.val.size())swap(all, cur);
for (auto [b, t]: cur.val)
all.update(b, t, 1);
}
for (auto [nd, idx, time]: Q[u]) {
int lc = T.getLCA(nd, u);
answer[idx] = all.max_xor(a[nd] ^ b[lc], time);
}
return all;
}
void solve() {
int q;
cin >> q;
adj.assign(q + 1, {});
timer.assign(q + 1, {});
a.assign(q + 1, {});
timer[1] = 0;
Q.assign(q + 1, {});
int id = 2, cnt = 1;
for (int i = 1; i <= q; ++i) {
string s;
cin >> s;
if (s[0] == 'A') {
int u, x;
cin >> u >> x;
a[id] = x;
timer[id] = i;
adj[u].emplace_back(id++);
} else {
int u, v;
cin >> u >> v;
Q[v].push_back({u, cnt++, i});
}
}
b = a;
T = LCA(adj);
dfs(1, 0);
go(1, 0);
for (int i = 1; i < cnt; ++i)
cout << answer[i] << '\n';
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
#ifdef HALZOOM
freopen("Input.txt", "r", stdin);
freopen("Output.txt", "w", stdout);
#endif
int test = 1;
// cin >> test;
for (int i = 1; i <= test; ++i) {
solve();
}
return 0;
}