/* template.cpp {{{ */
#include <bits/stdc++.h>
using namespace std;
 
// #define int long long
#define GET_MACRO(a, b, c, d, NAME, ...) NAME
#define REP1(n) REP2(i_, n)
#define REP2(i, n) REP3(i, 0, n)
#define REP3(i, a, b) REP4(i, a, b, 1)
#define REP4(i, a, b, s) for (long long i = (a); i < (long long)(b); i += (long long)(s))
#define RREP1(n) RREP2(i_, n)
#define RREP2(i, n) RREP3(i, 0, n)
#define RREP3(i, a, b) RREP4(i, a, b, 1)
#define RREP4(i, a, b, s) for (long long i = (b) - 1; i >= (long long)(a);  i -= (long long)(s))
#define rep(...) GET_MACRO(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define rrep(...) GET_MACRO(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define fs first
#define sc second
#define all(c) std::begin(c), std::end(c)
#define pcnt(x) __builtin_popcountll(x)
#define each(x, c) for (auto &&x : c)
#define endl "\n"
#define y0 y0_
#define y1 y1_
#define yn yn_
 
#define TMP_T template<typename T>
#define TMP_TU template<typename T, typename U>
#define TMP_Ts template<typename ...T>
#define TMP_NTs template<size_t N, typename ...T>
#define TMP_CT template<bool C, typename T = void>
 
#ifndef DEBUG
#define cerr no_output
struct NoOutput : ostream {
  TMP_T ostream &operator<<(const T &){ return *this; }
} no_output;
#endif
 
using uint = unsigned;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
TMP_T using PQL = priority_queue<T, vector<T>, greater<T>>;
TMP_T using PQG = priority_queue<T>;
TMP_CT using enable_if_t = typename enable_if<C, T>::type;
 
const ll LLINF = 1e18 + 10;
#ifndef int
const int INF = 1e9 + 10;
#else
const int INF = LLINF;
#endif
 
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};
const int dy[] = {0, -1, 0, 1, -1, -1, 1, 1};
 
TMP_T inline constexpr T sq(T x){ return x * x; }
TMP_TU inline T& chmin(T &x, U y){ if (x > y) x = y; return x; }
TMP_TU inline T& chmax(T &x, U y){ if (x < y) x = y; return x; }
 
TMP_NTs enable_if_t<(N >= sizeof...(T))> input_tuple(istream &, tuple<T...> &){}
TMP_NTs enable_if_t<(N < sizeof...(T))> input_tuple(istream &is, tuple<T...> &x){ is >> get<N>(x); input_tuple<N + 1, T...>(is, x); }
TMP_Ts ostream &operator>>(istream &is, tuple<T...> &x){ input_tuple<0, T...>(is, x); return is; }
TMP_TU ostream &operator>>(istream &is, pair<T, U> &x){ return is >> x.first >> x.second; }
TMP_NTs enable_if_t<(N >= sizeof...(T))> print_tuple(ostream &, const tuple<T...> &){}
TMP_NTs enable_if_t<(N < sizeof...(T))> print_tuple(ostream &os, const tuple<T...> &x){ os << (N > 0 ? " " : "") << get<N>(x); print_tuple<N + 1, T...>(os, x); }
TMP_Ts ostream &operator<<(ostream &os, const tuple<T...> &x){ print_tuple<0, T...>(os, x); return os; }
TMP_TU ostream &operator<<(ostream &os, const pair<T, U> &x){ return os << x.first << " " << x.second; }
 
#undef TMP_T
#undef TMP_TU
#undef TMP_Ts
#undef TMP_NTs
#undef TMP_CT

ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b){ return a / gcd(a, b) * b; }
tuple<ll, ll, ll> extgcd(ll a, ll b){
  if (b){
    ll g, x, y;
    tie(g, x, y) = extgcd(b, a % b);
    return make_tuple(g, y, x - a / b * y);
  }
  return make_tuple(a, 1, 0);
}
ll invmod(ll a, ll m = 1000000007){
  ll g, x;
  tie(g, x, ignore) = extgcd(a, m);
  return g == 1 ? (x + m) % m : 0;
}

inline ll in(){ ll x; cin >> x; return x; }
 
struct prepare {
  prepare(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(12);
    cerr << fixed << setprecision(12);
  }
} prepare_;
/* }}} */
/* rolling_hash.cpp {{{ */
class RollingHash {
public:
  using hash_type = array<ll, 3>;

  RollingHash(): n(0){}
  
  template<typename OutputIterator>
  RollingHash(OutputIterator first, OutputIterator last){
    n = distance(first, last);
    s.reserve(n);
    while (first != last){
      s.push_back(*first);
      ++first;
    }
    
    rep(i, 3){
      hs[i].resize(n + 1);
      hs[i][0] = 0;
      rep(j, n){
        hs[i][j + 1] = (base[i] * hs[i][j] + s[j]) % mod[i];
      }
    }
  }

  template<typename U>
  RollingHash(U s){
    *this = RollingHash(all(s));
  }

  hash_type hash(int l, int r) const {
    hash_type res;
    rep(i, 3){
      res[i] = ((hs[i][r] - hs[i][l] * pw[i][r - l]) % mod[i] + mod[i]) % mod[i];
    }
    return res;
  }
  
private:
  static struct prepare {
    prepare(){
      rep(i, 3){
        pw[i][0] = 1;
        rep(j, max_length){
          pw[i][j + 1] = base[i] * pw[i][j] % mod[i];
        }
      }
    }
  } prepare_;

  int n;
  vector<ll> s;
  array<vector<ll>, 3> hs;
  static const size_t max_length = 500000;
  static const hash_type base, mod;
  static array<array<ll, max_length + 1>, 3> pw;
};

const typename RollingHash::hash_type RollingHash::base{{11261, 77747, 93001}};
const typename RollingHash::hash_type RollingHash::mod{{1000000007, 1000000009, 99999971}};
typename RollingHash::prepare RollingHash::prepare_;
array<array<ll, RollingHash::max_length + 1>, 3> RollingHash::pw;
/* }}} */

signed main()
{
  int n, m;
  string s;
  cin >> n >> m >> s;
  RollingHash h(s);
  set<RollingHash::hash_type> st;
  int l = 0, r = 1;
  rep(m){
    string q;
    cin >> q;
    if (q == "L++") l++;
    else if (q == "L--") l--;
    else if (q == "R++") r++;
    else if (q == "R--") r--;
    st.insert(h.hash(l, r));
  }
  cout << st.size() << endl;
}

Measured memory_bytes: 43072