//#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;
}