Problem:
Substring

長さnの文字列s=s1,s2,…,snおよびm個のクエリが与えられる。
各クエリqk (1 ≤ k ≤ m)は、"L++", "L--", "R++", "R--"の4種類のいずれかであり、
k番目のクエリqkに対してl[k]とr[k]を以下で定義する。

L++：l[k]=l[k-1]+1,r[k]=r[k-1]

L--：l[k]=l[k-1]-1,r[k]=r[k-1]

R++：l[k]=l[k-1],r[k]=r[k-1]+1

R--：l[k]=l[k-1],r[k]=r[k-1]-1

但し、l[0]=r[0]=1である。

この時、m個の部分文字列
sl[k], sl[k]+1, …, sr[k]-1, sr[k] (1 ≤ k ≤ m)
について、何種類の文字列が作られるかを答えよ。

Input

入力は以下の形式で与えられる

n m
s
q1
q2
…
qm

Constraints

文字列sは小文字アルファベットからなる

1 ≤ n ≤ 3×105

1 ≤ m ≤ 3×105

qk(1 ≤ k ≤ m)は、"L++"、"L--"、"R++"、"R--"のいずれか

1 ≤ l[k] ≤ r[k] ≤ n (1 ≤ k ≤ m)

Output

問題の解を1行に出力せよ

Sample Input 1

5 4
abcde
R++
R++
L++
L--

Output for the Sample Input 1

3

l[1]=1, r[1]=2であり、部分文字列は"ab"である

l[2]=1, r[2]=3であり、部分文字列は"abc"である

l[3]=2, r[3]=3であり、部分文字列は"bc"である

l[4]=1, r[4]=3であり、部分文字列は"abc"である

よって、生成される文字列は{"ab","abc","bc"}の3種類である。

Sample Input 2

4 6
abab
R++
L++
R++
L++
R++
L++

Output for the Sample Input 2

4

l[1]=1, r[1]=2であり、部分文字列は"ab"である

l[2]=2, r[2]=2であり、部分文字列は"b"である

l[3]=2, r[3]=3であり、部分文字列は"ba"である

l[4]=3, r[4]=3であり、部分文字列は"a"である

l[5]=3, r[5]=4であり、部分文字列は"ab"である

l[6]=4, r[6]=4であり、部分文字列は"b"である

よって、生成される文字列は{"a","ab","b","ba"}の4種類である。

Sample Input 3

10 13
aacacbabac
R++
R++
L++
R++
R++
L++
L++
R++
R++
L--
L--
R--
R--

Output for the Sample Input 3

11

Solution in C++ (judge verdict: Wrong Answer)


// @snippet<sh19910711/contest:headers.cpp>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <limits>
#include <complex>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

// @snippet<sh19910711/contest:solution/interface.cpp>
namespace solution {
    class ISolution {
    public:
        virtual void init() {};
        virtual bool input() { return false; };
        virtual void output() {};
        virtual int run() = 0;
    };
}

// @snippet<sh19910711/contest:math/extgcd.cpp>
namespace math {
    template <class T> T extgcd( T a, T b, T& x, T& y ) {
        for ( T u = y = 1, v = x = 0; a; ) {
            T q = b / a;
            std::swap( x -= q * u, u );
            std::swap( y -= q * v, v );
            std::swap( b -= q * a, a );
        }
        return b;
    }
}

// @snippet<sh19910711/contest:math/mod_inverse.cpp>
namespace math {
    template <class T> T mod_inverse( T a, T m ) {
        T x, y;
        extgcd( a, m, x, y );
        x %= m;
        while ( x < 0 )
            x += m;
        return x;
    }
}


// @snippet<sh19910711/contest:solution/solution.cpp>
namespace solution {
    using namespace std;
    
    const int SIZE = 300011;
    int n, m;
    string s;
    string Q[SIZE];

    class IRollingHash {
    public:
        virtual void init() {};
        virtual void pushBack( char c ) {};
        virtual void popBack() {};
        virtual void pushFront( char c ) {};
        virtual void popFront() {};
    };
    
