#include using namespace std; inline void xor_letter(int &x, char l) { int bit = l - 'a'; x ^= (1 << bit); } inline int nr_bits(int x) { int bits = 0; while (x) { x = x & (x - 1); bits++; } return bits; } const int NMAX = 200005; int LG[NMAX << 1]; int First[NMAX]; int RMQ[NMAX << 1][23]; int EulerLvl[NMAX << 1]; int EulerTour[NMAX << 1]; int D[NMAX], NodeValue[NMAX]; int Mark[NMAX]; vector A[NMAX]; int Pos = 0, N, M; void EulerTraversal(int x, int depth) { EulerTour[++Pos] = x; EulerLvl [Pos] = depth; First [x] = Pos; for ( vector::iterator it = A[x].begin(); it != A[x].end(); ++it ) { if (First[*it]) continue; EulerTraversal(*it, depth + 1); EulerTour[++Pos] = x; EulerLvl [Pos] = depth; } } void BuildD(int x, int parent) { Mark[x] = true; D[x] ^= D[parent] ^ NodeValue[parent]; for (vector::iterator it = A[x].begin(); it != A[x].end(); it++) { if (Mark[*it]) { continue; } BuildD(*it, x); } } void BuildRMQ() { LG[1] = 0; for ( int i = 2; i <= Pos; i++ ) LG[i] = LG[i/2] + 1; for ( int i = 1; i <= Pos; i++ ) { RMQ[i][0] = i; } for ( int j = 1; (1 << j) <= Pos; j++ ) { for ( int i = 1; i + (1 << (j-1)) <= Pos; i++ ) { RMQ[i][j] = RMQ[i][j-1]; if (EulerLvl[RMQ[i + (1 << (j-1))][j-1]] < EulerLvl[RMQ[i][j]]) { RMQ[i][j] = RMQ[i + (1 << (j-1))][j-1]; } } } } inline int LCA(int x, int y) { int xPos = First[x], yPos = First[y]; if (xPos > yPos) { int tmp = xPos; xPos = yPos; yPos = tmp; } int L = LG[yPos - xPos + 1]; int sol = RMQ[xPos][L]; if (EulerLvl[RMQ[yPos - (1 << L) + 1][L]] < EulerLvl[RMQ[xPos][L]]) { sol = RMQ[yPos - (1 << L) + 1][L]; } return EulerTour[sol]; } char Letters[NMAX]; struct Query { int t, x, y; Query(int t, int x, int y) : t(t), x(x), y(y) {} }; vector Q; int main() { cin >> N >> M; cin >> Letters + 1; for (int i = 1; i <= N; i++) { xor_letter(NodeValue[i], Letters[i]); } for (int i = 1, x, y; i < N; i++) { cin >> x >> y; A[x].push_back(y); A[y].push_back(x); } for (int i = 1, t, x, y; i <= M; i++) { cin >> t; if (t == 2) { ++N; cin >> x >> Letters[N]; A[x].push_back(N); A[N].push_back(x); xor_letter(NodeValue[N], Letters[N]); } else { cin >> x >> y; Q.push_back(Query(t, x, y)); } } BuildD(1, 0); EulerTraversal(1, 0); BuildRMQ(); for (vector::iterator it = Q.begin(); it != Q.end(); ++it) { if (it->t == 1) { int lca = LCA(it->x, it->y); int result = D[it->x] ^ D[it->y] ^ NodeValue[it->x] ^ NodeValue[it->y] ^ NodeValue[lca]; cout << nr_bits(result) << endl; } } return 0; }