package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	// https://emtubasa.hateblo.jp/entry/2019/03/31/015542
	nq := nextIntArray()
	n, q := nq[0], nq[1]
	s := nextLine()
	t, d := make([]byte, q), make([]byte, q)
	for i := 0; i < q; i++ {
		a := nextLine()
		t[i], d[i] = a[0], a[2]
	}

	// 消滅しないロボットの左端、右端
	l, r := 0, n-1
	// 後ろから見る
	for i := q - 1; i >= 0; i-- {
		if s[l] == t[i] && d[i] == 'L' {
			l++
		} else if l > 0 && s[l-1] == t[i] && d[i] == 'R' {
			l--
		}

		if s[r] == t[i] && d[i] == 'R' {
			r--
		} else if r < n-1 && s[r+1] == t[i] && d[i] == 'L' {
			r++
		}
	}
	fmt.Println(max(0, r-l+1))
}

func lcm(a, b int64) int64 {
	return (a / gcd(a, b)) * b
}

func gcd(a, b int64) int64 {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

const size = 1000000

var reader = bufio.NewReaderSize(os.Stdin, size)

func nextLine() string {
	var line, buffer []byte
	isPrefix := true
	var err error
	for isPrefix {
		line, isPrefix, err = reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buffer = append(buffer, line...)
	}
	return string(buffer)
}
func nextStringArray() []string {
	return strings.Split(nextLine(), " ")
}
func nextInt() int {
	n, _ := strconv.Atoi(nextLine())
	return n
}

func nextIntArray() []int {
	s := strings.Split(nextLine(), " ")
	n := len(s)
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i], _ = strconv.Atoi(s[i])
	}
	return a
}

func min(i, j int) int {
	if i > j {
		return j
	}
	return i
}

func max(i, j int) int {
	if i < j {
		return j
	}
	return i
}
