#include "bits/stdc++.h"

#pragma warning(disable:4996)
using namespace std;
#define Seg_Max_N (1<<18) 

namespace lca_tree {

	class Tree {
	public:
		Tree(int V, int root) : root(root), cnum(V), place(V), id(V) {
			T.resize(V);
			for (int i = 0; i < MAXLOGV; i++) {
				parent[i].resize(V);
			}
			depth.resize(V);
		}

		// initする
		void init(const vector<vector<int>>&e) {
			T=e;
			dfs(root, 0, 0);
			int id = 0;
			getid(root, 0, id);
		}
		// uとvのlcaを求める
		int lca(int u, int v) const {
			if (depth[u] > depth[v]) swap(u, v);
			for (int k = 0; k < MAXLOGV; k++) {
				if ((depth[v] - depth[u]) >> k & 1) {
					v = parent[k][v];
				}
			}
			if (u == v) return u;
			for (int k = MAXLOGV - 1; k >= 0; k--) {
				if (parent[k][u] != parent[k][v]) {
					u = parent[k][u];
					v = parent[k][v];
				}
			}
			return parent[0][u];
		}
		//// uとvの距離を求める
		//// edgeを定義しないといけない時はこれじゃダメ
		int dist(int u, int v) const {
			int p = lca(u, v);
			return (depth[u] - depth[p]) + (depth[v] - depth[p]);
		}
		int dfs(int v, int p, int d) {
			parent[0][v] = p;
			depth[v] = d;
			cnum[v] = 0;
			for (int i = 1; i < MAXLOGV; i++) {
				parent[i][v] = parent[i - 1][parent[i - 1][v]];
			}
			for (int next : T[v]) {
				if (next != p) cnum[v] += dfs(next, v, d + 1);
			}
			return cnum[v] + 1;
		}

		//void dfs2(int v, int p, vector<vector<int>>&doubles, const vector<int>&nums) {
		//	for (int next : T[v]) {
		//		if (next != p) dfs2(next, v, doubles, nums);
		//	}
		//	doubles[0][v] = nums[v];
		//	for (int j = 1; j < MAXLOGV; ++j) {
		//		doubles[j][v] = min(doubles[j][v], doubles[j - 1][v]);
		//	}
		//	for (int j = 0; j < MAXLOGV - 1; ++j) {
		//		doubles[j + 1][parent[j][v]] = min(doubles[j + 1][parent[j][v]], doubles[j][v]);
		//	}
		//}
		////ここでは親から距離2^iの部分木の最小値を求めている
		//vector<vector<int>>get_doubles(const vector<int>&nums) {
		//	vector<vector<int>>doubles(MAXLOGV, vector<int>(V, 1e9));
		//	dfs2(root, -1, doubles, nums);
		//	return doubles;
		//}

		void getid(const int v, const int p, int &nplace) {
			place[v] = nplace;
			id[nplace] = v;
			nplace++;
			for (int next : T[v]) {
				if (next != p) getid(next, v, nplace);
			}
		}
		static const int MAXLOGV = 25;
		// グラフの隣接リスト表現
		vector<vector<int> > T;

		// 根ノードの番号
		int root;

		// 親ノード
		vector<int> parent[MAXLOGV];
		// 根からの深さ
		vector<int> depth;

		//子の数
		vector<int>cnum;

