#include #include #include #include #define Nmax 200005 #define pb push_back using namespace std; vector A[100005]; struct { int vecin; int value; unsigned int vect; } dp[Nmax][25]; char letters[Nmax]; int n, m; int tata[Nmax]; int level[Nmax]; int currentNode; bool isSet(unsigned int X, int bit) { return X & (1 << bit); } void changeVal (unsigned int &X, int bit) { if (isSet (X, bit)) { X = X & (~(1<=0; i--) { if (dp[x][i].vecin != 0 && dp[x][i].vecin != dp[y][i].vecin) { rezx ^= dp[x][i].vect; rezy ^= dp[y][i].vect; x = dp[x][i].vecin; y = dp[y][i].vecin; } } int v = tata[x]; rezx^= dp[x][0].vect; rezy^= dp[y][0].vect; rezx ^= rezy; changeVal (rezx, letters[v] - 'a'); } for (int i = 0; i <26; i++) if (isSet(rezx, i)) rez++; return rez; } int main() { //freopen ("fis.in", "r", stdin); //freopen ("fis.out", "w", stdout); scanf ("%d %d", &n, &m); currentNode = n+1; scanf ("%s", letters+1); for (int i = 1; i < n; i++) { int x, y; scanf ("%d %d\n", &x, &y); tata[y] = x; A[x].pb(y); A[y].pb(x); } for (int i = 1; i <=n; i++) if (tata[i] == 0) DFS(i, 1); for (int i = 1; i <= n; i++) { if (tata[i] != 0) { dp[i][0].vecin = tata[i]; changeVal(dp[i][0].vect, letters[i] - 'a'); dp[i][0].value = 1; } } for (int j = 1; j <= 20; j++) { for (int i = 1; i <= n; i++) { if (dp[i][j-1].vecin != 0 && dp[dp[i][j-1].vecin][j-1].vecin != 0) { dp[i][j].vecin = dp[dp[i][j-1].vecin][j-1].vecin; dp[i][j].vect = dp[i][j-1].vect ^ dp[dp[i][j-1].vecin][j-1].vect; int nr = 0; for (int k = 0; k < 26; k++) if (isSet ( dp[i][j].vect, k)) { nr ++; } dp[i][j].value = nr; } } } for (int i = 1; i <=m; i++) { int c, x, y; char let; scanf ("%d", &c); if (c == 1) { scanf ("%d %d", &x, &y); printf ("%d\n", query (x, y)); } if (c == 2) { scanf ("%d %c\n", &x, &let); update (x, let); } } return 0; }