#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::prelude::BufRead;
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufReader, BufWriter, Write};
#[allow(unused_imports)]
use std::mem::swap;
#[allow(unused_imports)]
use std::str::FromStr;

fn main() {
    let line = read_vector::<usize>();
    let (n, q) = (line[0], line[1]);
    let s = read_chars();
    let mut operation = vec![];
    for _ in 0..q {
        let line = read_chars();
        operation.push((line[0], line[2]));
    }
    let mut left = -1;
    let mut max_right = -1;
    let mut right = n as i32;
    let mut min_left = n as i32;
    for i in (0..q).rev() {
        if operation[i].1 == 'L' {
            if left + 1 < n as i32 {
                let index = (left + 1) as usize;
                if s[index] == operation[i].0 {
                    left = index as i32;
                    max_right = max(max_right, left);
                }
            }
            if right + 1 < n as i32 {
                let index = (right + 1) as usize;
                if s[index] == operation[i].0 {
                    right = index as i32
                }
            }
        } else {
            if left - 1 >= 0 {
                let index = (left - 1) as usize;
                if s[index] == operation[i].0 {
                    left = index as i32;
                }
            }
            if right - 1 >= 0 {
                let index = (right - 1) as usize;
                if s[index] == operation[i].0 {
                    right = index as i32;
                    min_left = min(min_left, right);
                }
            }
        }
    }

    println!("{}", n as i32 - min(max_right + 1 + n as i32 - min_left, n as i32));
}

#[allow(dead_code)]
fn read<T>() -> T
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    return buf.trim().parse().unwrap();
}

#[allow(dead_code)]
fn read_vector<T>() -> Vec<T>
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    let mut buf = String::with_capacity(100);
    stdin().read_line(&mut buf).unwrap();
    return buf.split_whitespace().map(|s| s.parse().unwrap()).collect();
}

#[allow(dead_code)]
fn read_matrix<T>() -> Vec<Vec<T>>
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    use std::io::prelude::*;
    let stdin = stdin();
    let mut reader = BufReader::with_capacity(100 * 1024, stdin);
    let mut line = String::with_capacity(100);
    let mut matrix: Vec<Vec<T>> = Vec::new();

    while reader.read_line(&mut line).unwrap() > 0 {
        matrix.push(
            line.trim()
                .split_whitespace()
                .map(|s| s.parse().unwrap())
                .collect(),
        );
        line.clear();
    }

    return matrix;
}

#[allow(dead_code)]
fn read_chars() -> Vec<char> {
    let stdin = stdin();
    let mut buf = String::new();
    let _bytes = stdin.read_line(&mut buf).unwrap();
    return buf.trim().chars().collect();
}
