#pragma comment(linker, "/stack:200000000") #pragma GCC optimize("Ofast") #include #define UINT unsigned int #define LL long long int #define ULL unsigned LL #define LD long double #define FI first #define SE second #define PB push_back #define PF push_front #define V vector #define PQ priority_queue #define ALL(x) x.begin(), x.end() #define SZ(x) (int)(x).size() #define FORI(i, a, b) for(int i = a; i < b ; ++i) #define FORD(i, a, b) for(int i = a; i > b ; --i) using namespace std; using pii = pair; const clock_t START_T = clock(); double time_running(){ return (double)(clock() - START_T) / CLOCKS_PER_SEC; } const int N = 2e4; V t(8*N, 0); void update(int v, int tl, int tr, int l, int r, int add){ if (l > r) return; if (l == tl && tr == r) t[v] ^= add; else { int tm = (tl + tr) / 2; update (v*2, tl, tm, l, min(r,tm), add); update (v*2+1, tm+1, tr, max(l,tm+1), r, add); } } int get(int v, int tl, int tr, int pos){ if (tl == tr) return t[v]; int tm = (tl + tr) / 2; if (pos <= tm) return t[v] ^ get (v*2, tl, tm, pos); else return t[v] ^ get (v*2+1, tm+1, tr, pos); } void root(int v, V& parent, const V>& edg, V& tin, V& tout, int& timer){ tin[v] = timer++; for(auto u: edg[v]){ if (u != parent[v]){ parent[u] = v; root(u, parent, edg, tin, tout, timer); } } tout[v] = timer++; } int main(){ ifstream cin("xor.in"); ofstream cout("xor.out"); mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int n, q, timer = 0; cin >> n >> q; V x(n), parent(n, -1), tin(n), tout(n); FORI(i,0,n){ cin >> x[i]; } V> edg(n); FORI(_,1,n){ int u, v; cin >> u >> v; edg[--u].PB(--v); edg[v].PB(u); } root(0, parent, edg, tin, tout, timer); FORI(i,0,n){ // cout << tin[i] << ' ' << tout[i] << endl; update(1, 0, timer-1, tin[i], tout[i], x[i]); } FORI(_,0,q){ int t, v; cin >> t >> v; --v; if (t == 1){ update(1, 0, timer-1, tin[v], tout[v], x[v]); cin >> x[v]; update(1, 0, timer-1, tin[v], tout[v], x[v]); } else { cout << get(1, 0, timer-1, tin[v]) << '\n'; } } // cerr << time_running() << endl; return 0; }