Buggy python submission (verdict: Runtime Error):
N, Q = map(int, input().split())
s = '#' + input() + '#'
T = []
D = []
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
def canReachEnd(iL, dir):
  nowL = iL
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      nowL += d
      nowt = s[nowL]
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else:
    return False

#1. iは左にたどり着くがi+1は辿りつかないようなiを探す
left = 0
right = N+1
while right > left+1:
  check = (left + right)//2
  if canReachEnd(check, -1):
    left = check
  else:
    right = check
leftborder = left

#2. jは右にたどり着くがj-1は辿りつかないようなjを探す
left = leftborder
right = N+1
while rigtht > left+1:
  check = (left+right)//2
  if canReachEnd(check, 1):
    right = check
  else:
    left = check
rightborder = right

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)


Fixed submission:
N, Q = map(int, input().split())
s = '#' + input() + '#'
#room[0], [1~N], [N+1]と考える
#文字を取り出すとき:[1~N]
T = [] #Title[0～Q-1]
D = [] #Direction[0～Q-1] R:1, L:-1で表現
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
#True, Falseを返す
def canReachEnd(iL, dir):
  #iLは初期マス(1~N), dirは方向(L:-1, R:1)
  
  #nowL:今いるマスの位置
  nowL = iL
  #nowt:今いるマスに書いてある文字
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      #左に動いても右に動いてもdを足せばok
      #端に落ちたら文字が'#'なので気にしない
      nowL += d
      nowt = s[nowL]
      
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else: return False
#たどり着けるかの関数終わり

#ここから二分探索で2つの「境目」を探す

#(1)「iは左に辿り着くがi+1は辿り着かない」iを探す
#何も辿り着かない場合はi=0とする？
#全部辿り着く場合はi=Nとする？
#leftとrightが隣接したときのleftを答えとする？
##すると、ありえるleftの範囲は0~N
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, -1):left = check
  else: right = check
#答えを代入
leftborder = left


#(2)「jは右に辿り着くがj-1は辿り着かない」jを探す
#何も辿り着かない場合はj=N+1とする？
#全部辿り着く場合はj=1とする？
#leftとrightが隣接したときのrightを答えとする？
##すると、ありえるrightの範囲はleftborder+1~N+1
left = leftborder #(1)で左に辿り着くと分かった部分は省く
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, 1):right = check
  else: left = check
#答えを代入
rightborder = right

#二分探索終わり

#lbには左に辿り着く限界,rbには右に辿り着く限界が格納
#1~lbまでは全部左端に落ちる lb==0なら0
#rb~Nまでは全部右端に落ちる rb==N+1なら0

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)

Buggy python submission (verdict: Runtime Error):
N, Q = map(int, input().split())
s = '#' + input() + '#'
T = []
D = []
for t, d in [input().split() for _ in range(Q)]:
  T.append(T)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどりつけるかの関数
def canReachEnd(iL, dir):
  nowL = iL
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      nowL += d
      nowt = s[nowL]
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else:
    return False

#1. iは左にたどりつくがi+1は辿りつかないようなiを探す
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  if canReachEnd(check, -1):
    left = check
  else:
    right = check
leftborder = leftborder

#2. jは右にたどり着くがj-1は辿りつかないようなjを探す
left = leftborder
right = N+1
while right > left+1:
  check = (left+right)//2
  if canReachEnd(check, 1):
    right = check
  else:
    left = check
rightborder = right

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)


Fixed submission:
N, Q = map(int, input().split())
s = '#' + input() + '#'
#room[0], [1~N], [N+1]と考える
#文字を取り出すとき:[1~N]
T = [] #Title[0～Q-1]
D = [] #Direction[0～Q-1] R:1, L:-1で表現
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
#True, Falseを返す
def canReachEnd(iL, dir):
  #iLは初期マス(1~N), dirは方向(L:-1, R:1)
  
  #nowL:今いるマスの位置
  nowL = iL
  #nowt:今いるマスに書いてある文字
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      #左に動いても右に動いてもdを足せばok
      #端に落ちたら文字が'#'なので気にしない
      nowL += d
      nowt = s[nowL]
      
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else: return False
#たどり着けるかの関数終わり

#ここから二分探索で2つの「境目」を探す

#(1)「iは左に辿り着くがi+1は辿り着かない」iを探す
#何も辿り着かない場合はi=0とする？
#全部辿り着く場合はi=Nとする？
#leftとrightが隣接したときのleftを答えとする？
##すると、ありえるleftの範囲は0~N
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, -1):left = check
  else: right = check
#答えを代入
leftborder = left


