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: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char thestring[300010];

int compstr(const char* as,int al,const char* bs,int bl) {
	if(al>bl)return 1;
	if(al<bl)return -1;
	return strncmp(as,bs,al);
}

#define TREE_MAX 300010

typedef struct {
	const char* start;
	int length;
	int isred;
	int parent;
	int left;
	int right;
} rbt_node_t;

int rbt_node_used;
rbt_node_t rbt_node[TREE_MAX+1];

void rbt_init(void) {
	rbt_node_used=1;
	memset(rbt_node,0,sizeof(rbt_node));
	rbt_node[0].start="";
	rbt_node[0].length=0;
}

int rbt_insert(const char* start,int length) {
	int pos=0;
	int parent,p_parent,p_left,p_right;
	int pp_parent,pp_left,pp_right;
	while(1) {
		int comp=compstr(rbt_node[pos].start,rbt_node[pos].length,
			start,length);
		if(comp==0) {
			return 0;
		} else if(comp<0) {
			if(rbt_node[pos].right==0)break;
			pos=rbt_node[pos].right;
		} else {
			if(rbt_node[pos].left==0)break;
			pos=rbt_node[pos].left;
		}
	}
	if(rbt_node_used>TREE_MAX)return 0;
	rbt_node[rbt_node_used].start=start;
	rbt_node[rbt_node_used].length=length;
	rbt_node[rbt_node_used].isred=1;
	rbt_node[rbt_node_used].parent=pos;
	rbt_node[rbt_node_used].left=0;
	rbt_node[rbt_node_used].right=0;
	if(compstr(rbt_node[pos].start,rbt_node[pos].length,start,length)<0) {
		rbt_node[pos].right=rbt_node_used;
	} else {
		rbt_node[pos].left=rbt_node_used;
	}
	pos=rbt_node_used;
	rbt_node_used++;

	while(pos>0) {
		if(rbt_node[pos].parent==0) {
			rbt_node[pos].isred=0;
			break;
		}
		parent=rbt_node[pos].parent;
		p_parent=rbt_node[parent].parent;
		p_left=rbt_node[parent].left;
		p_right=rbt_node[parent].right;
		if(!rbt_node[parent].isred) {
			break;
		}
		pp_parent=rbt_node[p_parent].parent;
		pp_left=rbt_node[p_parent].left;
		pp_right=rbt_node[p_parent].right;
		if(rbt_node[pp_left].isred && rbt_node[pp_right].isred) {
			rbt_node[pp_left].isred=0;
			rbt_node[pp_right].isred=0;
			rbt_node[p_parent].isred=1;
			pos=p_parent;
		} else {
			if(pos==p_right && parent==pp_left) {
				if(rbt_node[pos].left>0) {
					rbt_node[rbt_node[pos].left].parent=parent;
				}
				rbt_node[parent].right=rbt_node[pos].left;
				rbt_node[parent].parent=pos;
				rbt_node[pos].left=parent;
				rbt_node[pos].parent=p_parent;
				rbt_node[p_parent].left=pos;
				pos=parent;
			} else if(pos==p_left && parent==pp_right) {
				if(rbt_node[pos].right>0) {
					rbt_node[rbt_node[pos].right].parent=parent;
				}
				rbt_node[parent].left=rbt_node[pos].right;
				rbt_node[parent].parent=pos;
				rbt_node[pos].right=parent;
				rbt_node[pos].parent=p_parent;
				rbt_node[p_parent].right=pos;
				pos=parent;
			} else if(pos==p_left && parent==pp_left) {
				if(rbt_node[pp_parent].left==p_parent) {
					rbt_node[pp_parent].left=parent;
				} else if(rbt_node[pp_parent].right==p_parent) {
					rbt_node[pp_parent].right=parent;
				} else {
					/* error!bug! */
					return 0;
				}
				if(rbt_node[parent].right>0) {
					rbt_node[rbt_node[parent].right].parent=p_parent;
				}
				rbt_node[p_parent].left=rbt_node[parent].right;
				rbt_node[p_parent].parent=parent;
				rbt_node[parent].right=p_parent;
				rbt_node[parent].parent=pp_parent;
				rbt_node[p_parent].isred=1;
				rbt_node[parent].isred=0;
				break;
			} else if(pos==p_right && parent==pp_right) {
				if(rbt_node[pp_parent].left==p_parent) {
					rbt_node[pp_parent].left=parent;
				} else if(rbt_node[pp_parent].right==p_parent) {
					rbt_node[pp_parent].right=parent;
				} else {
					/* error!bug! */
					return 0;
				}
				if(rbt_node[parent].left>0) {
					rbt_node[rbt_node[parent].left].parent=p_parent;
				}
				rbt_node[p_parent].right=rbt_node[parent].left;
				rbt_node[p_parent].parent=parent;
				rbt_node[parent].left=p_parent;
				rbt_node[parent].parent=pp_parent;
				rbt_node[p_parent].isred=1;
				rbt_node[parent].isred=0;
				break;
			} else {
				/* error!bug! */
				return 0;
			}
		}
	}
	rbt_node[0].parent=0;
	rbt_node[0].left=0;
	rbt_node[0].isred=0;
	return 1;
}

int main(void) {
	int n,m;
	char query[4];
	int i;
	const char* start;
	int length;
	int count;
	scanf("%d%d",&n,&m);
	scanf("%s",thestring);
	start=thestring;length=1;
	count=0;
	rbt_init();
	for(i=0;i<m;i++) {
		scanf("%s",query);
		if(query[0]=='R') {
			if(query[1]=='+') {
				length++;
			} else if(query[1]=='-') {
				length--;
			}
		} else if(query[0]=='L') {
			if(query[1]=='+') {
				start++;
				length--;
			} else if(query[1]=='-') {
				start--;
				length++;
			}
		}
		if(rbt_insert(start,length))count++;
	}
	printf("%d\n",count);
	return 0;
}