//#define _GLIBCXX_DEBUG
#include "bits/stdc++.h"

using namespace std;

//------------------------------- Type Names -------------------------------//

using i64 = int_fast64_t;

using seika = string;
//{akari : 1D, yukari : 2D, maki : 3D} vector
template <class kizuna>
using akari = vector<kizuna>;
template <class yuzuki>
using yukari = akari<akari<yuzuki>>;
template <class tsurumaki>
using maki = akari<yukari<tsurumaki>>;
//{akane : ascending order, aoi : decending order} priority queue
template <class kotonoha>
using akane = priority_queue<kotonoha, akari<kotonoha>, greater<kotonoha>>;
template <class kotonoha>
using aoi = priority_queue<kotonoha>;

//------------------------------- Libraries ---------------------------------//

class RollingHash
{
    /*
        Reference:https://qiita.com/keymoon/items/11fac5627672a6d6a9f6
    */
public:
    //must be 64bit
    using yuzuki = uint_fast64_t;

    static const yuzuki base = 10009;
    static const yuzuki mod = (1ULL << 61) - 1;
    static const yuzuki MASK30 = (1ULL << 30) - 1;
    static const yuzuki MASK31 = (1ULL << 31) - 1;
    static const yuzuki SUP = mod * 3ULL;

    vector<yuzuki> hashed, powmemo;

    inline yuzuki mul(yuzuki a, yuzuki b) const
    {
        yuzuki au = a >> 31;
        yuzuki ad = a & MASK31;
        yuzuki bu = b >> 31;
        yuzuki bd = b & MASK31;
        yuzuki mid = ad * bu + au * bd;
        yuzuki midu = mid >> 30;
        yuzuki midd = mid & MASK30;
        return applyMod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    inline yuzuki applyMod(yuzuki val) const
    {
        val = (val & mod) + (val >> 61);
        if (val > mod)
        {
            val -= mod;
        }
        return val;
    }

    RollingHash(const string &s)
    {
        int n = (int)s.size();
        hashed.resize(n + 1);
        powmemo.resize(n + 1);
        powmemo[0] = 1;
        for (int i = 0; i < n; ++i)
        {
            hashed[i + 1] = applyMod(mul(hashed[i], base) + s[i]);
            powmemo[i + 1] = applyMod(mul(powmemo[i], base));
        }
    }

    //[l, r)
    inline yuzuki get(int l, int r) const
    {
        if (l >= r)
        {
            return 0ULL;
        }
        return applyMod(hashed[r] + SUP - mul(hashed[l], powmemo[r - l]));
    }

    inline yuzuki connect(const yuzuki &h1, const yuzuki &h2, int h2len) const
    {
        return applyMod(h2 + mul(h1, powmemo[h2len]));
    }

    inline int LCP(const RollingHash &b, int l1, int r1, int l2, int r2) const
    {
        int ok = 0, ng = min(r2 - l2, r1 - l1) + 1;
        while (ok + 1 < ng)
        {
            int m = (ok + ng) / 2;
            (get(l1, l1 + m) == b.get(l2, l2 + m) ? ok : ng) = m;
        }
        return ok;
    }
};

//------------------------------- Dubug Functions ---------------------------//

inline void print()
{
    cout << endl;
}
template <typename First, typename... Rest>
void print(const First &first, const Rest &... rest)
{
    cout << first << ' ';
    print(rest...);
}
//------------------------------- Solver ------------------------------------//

void solve()
{
    int n, m;
    seika s, q;
    cin >> n >> m >> s;
    RollingHash rh(s);
    int l = 0, r = 0;
    set<RollingHash::yuzuki> hashes;
    while (m--)
    {
        cin >> q;
        if (q == "L++")
        {
            l++;
        }
        else if (q == "L--")
        {
            l--;
        }
        else if (q == "R++")
        {
            r++;
        }
        else
        {
            r--;
        }
        hashes.insert(rh.get(l, r + 1));
    }
    cout << hashes.size() << endl;
}

int main()
{
    solve();
    return 0;
}



Measured memory_bytes: 21748