#pragma GCC optimize("Ofast,unroll-loops,inline,fast-math")
#pragma GCC target("avx,avx2,fma")
/*__stO_stO_stO_stO_stO_stO_stO_zit_Orz_Orz_Orz_Orz_Orz_Orz_Orz__*/
#include<bits/stdc++.h>
using namespace std;
#define name "zit"
using ll = int ;const ll MOD2=998244353;
#define all(x,y) x.begin()+1, x.begin()+y+1
#define FOR(i,a,b) for(ll i=(a);i<=(b);++i)
using vl=vector<ll>; using pll=pair<ll,ll>;
const int maxn=2e5+1, MOD=1e9+7;// __ c:
#define pb push_back// zit#6421 <(o )____|
const long long INF = 2e18;ll n;//( ._> /|
#define All(x) x.begin(),x.end()/* `----'*/
#define stop assert(0||!(cerr<<"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"));
#define ok cerr << "if u see this line , then ur code worked orz\n"
#define pr(orz) copy(orz,ostream_iterator<ll>(cerr," "));cerr<<'\n'
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
#define el cerr<<'\n'
const ll lg = 30;
struct Node {
ll min_time;
// neu query t >= min_time thi luc toi t thi node tren trie nay da ton tai
Node *child[2];
Node () : min_time (MOD) {
child[0] = child[1] = nullptr;
}
};
struct Trie {
Node *R = new Node ();
vector <pll> val;
void add (ll x, ll time) {
val.pb ({x, time});
Node *cur_root = R;
for (ll j = lg; j >= 0; --j) {
if (cur_root -> child[x >> j & 1] == nullptr)
cur_root -> child[x >> j & 1] = new Node ();
cur_root = cur_root -> child[x >> j & 1];
cur_root -> min_time = min (cur_root -> min_time, time);
}
}
ll get (ll x, ll time) {
ll ans = x;
Node *cur_root = R;
for (ll j = lg; j >= 0; --j) {
ll cur_bit = x >> j & 1;
ll best = cur_bit ^ 1;
if (cur_root -> child[best] != nullptr && cur_root -> child[best] -> min_time <= time) {
// neu time >= child.min_time thi da ton tai child nay -> di dc xuong child nay
cur_root = cur_root -> child[best];
ans ^= (best << j);
}
else cur_root = cur_root -> child[cur_bit],
ans ^= (cur_bit << j);
}
return ans;
}
};
struct qurey {
ll a, time, id;
}; vector <qurey> q[maxn];
vl ans_query (maxn + 5, -67676767);
struct Edge {
ll v, w;
}; vector <Edge> adj[maxn];
vl par (maxn), time_v (maxn), h (maxn, 0);
void dfs (ll u = 1) {
for (auto & x : adj[u]) if (x.v != par[u]) {
par[x.v] = u;
h[x.v] = (h[u] ^ x.w);
dfs (x.v);
}
}
void merge (Trie & A, Trie & B) {
if (A.val.size () < B.val.size ()) swap (A, B);
for (pll & X : B.val)
A.add (X.first, X.second);
}
Trie trie[maxn];
void dfs2 (ll u = 1) {
trie[u].add (h[u], time_v[u]);
for (auto & x : adj[u]) if (x.v != par[u]) {
dfs2 (x.v);
merge (trie[u], trie[x.v]);
}
for (qurey & X : q[u]) {
ll a = X.a, time = X.time, id = X.id;
ans_query[id] = trie[u].get (h[a], time);
}
}
void sibidi () {
ll Q; cin >> Q;
n = 1;
time_v[n] = 0;
ll cnt_q = 0;
FOR (i,1,Q) {
string type; cin >> type;
if (type == "Add") {
time_v[++n] = i;
ll x, y; cin >> x >> y;
adj[n].pb ({x, y});
adj[x].pb ({n, y});
}
else {
ll a, b; cin >> a >> b;
q[b].pb ({a, i, ++ cnt_q});
}
}
dfs (); dfs2 ();
FOR (i,1,cnt_q) {
cout << ans_query[i] << '\n';
}
} signed main() {
if(fopen(name".inp","r"))
{freopen(name".inp","r",stdin);freopen(name".out","w",stdout);}
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);ll _=1;
//cin>>_;
while(_--)sibidi();return 0;}