#include <bits/stdc++.h>

using namespace std;

inline void xor_letter(int &x, char l) {
    int bit = l - 'a';

    x ^= (1 << bit);
}

inline int nr_bits(int x) {
    int bits = 0;
    while (x) {
        x = x & (x - 1);
        bits++;
    }

    return bits;
}

const int NMAX = 200005;

int LG[NMAX << 1];
int First[NMAX];
int RMQ[NMAX << 1][23];
int EulerLvl[NMAX << 1];
int EulerTour[NMAX << 1];
int D[NMAX], NodeValue[NMAX];
int Mark[NMAX];
vector<int> A[NMAX];

int Pos = 0, N, M;

void EulerTraversal(int x, int depth) {
    EulerTour[++Pos] = x;
    EulerLvl [Pos] = depth;
    First    [x] = Pos;

    for ( vector<int>::iterator it = A[x].begin(); it != A[x].end(); ++it ) {
        if (First[*it])
            continue;

        EulerTraversal(*it, depth + 1);

        EulerTour[++Pos] = x;
        EulerLvl [Pos] = depth;
    }
}

void BuildD(int x, int parent) {
    Mark[x] = true;
    D[x] ^= D[parent] ^ NodeValue[parent];

    for (vector<int>::iterator it = A[x].begin(); it != A[x].end(); it++) {
        if (Mark[*it]) {
            continue;
        }

        BuildD(*it, x);
    }
}

void BuildRMQ() {
    LG[1] = 0;
    for ( int i = 2; i <= Pos; i++ )
        LG[i] = LG[i/2] + 1;

    for ( int i = 1; i <= Pos; i++ ) {
        RMQ[i][0] = i;
    }

    for ( int j = 1; (1 << j) <= Pos; j++ ) {
        for ( int i = 1; i + (1 << (j-1)) <= Pos; i++ ) {
            RMQ[i][j] = RMQ[i][j-1];

            if (EulerLvl[RMQ[i + (1 << (j-1))][j-1]] < EulerLvl[RMQ[i][j]]) {
                RMQ[i][j] = RMQ[i + (1 << (j-1))][j-1];
            }
        }
    }
}

inline int LCA(int x, int y) {
    int xPos = First[x],
        yPos = First[y];

    if (xPos > yPos) {
        int tmp = xPos;
        xPos = yPos;
        yPos = tmp;
    }

    int L = LG[yPos - xPos + 1];

    int sol = RMQ[xPos][L];

    if (EulerLvl[RMQ[yPos - (1 << L) + 1][L]] < EulerLvl[RMQ[xPos][L]]) {
        sol = RMQ[yPos - (1 << L) + 1][L];
    }

    return EulerTour[sol];
}

char Letters[NMAX];

struct Query {
    int t, x, y;

    Query(int t, int x, int y) : t(t), x(x), y(y) {}
};

vector<Query> Q;

int main() {
#if 1
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    cin >> N >> M;
    cin >> Letters + 1;

    for (int i = 1; i <= N; i++) {
        xor_letter(NodeValue[i], Letters[i]);
    }

    for (int i = 1, x, y; i < N; i++) {
        cin >> x >> y;
        A[x].push_back(y);
        A[y].push_back(x);
    }

    for (int i = 1, t, x, y; i <= M; i++) {
        cin >> t;

        if (t == 2) {
            ++N;
            cin >> x >> Letters[N];
            A[x].push_back(N);
            A[N].push_back(x);

            xor_letter(NodeValue[N], Letters[N]);
        } else {
            cin >> x >> y;
            Q.push_back(Query(t, x, y));
        }
    }

    BuildD(1, 0);
    EulerTraversal(1, 0);
    BuildRMQ();

    for (vector<Query>::iterator it = Q.begin(); it != Q.end(); ++it) {
        if (it->t == 1) {
            int lca = LCA(it->x, it->y);
            int result = D[it->x] ^ D[it->y] ^ NodeValue[it->x] ^ NodeValue[it->y] ^ NodeValue[lca];

            cout << nr_bits(result) << endl;
        }
    }


    return 0;
}