#(2)「jは右に辿り着くがj-1は辿り着かない」jを探す
#何も辿り着かない場合はj=N+1とする？
#全部辿り着く場合はj=1とする？
#leftとrightが隣接したときのrightを答えとする？
##すると、ありえるrightの範囲はleftborder+1~N+1
left = leftborder #(1)で左に辿り着くと分かった部分は省く
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, 1):right = check
  else: left = check
#答えを代入
rightborder = right

#二分探索終わり

#lbには左に辿り着く限界,rbには右に辿り着く限界が格納
#1~lbまでは全部左端に落ちる lb==0なら0
#rb~Nまでは全部右端に落ちる rb==N+1なら0

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)

Buggy python submission (verdict: Runtime Error):
N, Q = map(int, input().split())
s = '#' + input() + '#'
T = []
D = []
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
def canReachEnd(iL, dir):
  nowL = iL
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      nowL += {nowt = snowL]
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else:
    return False

#1. iは左にたどりつくがi+1はたどりつかないiを探す
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  if canReachEnd(check, -1):
    left = check
  else:
    right = check
leftborder = left

#2. jは右にたどりつくがj-1はたどりつかない jを探す
left = leftborder
right = N+1
while right > left+1:
  check = (left+right)//2
  if canReachEnd(check, 1):
    right = check
  else:
    left = check
rightborder = right

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)

Fixed submission:
N, Q = map(int, input().split())
s = '#' + input() + '#'
#room[0], [1~N], [N+1]と考える
#文字を取り出すとき:[1~N]
T = [] #Title[0～Q-1]
D = [] #Direction[0～Q-1] R:1, L:-1で表現
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
#True, Falseを返す
def canReachEnd(iL, dir):
  #iLは初期マス(1~N), dirは方向(L:-1, R:1)
  
  #nowL:今いるマスの位置
  nowL = iL
  #nowt:今いるマスに書いてある文字
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      #左に動いても右に動いてもdを足せばok
      #端に落ちたら文字が'#'なので気にしない
      nowL += d
      nowt = s[nowL]
      
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else: return False
#たどり着けるかの関数終わり

#ここから二分探索で2つの「境目」を探す

#(1)「iは左に辿り着くがi+1は辿り着かない」iを探す
#何も辿り着かない場合はi=0とする？
#全部辿り着く場合はi=Nとする？
#leftとrightが隣接したときのleftを答えとする？
##すると、ありえるleftの範囲は0~N
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, -1):left = check
  else: right = check
#答えを代入
leftborder = left


#(2)「jは右に辿り着くがj-1は辿り着かない」jを探す
#何も辿り着かない場合はj=N+1とする？
#全部辿り着く場合はj=1とする？
#leftとrightが隣接したときのrightを答えとする？
##すると、ありえるrightの範囲はleftborder+1~N+1
left = leftborder #(1)で左に辿り着くと分かった部分は省く
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, 1):right = check
  else: left = check
#答えを代入
rightborder = right

#二分探索終わり

#lbには左に辿り着く限界,rbには右に辿り着く限界が格納
#1~lbまでは全部左端に落ちる lb==0なら0
#rb~Nまでは全部右端に落ちる rb==N+1なら0

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)

Buggy python submission (verdict: Runtime Error):
N, Q = map(int, input().split())
s = '#' + input() + '#'
#room[0], [1~N], [N+1]と考える
#文字を取り出すとき:[1~N]
T = [] #Title[0～Q-1]
D = [] #Direction[0～Q-1] R:1, L:-1で表現
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
#True, Falseを返す
def canReachEnd(iL, dir):
  #iLは初期マス(1~N), dirは方向(L:-1, R:1)
  
  #nowL:今いるマスの位置
  nowL = iL
  #nowt:今いるマスに書いてある文字
  nowt = s[iL]
  for t, d in zip(T, D):
    print('nowtは'+str(nowt)+'で,'+str(t)+str(d))
    if t == nowt:
      #左に動いても右に動いてもdを足せばok
      #端に落ちたら文字が'#'なので気にしない
      nowL += d
      nowt = s[nowL]
      print('moved' + str(d) + ',' + str(nowL) + 'to:' + str(nowt))
      
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else: return False
#たどり着けるかの関数終わり

#まずは左側 room0に辿り着くかどうかの判定
#二分探索
  
print(canReachEnd(10,1))

