#include <iostream>
#include <vector>

using namespace std;

vector <char> let;
vector <vector <int> > a;
vector <int> v(1, 0);
int n, m;
bool gasitPath = false;
string pathCur;
vector <int> viz;
void read()
{
    cin >> n >> m;
    vector <int> v(1, 0);
    char c;
    for(int i = 0 ; i < n; i++)
    {
        cin >> c;
        let.push_back(c);
        a.push_back(v);
        viz.push_back(0);
    }
    int x, y;
    for(int i = 1; i < n; i++)
    {
        cin >> x >> y;
        x--;
        y--;
        a[x][0]++;
        a[y][0]++;
        a[x].push_back(y);
        a[y].push_back(x);
    }
}


void update(int x, char c)
{
    n++;
    let.push_back(c);
    a.push_back(v);
    a[x][0]++;
    a[x].push_back(n-1);
    a[n-1][0]++;
    a[n-1].push_back(x);
    viz.push_back(0);
}

void dfs(int x, int caut, string path){
    viz[x]=1;
    path.push_back(let[x]);
    for (int i=1; i<=a[x][0]; ++i){
        if(a[x][i] == caut)
        {
            gasitPath = true;
            pathCur = path;
            return;
        }
        if (!viz[a[x][i]] && !gasitPath) dfs(a[x][i], caut, path);
    }
}

int compPath(string s)
{
    int ret = 0;
    vector <int> frec(26, 0);
    for(int i = 0; i < s.size(); i++)
    {
        frec[s[i] - 'a']++;
    }
    for(int i = 0 ; i < 26; i++)
    {
        if(frec[i]%2) ret++;
    }
    return ret;
}

int main()
{
    read();
    int t, x, y;
    char c;
    for(int i = 0 ; i < m; i++)
    {
        cin >> t;
        if(t == 1)
        {
            cin >> x >> y;
            x--;
            y--;
            gasitPath = false;
            pathCur = "";
            for(int i = 0; i < n; i++) viz[i] = 0;
            dfs(x, y, "");
            pathCur.push_back(let[y]);
            //cout << pathCur << endl;
            cout << compPath(pathCur);

        }
        else
        {
            cin >> x >> c;
            x--;
            update(x, c);
        }
    }
}