    template <long long B, long long MOD> class RollingHash: public IRollingHash {
    public:
        typedef long long LL;
        LL hash;
        LL bases;
        LL mod;
        LL b_inv;
        std::deque<char> Q;
        RollingHash() {
            init();
        }
        void init() {
            hash = 0;
            bases = 1;
            b_inv = math::mod_inverse( B, MOD ) % MOD;
            Q.clear();
        }
        void pushBack( char c ) {
            hash = ( hash * B + c ) % MOD;
            bases = ( bases * B ) % MOD;
            Q.push_back(c);
        }
        void popBack() {
            char c = Q.back();
            hash = ( ( hash - c + MOD ) % MOD * b_inv ) % MOD;
            bases = ( bases * b_inv ) % MOD;
            Q.pop_back();
        }
        void pushFront( char c ) {
            hash = ( hash + ( c * bases ) % MOD ) % MOD;
            bases = ( bases * B ) % MOD;
            Q.push_front(c);
        }
        void popFront() {
            char c = Q.front();
            hash = ( hash - ( bases * b_inv * c ) % MOD + MOD ) % MOD;
            bases = ( bases * b_inv ) % MOD;
            Q.pop_front();
        }
        void init( string s ) {
            int n = s.size();
            for ( int i = 0; i < n; ++ i ) {
                pushBack(s[i]);
            }
        }
    };

    const int SIZE1 = 214831;
    const int SIZE2 = 215827;
    RollingHash<29LL, SIZE1> rh1;
    RollingHash<29LL, SIZE2> rh2;

    const int RHC = 2;
    IRollingHash* RH[RHC] = { &rh1, &rh2 };
    
    void push_front( char c ) {
        for ( int i = 0; i < RHC; ++ i ) {
            RH[i]->pushFront(c);
        }
    }
    
    void pop_front() {
        for ( int i = 0; i < RHC; ++ i ) {
            RH[i]->popFront();
        }
    }
    
    void push_back( char c ) {
        for ( int i = 0; i < RHC; ++ i ) {
            RH[i]->pushBack(c);
        }
    }
    
    void pop_back() {
        for ( int i = 0; i < RHC; ++ i ) {
            RH[i]->popBack();
        }
    }
    
    class Solution: public ISolution {
    public:
        void init() {
            rh1.init();
            rh2.init();
        }
        bool input() {
            if ( ! ( cin >> n >> m ) )
                return false;
            cin >> s;
            for ( int i = 0; i < m; ++ i )
                cin >> Q[i];
            return true;
        }
        bool check( const int& l, const int& r ) {
            return l >= 0 && l <= r;
        }
        void solve() {
            for ( int i = 0; i < n; ++ i )
                s[i] = s[i] - 'a' + 1;

            set <pair<long long, long long> > S;
            string sub = s.substr( 0, 1 );
            push_back(s[0]);
            
            int l = 0, r = 0;
            for ( int i = 0; i < m; ++ i ) {
                string& q = Q[i];
                if ( q[0] == 'L' ) {
                    if ( q[1] == '+' ) {
                        l ++;
                        if ( check( l, r ) ) {
                            sub = sub.substr( 1 );
                            pop_front();
                        }
                    } else {
                        l --;
                        if ( check( l, r ) ) {
                            sub = s[l] + sub;
                            push_front( s[l] );
                        }
                    }
                } else {
                    if ( q[1] == '+' ) {
                        r ++;
                        if ( check( l, r ) ) {
                            sub += s[r];
                            push_back(s[r]);
                        }
                    } else {
                        r --;
                        if ( check( l, r ) ) {
                            sub = sub.substr( 0, sub.size() - 1 );
                            pop_back();
                        }
                    }
                }
                
                S.insert( make_pair( rh1.hash, rh2.hash ) );
            }

            cout << S.size() << endl;
        }
        int run() {
            while ( init(), input() ) {
                solve();
                output();
            }
            return 0;
        }
    };
}


// @snippet<sh19910711/contest:main.cpp>

int main() {
    return solution::Solution().run();
}