Buggy python submission (verdict: Runtime Error):
S=input()
N=len(S)
mod=10**9+7

import sys
sys.setrecursionlimit(200000)

from functools import lru_cache

@lru_cache(maxsize=None)
def dp(cur,i):
	if cur==N:
		if i==3:
			return 1
		else:
			return 0
	else:
		if S[cur]=='ABCD'[i]:
			return (dp(cur+1,i+1)+dp(cur+1,i))%mod
		elif S[cur]=='?' and i!=3:
			return (dp(cur+1,i+1)+3*dp(cur+1,i))%mod
		elif S[cur]=='?':
			return 3*dp(cur+1,i)%mod
		else:
			return dp(cur+1,i)%mod

print(dp(0,0)%mod)

Fixed submission:
S=input()
lens=len(S)
mod=10**9+7
cnt=[0,0,0,1]
for s in S:
    if s=="A":
        cnt[0]=(cnt[0]+cnt[3])%mod
    elif s=="B":
        cnt[1]=(cnt[0]+cnt[1])%mod
    elif s=="C":
        cnt[2]=(cnt[1]+cnt[2])%mod
    else:
        cnt[2]=(cnt[1]+3*cnt[2])%mod
        cnt[1]=(cnt[0]+3*cnt[1])%mod
        cnt[0]=(3*cnt[0]+cnt[3])%mod
        cnt[3]=cnt[3]*3%mod
print(cnt[2]%mod)

Buggy python submission (verdict: Runtime Error):
S=input()
N=len(S)
mod=10**9+7

#import sys
#sys.setrecursionlimit(200000)

from functools import lru_cache

@lru_cache(maxsize=None)
def dp(cur,i):
	if cur==N:
		if i==3:
			return 1
		else:
			return 0
	else:
		if S[cur]=='ABCD'[i]:
			return (dp(cur+1,i+1)+dp(cur+1,i))%mod
		elif S[cur]=='?' and i!=3:
			return (dp(cur+1,i+1)+3*dp(cur+1,i))%mod
		elif S[cur]=='?':
			return 3*dp(cur+1,i)%mod
		else:
			return dp(cur+1,i)%mod

print(dp(0,0)%mod)

Fixed submission:
S=input()
lens=len(S)
mod=10**9+7
cnt=[0,0,0,1]
for s in S:
    if s=="A":
        cnt[0]=(cnt[0]+cnt[3])%mod
    elif s=="B":
        cnt[1]=(cnt[0]+cnt[1])%mod
    elif s=="C":
        cnt[2]=(cnt[1]+cnt[2])%mod
    else:
        cnt[2]=(cnt[1]+3*cnt[2])%mod
        cnt[1]=(cnt[0]+3*cnt[1])%mod
        cnt[0]=(3*cnt[0]+cnt[3])%mod
        cnt[3]=cnt[3]*3%mod
print(cnt[2]%mod)

Buggy python submission (verdict: Runtime Error):
S=input()
N=len(S)

import sys
sys.setrecursionlimit(200000)

from functools import lru_cache

@lru_cache(maxsize=None)
def dp(cur,i):
	if cur==N:
		if i==3:
			return 1
		else:
			return 0
	else:
		if S[cur]=='ABCD'[i]:
			return dp(cur+1,i+1)+dp(cur+1,i)
		elif S[cur]=='?':
			return dp(cur+1,i+1)+3*dp(cur+1,i)
		else:
			return dp(cur+1,i)

print(dp(0,0))

Fixed submission:
S=input()
lens=len(S)
mod=10**9+7
cnt=[0,0,0,1]
for s in S:
    if s=="A":
        cnt[0]=(cnt[0]+cnt[3])%mod
    elif s=="B":
        cnt[1]=(cnt[0]+cnt[1])%mod
    elif s=="C":
        cnt[2]=(cnt[1]+cnt[2])%mod
    else:
        cnt[2]=(cnt[1]+3*cnt[2])%mod
        cnt[1]=(cnt[0]+3*cnt[1])%mod
        cnt[0]=(3*cnt[0]+cnt[3])%mod
        cnt[3]=cnt[3]*3%mod
print(cnt[2]%mod)

Buggy python submission (verdict: Runtime Error):
S=input()
N=len(S)

from functools import lru_cache

@lru_cache(maxsize=None)
def dp(cur,i):
	if cur==N:
		if i==3:
			return 1
		else:
			return 0
	else:
		if S[cur]=='ABCD'[i]:
			return dp(cur+1,i+1)+dp(cur+1,i)
		elif S[cur]=='?':
			return dp(cur+1,i+1)+3*dp(cur+1,i)
		else:
			return dp(cur+1,i)

print(dp(0,0))

Fixed submission:
S=input()
lens=len(S)
mod=10**9+7
cnt=[0,0,0,1]
for s in S:
    if s=="A":
        cnt[0]=(cnt[0]+cnt[3])%mod
    elif s=="B":
        cnt[1]=(cnt[0]+cnt[1])%mod
    elif s=="C":
        cnt[2]=(cnt[1]+cnt[2])%mod
    else:
        cnt[2]=(cnt[1]+3*cnt[2])%mod
        cnt[1]=(cnt[0]+3*cnt[1])%mod
        cnt[0]=(3*cnt[0]+cnt[3])%mod
        cnt[3]=cnt[3]*3%mod
print(cnt[2]%mod)