Fixed submission:
N, Q = map(int, input().split())
s = '#' + input() + '#'
#room[0], [1~N], [N+1]と考える
#文字を取り出すとき:[1~N]
T = [] #Title[0～Q-1]
D = [] #Direction[0～Q-1] R:1, L:-1で表現
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
#True, Falseを返す
def canReachEnd(iL, dir):
  #iLは初期マス(1~N), dirは方向(L:-1, R:1)
  
  #nowL:今いるマスの位置
  nowL = iL
  #nowt:今いるマスに書いてある文字
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      #左に動いても右に動いてもdを足せばok
      #端に落ちたら文字が'#'なので気にしない
      nowL += d
      nowt = s[nowL]
      
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else: return False
#たどり着けるかの関数終わり

#ここから二分探索で2つの「境目」を探す

#(1)「iは左に辿り着くがi+1は辿り着かない」iを探す
#何も辿り着かない場合はi=0とする？
#全部辿り着く場合はi=Nとする？
#leftとrightが隣接したときのleftを答えとする？
##すると、ありえるleftの範囲は0~N
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, -1):left = check
  else: right = check
#答えを代入
leftborder = left


#(2)「jは右に辿り着くがj-1は辿り着かない」jを探す
#何も辿り着かない場合はj=N+1とする？
#全部辿り着く場合はj=1とする？
#leftとrightが隣接したときのrightを答えとする？
##すると、ありえるrightの範囲はleftborder+1~N+1
left = leftborder #(1)で左に辿り着くと分かった部分は省く
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, 1):right = check
  else: left = check
#答えを代入
rightborder = right

#二分探索終わり

#lbには左に辿り着く限界,rbには右に辿り着く限界が格納
#1~lbまでは全部左端に落ちる lb==0なら0
#rb~Nまでは全部右端に落ちる rb==N+1なら0

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)

Buggy python submission (verdict: Time Limit Exceeded):
N, Q = map(int, input().split())
s = input()
T = [0 for i in range(Q)]
D = [0 for i in range(Q)]
for i in range(Q):
    T[i], D[i] = input().split()
for i in range(Q):
    if T[i] == 'A':
        T[i] = 0
    elif T[i] == 'B':
        T[i] = 1
    elif T[i] == 'C':
        T[i] = 2
    elif T[i] == 'D':
        T[i] = 3
    elif T[i] == 'E':
        T[i] = 4
    elif T[i] == 'F':
        T[i] = 5
    elif T[i] == 'G':
        T[i] = 6
    elif T[i] == 'H':
        T[i] = 7
    elif T[i] == 'I':
        T[i] = 8
    elif T[i] == 'J':
        T[i] = 9
    elif T[i] == 'K':
        T[i] = 10
    elif T[i] == 'L':
        T[i] = 11
    elif T[i] == 'M':
        T[i] = 12
    elif T[i] == 'N':
        T[i] = 13
    elif T[i] == 'O':
        T[i] = 14
    elif T[i] == 'P':
        T[i] = 15
    elif T[i] == 'Q':
        T[i] = 16
    elif T[i] == 'R':
        T[i] = 17
    elif T[i] == 'S':
        T[i] = 18
    elif T[i] == 'T':
        T[i] = 19
    elif T[i] == 'U':
        T[i] = 20
    elif T[i] == 'V':
        T[i] = 21
    elif T[i] == 'W':
        T[i] = 22
    elif T[i] == 'X':
        T[i] = 23
    elif T[i] == 'Y':
        T[i] = 24
    elif T[i] == 'Z':
        T[i] = 25
for i in range(Q):
    if D[i] == 'L':
        D[i] = 0
    elif D[i] == 'R':
        D[i] = 1
word_of_cell = [0] * N 
for i in range(1,N+1):
    w = s[i-1:i] 
    if w == 'A':
        word_of_cell[i-1] = 0
    elif w == 'B':
        word_of_cell[i-1] = 1
    elif w == 'C':
        word_of_cell[i-1] = 2
    elif w == 'D':
        word_of_cell[i-1] = 3
    elif w == 'E':
        word_of_cell[i-1] = 4
    elif w == 'F':
        word_of_cell[i-1] = 5
    elif w == 'G':
        word_of_cell[i-1] = 6
    elif w == 'H':
        word_of_cell[i-1] = 7
    elif w == 'I':
        word_of_cell[i-1] = 8
    elif w == 'J':
        word_of_cell[i-1] = 9
    elif w == 'K':
        word_of_cell[i-1] = 10
    elif w == 'L':
        word_of_cell[i-1] = 11
    elif w == 'M':
        word_of_cell[i-1] = 12
    elif w == 'N':
        word_of_cell[i-1] = 13
    elif w == 'O':
        word_of_cell[i-1] = 14
    elif w == 'P':
        word_of_cell[i-1] = 15
    elif w == 'Q':
        word_of_cell[i-1] = 16
    elif w == 'R':
        word_of_cell[i-1] = 17
    elif w == 'S':
        word_of_cell[i-1] = 18
    elif w == 'T':
        word_of_cell[i-1] = 19
    elif w == 'U':
        word_of_cell[i-1] = 20
    elif w == 'V':
        word_of_cell[i-1] = 21
    elif w == 'W':
        word_of_cell[i-1] = 22
    elif w == 'X':
        word_of_cell[i-1] = 23
    elif w == 'Y':
        word_of_cell[i-1] = 24
    elif w == 'Z':
        word_of_cell[i-1] = 25
