//#include<fstream> #include<iostream> #include<vector> using namespace std; typedef int var; #define fin cin #define fout cout #define mp make_pair #define pii pair<var, var> #define MAXN 400005 #define SIGMA 27 //ifstream fin("date.in"); //ofstream fout("date.out"); var PARENT[MAXN], C[MAXN][SIGMA]; var BEG[MAXN]; vector<var> G[MAXN]; vector<pii> QUERIES; bool VIZ[MAXN]; vector<var> EULER(1), DEPTH(1); var D[MAXN]; var LOG[MAXN]; var RMQ[23][MAXN], SOL[23][MAXN]; void dfs(var node, var depth) { VIZ[node] = 1; BEG[node] = EULER.size(); RMQ[0][EULER.size()] = depth; SOL[0][EULER.size()] = node; EULER.push_back(node); DEPTH.push_back(depth); for(auto vec : G[node]) { if(!VIZ[vec]) { PARENT[vec] = node; for(var i=0; i<SIGMA;i++) { C[vec][i] += C[node][i]; } dfs(vec, depth+1); RMQ[0][EULER.size()] = depth; SOL[0][EULER.size()] = node; EULER.push_back(node); DEPTH.push_back(depth); } } } void build_log_table(var maxx) { for(var i=2; i<=maxx; i++) { LOG[i] = LOG[i/2] + 1; } } void build_rmq_table(var n) { for(var i=1; (1<<i) <= n; i++) { var dt = 1<<(i-1); for(var j=1; j+(1<<i)-1 <= n; j++) { if(RMQ[i-1][j] < RMQ[i-1][j+dt]) { RMQ[i][j] = RMQ[i-1][j]; SOL[i][j] = SOL[i-1][j]; } else { RMQ[i][j] = RMQ[i-1][j+dt]; SOL[i][j] = SOL[i-1][j+dt]; } } } } var lca(var n1, var n2) { n1 = BEG[n1]; n2 = BEG[n2]; if(n1 > n2) swap(n1, n2); var lg = LOG[n2-n1+1]; if(RMQ[lg][n1] < RMQ[lg][n2-(1<<lg)+1]) { return SOL[lg][n1]; } else { return SOL[lg][n2-(1<<lg)+1]; } } int main() { var n, m; char c; var a, b, type; fin>>n>>m; for(var i=1; i<=n; i++) { fin>>c; C[i][c-'a']++; } for(var i=1; i<n; i++) { fin>>a>>b; G[a].push_back(b); G[b].push_back(a); } while(m--) { fin>>type; if(type == 1) { fin>>a>>b; QUERIES.push_back(mp(a, b)); } else { fin>>a>>c; G[a].push_back(++n); G[n].push_back(a); C[n][c-'a'] ++; } } dfs(1, 0); build_log_table(EULER.size() + 1); build_rmq_table(EULER.size() - 1); for(auto query : QUERIES) { var a = query.first, b = query.second; var lc = lca(a, b); var sum = 0; for(var i=0; i<SIGMA; i++) { sum += (C[a][i] + C[b][i] + C[lc][i] - C[PARENT[lc]][i])%2; } fout<<sum<<'\n'; } return 0; }