Buggy python submission (verdict: Time Limit Exceeded):
import sys
# input = sys.stdin.readline
S = list(input())
p = 10 ** 9 + 7
# p = 10 ** 18

A = AB = ABC = 0
Q = 0
for i, Si in enumerate(S):
    # print("#", A, AB, ABC)
    if Si == 'A':
        A = (A + 1 * (3 ** Q)) % p
    elif Si == 'B':
        AB = (AB + A) % p
    elif Si == 'C':
        ABC = (ABC + AB) % p
    else:
        ABC = (3 * ABC + AB) % p
        AB = (3 * AB + A) % p
        A = (3 * A + 1 * (3 ** Q)) % p
        Q += 1

print(ABC)

Fixed submission:
# encoding: utf-8
S = input()

A = 0
C = S.count("C") # N
q = 0

q_max = S.count("?") # N

ABC = 0
div = 10 ** 9 + 7
B_base = 3 ** (q_max - 2) % div
q_base = 3 ** (q_max - 3) % div
for si in S: # N
    if si == "A": A += 1
    elif si == "C": C -= 1
    elif si == "B":
        # ABC = (ABC + (A * C) * (3 ** q_max)) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (A * (q_max - q)) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * (q_max - q)) * (3 ** (q_max - 2))) % div
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q) * B_base) % div
    else: # "?"
        # ABC = (ABC + (A * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (A * (q_max - q - 1)) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (q * (q_max - q - 1)) * (3 ** (q_max - 3))) % div        
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q - 1) * q_base) % div
        q += 1
    # print(si, ABC)
    
print(int(ABC))

Buggy python submission (verdict: Time Limit Exceeded):
# encoding: utf-8
S = input()

A = 0
C = S.count("C") # N
q = 0

q_max = S.count("?") # N

ABC = 0
div = 10 ** 9 + 7
for si in S: # N
    if si == "A": A += 1
    elif si == "C": C -= 1
    elif si == "B":
        # ABC = (ABC + (A * C) * (3 ** q_max)) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (A * (q_max - q)) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * (q_max - q)) * (3 ** (q_max - 2))) % div
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q) * (3 ** (q_max - 2))) % div
    else: # "?"
        # ABC = (ABC + (A * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (A * (q_max - q - 1)) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (q * (q_max - q - 1)) * (3 ** (q_max - 3))) % div        
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q - 1) * (3 ** (q_max - 3))) % div
        q += 1
    # print(si, ABC)
    
print(int(ABC))

Fixed submission:
# encoding: utf-8
S = input()

A = 0
C = S.count("C") # N
q = 0

q_max = S.count("?") # N

ABC = 0
div = 10 ** 9 + 7
B_base = 3 ** (q_max - 2) % div
q_base = 3 ** (q_max - 3) % div
for si in S: # N
    if si == "A": A += 1
    elif si == "C": C -= 1
    elif si == "B":
        # ABC = (ABC + (A * C) * (3 ** q_max)) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (A * (q_max - q)) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * (q_max - q)) * (3 ** (q_max - 2))) % div
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q) * B_base) % div
    else: # "?"
        # ABC = (ABC + (A * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (A * (q_max - q - 1)) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (q * (q_max - q - 1)) * (3 ** (q_max - 3))) % div        
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q - 1) * q_base) % div
        q += 1
    # print(si, ABC)
    
print(int(ABC))

Buggy python submission (verdict: Time Limit Exceeded):
# encoding: utf-8
S = input()

A = 0
C = S.count("C") # N
q = 0

q_max = S.count("?") # N

ABC = 0
div = 10 ** 9 + 7
for si in S: # N
    if si == "A": A += 1
    elif si == "C": C -= 1
    elif si == "B":
        ABC = (ABC + (A * C) * (3 ** q_max)) % div
        ABC = (ABC + (q * C) * (3 ** (q_max - 1))) % div
        ABC = (ABC + (A * (q_max - q)) * (3 ** (q_max - 1))) % div
        ABC = (ABC + (q * (q_max - q)) * (3 ** (q_max - 2))) % div
    else: # "?"
        ABC = (ABC + (A * C) * (3 ** (q_max - 1))) % div
        ABC = (ABC + (q * C) * (3 ** (q_max - 2))) % div
        ABC = (ABC + (A * (q_max - q - 1)) * (3 ** (q_max - 2))) % div
        ABC = (ABC + (q * (q_max - q - 1)) * (3 ** (q_max - 3))) % div        
        q += 1
    # print(si, ABC)
    
print(int(ABC))

Fixed submission:
# encoding: utf-8
S = input()

A = 0
C = S.count("C") # N
q = 0

q_max = S.count("?") # N

ABC = 0
div = 10 ** 9 + 7
B_base = 3 ** (q_max - 2) % div
q_base = 3 ** (q_max - 3) % div
for si in S: # N
    if si == "A": A += 1
    elif si == "C": C -= 1
    elif si == "B":
        # ABC = (ABC + (A * C) * (3 ** q_max)) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (A * (q_max - q)) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * (q_max - q)) * (3 ** (q_max - 2))) % div
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q) * B_base) % div
    else: # "?"
        # ABC = (ABC + (A * C) * (3 ** (q_max - 1))) % div
        # ABC = (ABC + (q * C) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (A * (q_max - q - 1)) * (3 ** (q_max - 2))) % div
        # ABC = (ABC + (q * (q_max - q - 1)) * (3 ** (q_max - 3))) % div        
        ABC = (ABC + (3 * A + q) * (3 * C + q_max - q - 1) * q_base) % div
        q += 1
    # print(si, ABC)
    
print(int(ABC))