#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
int n, m, nr[26][200100], sol;
int euler[400100], adancime[400100], poz, pozitie[200100], rmq[22][400100], put[400100];
char litera[200100];
vector <int> G[200100];
bool viz[200100];
int op[100100], A[100100], B[100100];
char C[100100];

inline void DFS(int x, int tata, int lvl)
{
	for(int i = 0; i < 26; ++i)
		nr[i][x] = nr[i][tata];
	nr[litera[x] - 'a'][x]++;
	viz[x] = true;
	vector <int>::iterator it;
	for(it = G[x].begin(); it != G[x].end(); ++it)
		if(!viz[*it])
		{
			poz++;
			euler[poz] = x;
			adancime[poz] = lvl;
			DFS(*it, x, lvl + 1);
		}
	poz++;
	euler[poz] = x;
	adancime[poz] = lvl;
	pozitie[x] = poz;
}

int main()
{
	int i, k, x, y, lca, lg, now[26];
	cin >> n >> m;
	cin >> (litera + 1);
	for(i = 1; i < n; ++i)
	{
		cin >> x >> y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(i = 1; i <= m; ++i)
	{
		cin >> op[i];
		if(op[i] == 1)
			cin >> A[i] >> B[i];
		else
			cin >> A[i] >> C[i];
		if(op[i] == 2)
		{
			n++;
			litera[n] = C[i];
			G[n].push_back(A[i]);
			G[A[i]].push_back(n);
		}
	}
	DFS(1, 0, 1);
	put[1] = 0;
	for(i = 2; i <= poz; ++i)
		put[i] = put[i / 2] + 1;
	for(i = 1; i <= poz; ++i)
		rmq[0][i] = i;
	for(k = 1; (1 << k) <= poz; ++k)
	{
		int lg = (1 << (k - 1));
		for(i = 1; i + (1 << k) - 1 <= poz; ++i)
		{
			if(adancime[rmq[k - 1][i]] < adancime[rmq[k - 1][i + lg]])
				rmq[k][i] = rmq[k - 1][i];
			else
				rmq[k][i] = rmq[k - 1][i + lg];
		}
	}
	for(i = 1; i <= m; ++i)
	{
		if(op[i] == 1)
		{
			x = A[i];
			y = B[i];
			if(pozitie[x] > pozitie[y])
				swap(x, y);
			lg = pozitie[y] - pozitie[x] + 1;
			k = put[lg];
			if(adancime[rmq[k][pozitie[x]]] < adancime[rmq[k][pozitie[x] + lg - (1 << k)]])
				lca = euler[rmq[k][pozitie[x]]];
			else
				lca = euler[rmq[k][pozitie[x] + lg - (1 << k)]];
			for(int j = 0; j < 26; ++j)
				now[j] = nr[j][x] + nr[j][y];
			now[litera[lca] - 'a']++;
			sol = 0;
			for(int j = 0; j < 26; ++j)
				sol += (now[j] % 2);
			cout << sol << "\n";
		}
	}
	return 0;
}