import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

bool solve() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto Q = s[1];
    if (N == 0) return false;

    auto G = new int[][](N);
    auto D = new int[](N);
    auto P = new int[](N);
    P[0] = -1;

    foreach (i; 1..N) {
        auto n = readln.chomp.to!int;
        P[i] = n-1;
        G[i] ~= n-1;
        G[n-1] ~= i;
    }

    void dfs(int n, int p, int d) {
        D[n] = d;
        foreach (m; G[n]) if (m != p) dfs(m, n, d+1);
    }

    dfs(0, -1, 0);

    Tuple!(int, int)[] queries;
    auto marked = new int[](N);

    foreach (i; 1..Q+1) {
        auto t = readln.split;
        auto n = t[1].to!int - 1;
        if (t[0] == "M" && !marked[n]) {
            queries ~= tuple(0, n);
            marked[n] = i;
        } else if (t[0] == "Q") {
            queries ~= tuple(1, n);
        }
    }

    auto uf = new UnionFind(N, D);
    foreach (i; 0..N) if (!marked[i]) uf.unite(i, P[i]);
    long ans = 0;

    foreach_reverse (q; queries) {
        if (q[0] == 0) {
            uf.unite(q[1], P[q[1]]);
        } else {
            ans += uf.find(q[1]) + 1;
        }
    }

    ans.writeln;

    return true;
}

void main() {
    while (solve()) {}
}


class UnionFind {
    int N;
    int[] table;
    int[] depth;

    this(int n, int[] d) {
        N = n;
        table = new int[](N);
        fill(table, -1);
        depth = d.dup;
    }

    int find(int x) {
        return table[x] < 0 ? x : (table[x] = find(table[x]));
    }

    void unite(int x, int y) {
        if (x == -1 || y == -1) return;
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (depth[x] > depth[y]) swap(x, y);
        table[x] += table[y];
        table[y] = x;
    }
}

