#![allow(unused_imports)]
use std::io::{ self, Write };
use std::str::FromStr;
use std::cmp::{ min, max };
use std::collections::{ BinaryHeap, VecDeque };

#[allow(unused_macros)]
macro_rules! trace {
    ($var:expr) => {
        let _ = writeln!(&mut std::io::stderr(), ">>> {} = {:?}", stringify!($var), $var);
    };
    ($($args:expr),*) => {
        let _ = writeln!(&mut std::io::stderr(), ">>> {} = {:?}", stringify!($($args),*), ($($args),*));
    };
}

#[allow(unused_macros)]
macro_rules! put {
    ($var:expr) => {
        let _ = writeln!(&mut std::io::stdout(), "{}", $var);
    };
    ($var:expr, $($args:expr),*) => {
        let _ = write!(&mut std::io::stdout(), "{} ", $var);
        put!($($args),*);
    };
}

const M: usize = 1_000_000_007;

#[derive(PartialEq, Eq, Debug)]
enum Limit { Left, Alive, Right }

fn simu(s: &Vec<char>, i: usize, qs: &Vec<(char, char)>) -> Limit {
    let mut pos = i;
    for &(a, d) in qs.iter() {
        if s[pos] != a { continue }
        if d == 'L' {
            if pos == 0 {
                return Limit::Left
            }
            pos -= 1;
        } else {
            if pos == s.len() - 1 {
                return Limit::Right
            }
            pos += 1
        }
    }
    Limit::Alive
}

fn main() {
    let mut sc = Scanner::new();
    let n: usize = sc.cin();
    let q: usize = sc.cin();
    let s: Vec<char> = sc.cin::<String>().chars().collect();
    let qs: Vec<(char, char)> = (0..q).map(|_|
        (sc.cin::<char>(), sc.cin::<char>())).collect();

    // for p in 0..n { trace!(simu(&s, p, &qs)); }

    if simu(&s, n - 1, &qs) == Limit::Left {
        put!(0);
        return;
    }
    if simu(&s, 0, &qs) == Limit::Right {
        put!(0);
        return;
    }

    let mut a0 = 0;  // most left alive
    {
        if simu(&s, 0, &qs) == Limit::Alive {
            a0 = 0;
        } else { // bisec
            let mut left = 0;
            let mut right = n - 1;
            for _ in 0..1000 {
                let mid = (left + right) / 2;
                if simu(&s, mid, &qs) == Limit::Left {
                    left = mid;
                } else {
                    right = mid;
                }
            }
            a0 = right;
        }
    }
    // trace!(a0);

    let mut a1 = n-1; // most right alive
    {
        if simu(&s, n-1, &qs) == Limit::Alive {
            a1 = n - 1;
        } else { //bisec
            let mut left = 0;
            let mut right = n-1;
            for _ in 0..1000 {
                let mid = (left + right) / 2;
                if simu(&s, mid, &qs) == Limit::Right {
                    right = mid;
                } else {
                    left = mid;
                }
            }
            a1 = left;
        }
    }
    // trace!(a1);

    put!(a1 - a0 + 1);
}

#[allow(dead_code)]
struct Scanner { stdin: io::Stdin, buffer: VecDeque<String>, }
#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner { Scanner { stdin: io::stdin(), buffer: VecDeque::new() } }
    fn reserve(&mut self) {
        while self.buffer.len() == 0 {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
    }
    fn cin<T: FromStr>(&mut self) -> T {
        self.reserve();
        match self.buffer.pop_front().unwrap().parse::<T>() {
            Ok(a) => a,
            Err(_) => panic!("parse err")
        }
    }
}