g_leave = [[[0 for i in range(N+3)] for d in range(2)] for t in range(26)] 
g_enter = [[[0 for i in range(N+3)]  for d in range(2)] for t in range(26)]
for t in range(26):
    for d in range(2):
        for i in range(1,N+1): 
            if word_of_cell[i-1] == t and d == 0: 
                g_enter[t][d][0] += 1 
                g_enter[t][d][g_enter[t][d][0]] = i 
                g_leave[t][d][0] += 1 
                g_leave[t][d][g_leave[t][d][0]] = i+1 
            if word_of_cell[i-1] == t and d == 1: 
                g_enter[t][d][0] += 1 
                g_enter[t][d][g_enter[t][d][0]] = i+2 
                g_leave[t][d][0] += 1 
                g_leave[t][d][g_leave[t][d][0]] = i+1 
golem_count = [0]*(N+2) 
for i in range(1,N+1): 
    golem_count[i] = 1
import copy
for q in range(Q):
    previous_golem_count = copy.deepcopy(golem_count) 
    for i in range(1,g_enter[T[q]][D[q]][0]+1):
        if D[q] == 0: 
            golem_count[g_enter[T[q]][D[q]][i]-1] += previous_golem_count[g_enter[T[q]][D[q]][i]]
        if D[q] == 1: 
            golem_count[g_enter[T[q]][D[q]][i]-1] += previous_golem_count[g_enter[T[q]][D[q]][i]-2]
    for i in range(1,g_leave[T[q]][D[q]][0]+1): 
            golem_count[g_leave[T[q]][D[q]][i]-1] -= previous_golem_count[g_leave[T[q]][D[q]][i]-1] 
print(N-golem_count[0]-golem_count[N+1])


Fixed submission:
N, Q = map(int, input().split())
s = '#' + input() + '#'
#room[0], [1~N], [N+1]と考える
#文字を取り出すとき:[1~N]
T = [] #Title[0～Q-1]
D = [] #Direction[0～Q-1] R:1, L:-1で表現
for t, d in [input().split() for _ in range(Q)]:
  T.append(t)
  D.append(-1 if d=='L' else 1)

#そのゴーレムがどちらかの端にたどり着けるかの関数
#True, Falseを返す
def canReachEnd(iL, dir):
  #iLは初期マス(1~N), dirは方向(L:-1, R:1)
  
  #nowL:今いるマスの位置
  nowL = iL
  #nowt:今いるマスに書いてある文字
  nowt = s[iL]
  for t, d in zip(T, D):
    if t == nowt:
      #左に動いても右に動いてもdを足せばok
      #端に落ちたら文字が'#'なので気にしない
      nowL += d
      nowt = s[nowL]
      
  if dir == 1 and nowL == N+1:
    return True
  elif dir == -1 and nowL == 0:
    return True
  else: return False
#たどり着けるかの関数終わり

#ここから二分探索で2つの「境目」を探す

#(1)「iは左に辿り着くがi+1は辿り着かない」iを探す
#何も辿り着かない場合はi=0とする？
#全部辿り着く場合はi=Nとする？
#leftとrightが隣接したときのleftを答えとする？
##すると、ありえるleftの範囲は0~N
left = 0
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, -1):left = check
  else: right = check
#答えを代入
leftborder = left


#(2)「jは右に辿り着くがj-1は辿り着かない」jを探す
#何も辿り着かない場合はj=N+1とする？
#全部辿り着く場合はj=1とする？
#leftとrightが隣接したときのrightを答えとする？
##すると、ありえるrightの範囲はleftborder+1~N+1
left = leftborder #(1)で左に辿り着くと分かった部分は省く
right = N+1
while right > left+1:
  check = (left+right)//2
  
  if canReachEnd(check, 1):right = check
  else: left = check
#答えを代入
rightborder = right

#二分探索終わり

#lbには左に辿り着く限界,rbには右に辿り着く限界が格納
#1~lbまでは全部左端に落ちる lb==0なら0
#rb~Nまでは全部右端に落ちる rb==N+1なら0

dropcnt = 0
dropcnt += leftborder
dropcnt += (N-(rightborder-1))
print(N-dropcnt)