		//変換
		vector<int>place;
		vector<int>id;

	};
	//
	////rootを根に,幅優先探索でIDを振っていく。
	////返り値はtos 
	//vector<int> get_width_tos(const vector<vector<int>>&edges, int root) {
	//	vector<int>tos(edges.size());
	//	queue<int>que;
	//	que.push(root);
	//	vector<int>flags(edges.size());
	//	int nid = 0;
	//	while (!que.empty()) {
	//		const int now(que.front());
	//		que.pop();
	//		tos[now] = nid++;
	//		flags[now] = true;
	//		for (auto e : edges[now]) {
	//			if (flags[e]) {
	//			}
	//			else {
	//				que.push(e);
	//			}
	//		}
	//	}
	//	return tos;
	//}
	//ls と　rs を求める。
	void dfs(vector<int>&ls, vector<int>&rs, int &a,
		const vector<vector<int>>&edges, int now, int from) {
		ls[now] = a;
		a++;

		for (auto e : edges[now]) {
			if (e == from)continue;
			dfs(ls, rs, a, edges, e, now);
		}
		rs[now] = a;
	}
	vector<int>mp;
	vector<int>rev_mp;
	vector<int>ls, rs;
	vector<vector<int>>solve(
		const vector<vector<int>>&edges, const int root) {
		ls.resize(edges.size());
		rs.resize(edges.size());

		int a = 0;
		dfs(ls, rs, a, edges, root, -1);
		mp.resize(edges.size());
		rev_mp.resize(edges.size());

		vector<vector<int>>newedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto e : edges[i]) {
				newedges[ls[i]].push_back(ls[e]);
			}
		}
		mp = ls;
		for (int i = 0; i < edges.size(); ++i) {
			rev_mp[ls[i]] = i;
		}
		vector<int>new_rs(edges.size());
		vector<int>new_ls(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			new_ls[ls[i]] = ls[i];
			new_rs[ls[i]] = rs[i];
		}
		ls = new_ls;
		rs = new_rs;
		return newedges;
	}
}
struct query {
	int id;
	int place;
	int plus;
};
int main() {
	int N;cin>>N;
	vector<vector<int>>graph(N);
	for (int i = 0; i < N-1; ++i) {
		int u,v;cin>>u>>v;u--;v--;
		graph[u].push_back(v);
		graph[v].push_back(u);

	}
	using namespace lca_tree;
	graph=solve(graph,0);
	vector<int>colors(N);


	vector<vector<pair<int,int>>>qs(100000);
	for (int i = 0; i < N; ++i) {
		int c;cin>>c;c--;
		qs[c].push_back(make_pair(mp[i],1));
		colors[mp[i]]=c;
	}
	int Q; cin >> Q;

	for (int i = 0; i < Q;++i) {
		char ch;cin>>ch;
		if (ch == 'U') {
			int x,y;cin>>x>>y;
			x--;y--;
			x=mp[x];
			qs[colors[x]].push_back(make_pair(x,-1));
			qs[y].push_back(make_pair(x,1));
			colors[x]=y;
		}
		else {
			int y;cin>>y;
			y--;
			qs[y].push_back(make_pair(-1,i));
		}
	}
	Tree t(N,0);
	t.init(graph);
	map<int,int>ans_mp;
	for (int i = 0; i < 100000; ++i) {
		auto qq(qs[i]);
		int nans=-1;
		set<int>color_place_set;
		int lca_root=-1;
		for (auto q : qq) {
			if (q.first == -1) {
				ans_mp[q.second]=nans;
			//	cout<<i<< " "<<nans<<endl;
			}
			else {
				if (q.second == 1) {
					if (color_place_set.empty()) {
						nans=0;
						color_place_set.emplace(q.first);
						lca_root=q.first;
					}
					else {
						assert(color_place_set.find(q.first)==color_place_set.end());
						int next_lca_root=t.lca(lca_root,q.first);
						if (lca_root != next_lca_root) {
							nans+=t.dist(q.first,lca_root);
						}
						else {
							auto it=color_place_set.lower_bound(q.first);
							int aroot=-1;
							if (it != color_place_set.begin()) {
								int prev_place=*prev(it);
								aroot=t.lca(q.first,prev_place);
							}
							if (it != color_place_set.end()) {
								int nex_place=*it;
								if(aroot==-1)aroot=t.lca(q.first,nex_place);
								else {
									if (t.depth[aroot] < t.depth[t.lca(q.first, nex_place)]) {
										aroot=t.lca(q.first,nex_place);
									}
								}
							}
							nans+=t.dist(q.first,aroot);
						}

						lca_root=next_lca_root;
						color_place_set.emplace(q.first);

					}
				}
				else {
					assert(q.second==-1);
					if (color_place_set.size() == 1) {
						color_place_set.clear();
						nans=-1;
					}
					else {
						auto it = color_place_set.lower_bound(q.first);
						assert(color_place_set.find(q.first)!=color_place_set.end());
						int al = -1, ar = -1;
						if (it == color_place_set.begin()) {
							al = *next(color_place_set.begin());
							ar = *prev(color_place_set.end());
						}
						else if (it == prev(color_place_set.end())) {
							al = *color_place_set.begin();
							ar = *prev(prev(color_place_set.end()));
						}
						int next_lca_root = -1;
						if (al != -1) {
							next_lca_root = t.lca(al, ar);
							if (next_lca_root != lca_root) {
								nans -= t.dist(q.first, next_lca_root);
								lca_root = next_lca_root;
								color_place_set.erase(it);
								continue;
							}

						}
						 
						{
							int aroot = -1;
							if (it != color_place_set.begin()) {
								int prev_place = *prev(it);
								aroot = t.lca(q.first, prev_place);
							}
							if(next(it)!=color_place_set.end()){
								int nex_place = *(next(it));
									if(aroot!=-1){
									if (t.depth[aroot] < t.depth[t.lca(q.first, nex_place)]) {
										aroot = t.lca(q.first, nex_place);
									}
									}
									else {
										aroot=t.lca(q.first,nex_place);
									}
							}
							nans -= t.dist(q.first, aroot);
						}

						color_place_set.erase(it);

					}
					
				}
				
			}
		}
		
	}

	for (auto m : ans_mp) {
		cout<<m.second<<endl;
	}

	return 0;
}
