#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <cctype>
#include <typeinfo>
#include <algorithm>
#include <sstream>

#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <iterator>

using namespace std;

typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

#define INF 1e9
#define ll long long
#define ull unsigned long long
string s;
int target, source;
int visited[20000] = {0};
int curr_mask = 0;
int char_val[20000];
vector<vector<int> > v(20001);
int char_val_to_mask(int ch){
    return 1 << (ch - 'a');
}
void dfs(int x, int mask){
    visited[x] = 1;
    if(x == target) {
        curr_mask = mask;
        return;
    }

    for(int i=0; i<v[x].size(); ++i){
        int adj = v[x][i];
        if(!visited[adj]){
            dfs(adj, char_val[adj]^ mask);
        }
    }
}
int mask_to_res(){
    int res = 0;
    while(curr_mask>0){
        if(curr_mask & 1){ res++;}
        curr_mask>>=1;
    }
    return res;
}
int main()
{
  //  freopen("C:\\in.txt", "r", stdin);
    int n,m;
    scanf("%d %d", &n, &m);
    cin >> s;
    for(int i=0; i<s.size(); ++i){
        char_val[i] = char_val_to_mask(s[i]);
    }
    for(int i=0; i<n-1; ++i){
        int x,y;
        scanf("%d %d", &x, &y);
        x--; y--;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    int cmd;
    int new_v;
    char new_c;
    while(m--){
        scanf("%d", &cmd);
        if(cmd == 1){
            scanf("%d %d", &source, &target);
            source--; target--;
            memset(visited, 0, sizeof(visited));
            dfs(source, char_val[source]);
            printf("%d\n", mask_to_res());
        } else {
            scanf("%d %c", &new_v, &new_c);
            new_v--;
            v[new_v].push_back(n);
            v[n].push_back(new_v);
            char_val[n] = char_val_to_mask(new_c);
            n++;
        }
    }

    return 0;
}