/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Ido Kessler
 */

#pragma GCC optimize("O3")

#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <functional>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <bitset>

#define all(x) (x).begin(), (x).end()
#define fori(i, n) for(int i = 0; i < n; i++)
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#define repr(i, s, e) for(int i = (s); i >= (e); --i)
#define ll long long int
#define pb push_back

namespace io{
class input_reader{
std::istream&in;
void throw_error(){throw std::runtime_error("No more inputs while reading number");}
template<typename T>
inline void readIntegerValue(T&f){bool positive=true;f=0;char c;
if(!in.get(c))throw_error();
while(c<'0'||c>'9'){if(c=='-')positive=false;if(!in.get(c))throw_error();}
while(c>='0'&&c<='9'){f=(f<<3)+(f<<1)+(c&15);if(!in.get(c))break;}
if(!positive)f*=-1;}
public:
explicit input_reader(std::istream&in):in(in){}
inline void read(int&f){readIntegerValue(f);}
inline void read(short&f){readIntegerValue(f);}
inline void read(long int&f){readIntegerValue(f);}
inline void read(long long int&f){readIntegerValue(f);}
inline void read(unsigned int&f){readIntegerValue(f);}
inline void read(unsigned short&f){readIntegerValue(f);}
inline void read(unsigned long int&f){readIntegerValue(f);}
inline void read(unsigned long long int&f){readIntegerValue(f);}
template<typename T>inline void read(std::vector<T>&f){for(auto&i:f)read(i);}
template<typename T,int N>inline void read(std::array<T,N>&res){for(auto&i:res)read(i);}
template<typename T1,typename T2>inline void read(std::pair<T1,T2>&p){in.read(p.first,p.second);}
template<typename T>inline void read(T&f){in>>f;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t),read(args...);}
template<typename T>inline void readArray(int n,T*res){while(n--)read(*(res++));}
template<typename T>inline input_reader&operator>>(T&t){return read(t),*this;}
};
}

namespace io{
class output_writer{
std::ostream&out;
template<typename T>inline void printIntegerHelper(T x){if(x>=10)printIntegerHelper(x/10);out.put(x%10+48);}
template<typename T>inline void printInteger(T x){if(x<0)out.put('-'),x=-x;printIntegerHelper(x);}
template<typename T>inline void printArray(T&ar){bool first=true;for(auto&t:ar)print((first)? first=false,"":" ",t);}
public:
explicit output_writer(std::ostream&out):out(out){}
inline void flush(){out.flush();}
inline void print(){}
inline void print(char x){out.put(x);}
inline void print(short x){printInteger(x);}
inline void print(int x){printInteger(x);}
inline void print(long int x){printInteger(x);}
inline void print(long long int x){printInteger(x);}
inline void print(unsigned short x){printInteger(x);}
inline void print(unsigned int x){printInteger(x);}
inline void print(unsigned long int x){printInteger(x);}
inline void print(unsigned long long int x){printInteger(x);}
template<typename T1>inline void print(const T1&t1){out<<t1;}
template<typename T1>inline void print(const std::vector<T1>&t1){printArray(t1);}
template<typename T1,int N>inline void print(const std::array<T1,N>&t1){printArray(t1);}
template<typename T1,int N,int M>inline void print(const std::array<std::array<T1,M>,N>&t1){for(auto&t:t1)println(t);}
template<typename T1>inline void print(const std::vector<std::vector<T1>>&t1){for(auto&t:t1)println(t);}
template<typename T,typename...Args>inline void print(const T&t,Args...args){print(t),print(args...);}
template<typename...Args>inline void println(Args...args){print(args...),print('\n');}
template<typename T>output_writer&operator<<(const T&t){return print(t),*this;}
};
}


inline ll pow_mod(const ll a, const ll b, const ll MOD) {
	if (b == 0) return 1;
	if (b == 1) return a % MOD;
	ll res = pow_mod(a * a % MOD, b >> 1, MOD);
	if (b & 1) res = res * a % MOD;
	return res % MOD;
}

inline ll mod_inv(const ll a, const ll MOD) {
	return pow_mod(a, MOD - 2, MOD);
}

ll gcd(ll a, ll b) {
	if (a == 0)
		return b;
	return gcd(b % a, a);
}

int gcd(int a, int b) {
	if (a == 0)
		return b;
	return gcd(b % a, a);
}


using namespace std;

class CSnukeTheWizard {
	class Solver {
		io::input_reader in;
		io::output_writer out;

	public:
		Solver(std::istream &in, std::ostream &out) : in(in), out(out) {}

		int solve(const string &s, const vector<vector<int>> &goodAction, const vector<vector<int>> &badAction) {
			auto next = [](const vector<vector<int>> &list, int turn, char S) {
				S -= 'A';
				auto val = lower_bound(all(list[S]), turn);
				if (val == list[S].end()) return -1;
				else return *val;
			};
			auto nextGood = [&](int turn, char S) {
				return next(goodAction, turn, S);
			};
			auto nextBad = [&](int turn, char S) {
				return next(badAction, turn, S);
			};
			auto can = [&](int m) {
				int turn = 0;
				while (m >= 0 && m < s.size()) {
					auto ng = nextGood(turn, s[m]);
					auto nb = nextBad(turn, s[m]);
					if (ng == -1 && nb == -1) break;
					else if (nb == -1 || (ng != -1 && ng < nb)) {
						m--, turn = ng + 1;
					} else {
						m++, turn = nb + 1;
					}
				}
				return m < 0;
			};
			int l = -1, r = s.size();
			while (l + 1 < r) {
				int m = (l + r) / 2;
				if (can(m)) {
					l = m;
				} else {
					r = m;
				}
			}
			return l + 1;
		}

		void solve() {
			int n, q;
			string s;
			in.read(n, q, s);
			vector<vector<int>> actionsL(26);
			vector<vector<int>> actionsR(26);
			fori(i, q) {
				char a, b;
				in.read(a, b);
				auto l = (b == 'L') ? &actionsL : &actionsR;
				(*l)[a - 'A'].pb(i);
			}
			int res = solve(s, actionsL, actionsR);
			reverse(all(s));
			res += solve(s, actionsR, actionsL);
			out << (n - res);
		}
	};

public:
	void solve(std::istream &in, std::ostream &out) {
		Solver(in, out).solve();
	}
};

int main() {
	std::ios_base::sync_with_stdio(false), cin.tie(0);
	CSnukeTheWizard solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}


Measured memory_bytes: 1872