#include <iostream>
#include <vector>
#include <algorithm>
#include <set>

#define show(x) cerr << #x << " = " << x << endl

using namespace std;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    os << "sz:" << v.size() << "\n[";
    for (const auto& p : v) {
        os << p << ",";
    }
    os << "]\n";
    return os;
}

template <typename S, typename T>
ostream& operator<<(ostream& os, const pair<S, T>& p)
{
    os << "(" << p.first << "," << p.second
       << ")";
    return os;
}


class DisjointSets
{
public:
    DisjointSets(const int v)
    {
        m_parent.resize(v);
        m_rank.resize(v);
        m_size.resize(v);
        for (int i = 0; i < v; i++) {
            m_parent[i] = i;
            m_rank[i] = 0;
            m_size[i] = 1;
        }
    }

    bool same(const int a, const int b)
    {
        return find(a) == find(b);
    }


    int find(const int a)
    {
        if (m_parent[a] == a) {
            return a;
        } else {
            return m_parent[a] = find(m_parent[a]);
        }
    }

    void unite(const int a_, const int b_)
    {
        const int a = find(a_);
        const int b = find(b_);
        if (a == b) {
            return;
        }
        if (m_rank[a] > m_rank[b]) {
            m_parent[b] = a;
            m_size[a] += m_size[b];
        } else {
            m_parent[a] = b;
            m_size[b] += m_size[a];
        }
        if (m_rank[a] == m_rank[b]) {
            m_rank[b]++;
        }
    }

    int getSize(const int a)
    {
        return m_size[m_parent[a]];
    }

private:
    vector<int> m_parent;
    vector<int> m_rank;
    vector<int> m_size;
};

struct Graph {
    Graph(const int n)
    {
        edge.resize(n);
    }
    void addEdge(const int from, const int to)
    {
        edge[from].push_back(to);
    }
    vector<vector<int>> edge;
};

void dfs(const int s, const Graph& g, const vector<bool>& marked, DisjointSets& uf, vector<int>& comp)
{
    for (const int to : g.edge[s]) {
        if (not marked[to]) {
            const int root = uf.find(s);
            uf.unite(s, to);
            comp[uf.find(s)] = comp[root];
        }
        dfs(to, g, marked, uf, comp);
    }
}

int main()
{
    while (true) {
        int N, Q;
        cin >> N >> Q;
        if (N == 0 and Q == 0) {
            break;
        }
        Graph g(N);
        vector<bool> marked(N, false);
        marked[0] = true;
        vector<int> parent(N, 0);
        for (int i = 1; i < N; i++) {
            int from;
            cin >> from;
            from--;
            parent[i] = from;
            g.addEdge(from, i);
        }

        vector<bool> visited(N, false);

        using P = pair<char, int>;
        vector<P> query;
        vector<int> comp(N, 0);
        for (int q = 0; q < Q; q++) {
            char c;
            int n;
            cin >> c >> n;
            n--;
            if (c == 'M') {
                if (marked[n]) {
                    continue;
                }
                comp[n] = n;
                marked[n] = true;
            }
            query.push_back(make_pair(c, n));
        }

        DisjointSets uf(N);
        dfs(0, g, marked, uf, comp);

        reverse(query.begin(), query.end());
        long long sum = 0;
        for (const auto& q : query) {
            if (q.first == 'M') {
                const int s = q.second;
                const int par = parent[s];
                const int root = uf.find(par);
                uf.unite(par, s);
                comp[uf.find(s)] = comp[root];
            } else {
                sum += (comp[uf.find(q.second)] + 1);
            }
        }
        cout << sum << endl;
    }
    return 0;
}

Measured memory_bytes: 28536