#include #define endl '\n' using namespace std; ifstream fin("xor.in"); ofstream fout("xor.out"); const int maxn = 2e4+2; int n, q, st[maxn], a[2*maxn], in[maxn], out[maxn], pos = 0, t[8*maxn]; bool used[maxn]; vector v[maxn]; void read() { ios_base::sync_with_stdio(false); fin.tie(NULL); fout.tie(NULL); fin >> n >> q ; int i, x, y; for (i=1; i<=n; ++i) fin >> st[i] ; for (i=1; i> x >> y ; v[x].push_back(y); v[y].push_back(x); } } void dfs(int ver) { used[ver] = true; a[(++pos)] = ver; in[ver] = pos; int j, len = v[ver].size(); for (j=0; j> 1; make_tree(2*i, l, mid); make_tree(2*i+1, mid+1, r); t[i] = (t[2*i] ^ t[2*i+1]); } void update(int i, int l, int r, int&idx, int&val) { if (l == r) { t[i] = val; return; } int mid = (l+r) >> 1; if (idx <= mid) update(2*i, l, mid, idx, val); else update(2*i+1, mid+1, r, idx, val); t[i] = (t[2*i] ^ t[2*i+1]); } int query(int i, int l, int r, int ql, int qr) { if (ql == l && qr == r) return t[i]; int mid = (l+r) >> 1; if (qr <= mid) return query(2*i, l, mid, ql, qr); if (ql > mid) return query(2*i+1, mid+1, r, ql, qr); return (query(2*i, l, mid, ql, mid) ^ query(2*i+1, mid+1, r, mid+1, qr)); } void solve() { dfs(1); make_tree(1, 1, (2*n)); int i, type, idx, val, node, ql, qr; for (i=1; i<=q; ++i) { fin >> type >> node; if (type == 1) { fin >> val ; idx = in[node]; update(1, 1, (2*n), idx, val); idx = out[node]; update(1, 1, (2*n), idx, val); } else { ql = 1, qr = in[node]; fout << query(1, 1, (2*n), ql, qr) << '\n' ; } } } int main() { read(); solve(); return 0; }