#include <bits/stdc++.h>
template <typename T>
using vec = std::vector<T>;
using vi = vec<int>;
using vvi = vec<vi>;
using pii = std::pair<int, int>;
using ll = long long;
using vll = vec<ll>;
using ld = long double;
using namespace std;
const int MOD = 1000000007;
template <typename T>
void putv(vector<T> &V) {
  for (auto x : V) cout << x << " ";
  cout << endl;
}
template <class T>
vector<T> getv(int n) {
  vector<T> vec;
  for (int i = (0); i < int(n); ++i) {
    T input;
    cin >> input;
    vec.emplace_back(input);
  }
  return vec;
}
using Weight = ll;
using Flow = int;
struct Edge {
  int src, dst;
  Weight weight;
  Flow cap;
  Edge() : src(0), dst(0), weight(0) {}
  Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;
void add_edge(Graph &g, int a, int b, Weight w = 1) {
  g[a].emplace_back(a, b, w);
  g[b].emplace_back(b, a, w);
}
void add_arc(Graph &g, int a, int b, Weight w = 1) {
  g[a].emplace_back(a, b, w);
}
void init_weighted_graph(Graph &g, int N, int M) {
  vector<Edge> empty_Edges;
  g = Graph(N, empty_Edges);
  for (int i = (0); i < int(M); ++i) {
    int a, b, w;
    cin >> a >> b >> w;
    add_edge(g, a - 1, b - 1, w);
  }
}
void init_weighted_directed_graph(Graph &g, int N, int M) {
  vector<Edge> empty_Edges;
  g = Graph(N, empty_Edges);
  for (int i = (0); i < int(M); ++i) {
    int a, b, w;
    cin >> a >> b >> w;
    add_arc(g, a - 1, b - 1, -w);
  }
}
void show_weighted_graph(const Graph &g) {
  int N = g.size();
  int M = 0;
  for (int s = (0); s < int(N); ++s) M += g[s].size();
  cout << "///////////////////////" << endl;
  cout << "The Adjacency List of" << endl
       << "G=(V,E) (n=" << N << ","
       << "m=" << M << ")" << endl;
  for (int s = (0); s < int(N); ++s) {
    cout << s << ": ";
    int size = g[s].size();
    for (int t = (0); t < int(size); ++t)
      cout << "(" << g[s][t].dst << "," << g[s][t].weight << ")";
    cout << endl;
  }
  cout << "////////////////////////" << endl << endl;
}
bool is_adj(Graph &g, int a, int b) {
  for (auto e : g[a])
    if (b == e.dst) return true;
  return false;
}
pair<vec<Weight>, bool> bellmanFord(const Graph &g, int s) {
  int n = g.size();
  const Weight inf = numeric_limits<Weight>::max() / 8;
  Edges es;
  for (int v = (0); v < int(n); ++v)
    for (auto &e : g[v]) es.emplace_back(e);
  vector<Weight> dist(n, inf);
  dist[s] = 0;
  bool negCycle = false;
  for (int i = 0;; i++) {
    bool update = false;
    for (auto &e : es)
      if (dist[e.src] != inf && dist[e.dst] > dist[e.src] + e.weight) {
        dist[e.dst] = dist[e.src] + e.weight;
        update = true;
      }
    if (!update) break;
    if (i > n) {
      negCycle = true;
      break;
    }
  }
  return make_pair(dist, !negCycle);
}
void out(bool ans) {
  if (ans == true)
    cout << "yes" << endl;
  else
    cout << "no" << endl;
}
void Out(bool ans) {
  if (ans == true)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
void OUT(bool ans) {
  if (ans == true)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}
ll gcd(const ll a, const ll b) { return (b == 0) ? a : gcd(b, a % b); }
ll lcm(const ll a, const ll b) { return a * (b / gcd(a, b)); }
ll Manhattan_dist(ll x1, ll y1, ll x2, ll y2) {
  return abs(x1 - x2) + abs(y1 - y2);
}
ll hmt_p_divide_n(ll p, ll n) {
  ll s = 0;
  while (n % p == 0) {
    n /= p;
    s++;
  }
  return s;
}
int digit(ll n) {
  int cntr = 0;
  while (n > 0) {
    n /= 10;
    cntr++;
  }
  return cntr;
}
template <class T>
T gabs(const T &x) {
  return max(x, -x);
}
unsigned long long memo[100][100] = {};
unsigned long long nCr(const int n, const int r) {
  if (n < r) return 0;
  if (r == 0 || n == r) return 1;
  if (memo[n][r] > 0)
    return memo[n][r];
  else
    return memo[n][r] = nCr(n - 1, r) + nCr(n - 1, r - 1);
}
int N, Q;
string s;
char t[200001], d[200001];
bool LL(int pos) {
  for (int i = (0); i < int(Q); ++i) {
    if (s[pos] == t[i] && d[i] == 'R')
      pos++;
    else
      pos--;
    if (pos < 0) return true;
    if (N <= pos) return false;
  }
  return false;
}
bool RR(int pos) {
  for (int i = (0); i < int(Q); ++i) {
    if (s[pos] == t[i] && d[i] == 'L')
      pos++;
    else
      pos--;
    if (pos < 0) return false;
    if (N <= pos) return true;
  }
  return false;
}
int searchL(int a, int b) {
  if (a + 1 == b) {
    if (a == 0 && !LL(0)) {
      return 0;
    } else if (b == N - 1 && LL(N - 1))
      return N;
    return b;
  }
  int m = (a + b) / 2;
  int pos = m;
  for (int i = (0); i < int(Q); ++i) {
    if (t[i] == s[pos]) {
      if (d[i] == 'R')
        pos++;
      else
        pos--;
      if (pos < 0) {
        return searchL(m, b);
      }
    }
  }
  return searchL(a, m);
}
int searchR(int a, int b) {
  if (a + 1 == b) {
    if (b == N - 1 && !RR(N - 1)) {
      return 0;
    } else if (a == 0 && RR(0))
      return N;
    return N - b;
  }
  int m = (a + b) / 2;
  int pos = m;
  for (int i = (0); i < int(Q); ++i) {
    if (t[i] == s[pos]) {
      if (d[i] == 'R')
        pos++;
      else
        pos--;
      if (N <= pos) return searchR(a, m);
    }
  }
  return searchR(m, b);
}
int main() {
  cin >> N >> Q >> s;
  for (int i = (0); i < int(Q); ++i) cin >> t[i] >> d[i];
  int posL = searchL(0, N - 1);
  int posR = searchR(0, N - 1);
  cout << N - (posR + posL) << endl;
}
