Problem:
Score : 400 points

Problem Statement

The ABC number of a string T is the number of triples of integers (i, j, k) that satisfy all of the following conditions:

1 ≤ i < j < k ≤ |T| (|T| is the length of T.)

T_i = A (T_i is the i-th character of T from the beginning.)

T_j = B

T_k = C

For example, when T = ABCBC, there are three triples of integers (i, j, k) that satisfy the conditions: (1, 2, 3), (1, 2, 5), (1, 4, 5). Thus, the ABC number of T is 3.

You are given a string S. Each character of S is A, B, C or ?.

Let Q be the number of occurrences of ? in S. We can make 3^Q strings by replacing each occurrence of ? in S with A, B or C. Find the sum of the ABC numbers of all these strings.

This sum can be extremely large, so print the sum modulo 10^9 + 7.

Constraints

3 ≤ |S| ≤ 10^5

Each character of S is A, B, C or ?.

Input

Input is given from Standard Input in the following format:

S

Output

Print the sum of the ABC numbers of all the 3^Q strings, modulo 10^9 + 7.

Sample Input 1

A??C

Sample Output 1

8

In this case, Q = 2, and we can make 3^Q = 9 strings by by replacing each occurrence of ? with A, B or C. The ABC number of each of these strings is as follows:

AAAC: 0

AABC: 2

AACC: 0

ABAC: 1

ABBC: 2

ABCC: 2

ACAC: 0

ACBC: 1

ACCC: 0

The sum of these is 0 + 2 + 0 + 1 + 2 + 2 + 0 + 1 + 0 = 8, so we print 8 modulo 10^9 + 7, that is, 8.

Sample Input 2

ABCBC

Sample Output 2

3

When Q = 0, we print the ABC number of S itself, modulo 10^9 + 7. This string is the same as the one given as an example in the problem statement, and its ABC number is 3.

Sample Input 3

????C?????B??????A???????

Sample Output 3

979596887

In this case, the sum of the ABC numbers of all the 3^Q strings is 2291979612924, and we should print this number modulo 10^9 + 7, that is, 979596887.

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.util.*;
import java.io.*;

public class Main {
	static int mod = (int) 1e9 + 7;
	
	public static void main(String[] args) {
		FastScanner fs = new FastScanner(System.in);
		String S = fs.next();
		int len = S.length();
		long dp[][] = new long[len][3];
		int qcnt = 0;
		if(S.charAt(0)=='A') dp[0][0]=1;
		if(S.charAt(0)=='?') {
			dp[0][0] = 1;
			qcnt++;
		}
		for(int i=1;i<len;i++) {
			if(S.charAt(i)=='A') {
				dp[i][0]=dp[i-1][0] + modpow(3,qcnt);
				dp[i][0]%=mod;
				dp[i][1]=dp[i-1][1];
				dp[i][2]=dp[i-1][2];
				
			}
			if(S.charAt(i)=='B') {
				dp[i][1]=dp[i-1][1] + dp[i-1][0];
				dp[i][1]%=mod;
				dp[i][0]=dp[i-1][0];
				dp[i][2]=dp[i-1][2];

			}
			if(S.charAt(i)=='C') {
				dp[i][2]=dp[i-1][2] + dp[i-1][1];
				dp[i][2]%=mod;
				dp[i][0]=dp[i-1][0];
				dp[i][1]=dp[i-1][1];
			}
			if(S.charAt(i)=='?') {
				
				dp[i][0]=3 * dp[i-1][0] %mod + modpow(3,qcnt);
				dp[i][1]=3 * dp[i-1][1] %mod + dp[i-1][0];
				dp[i][2]=3 * dp[i-1][2] %mod + dp[i-1][1];	
				dp[i][0]%=mod;
				dp[i][1]%=mod;
				dp[i][2]%=mod;
				
				qcnt++;
			}
		}
		System.out.println(dp[len-1][2]);
	}

	//modの元での高速pow()
	static long modpow(long a, long p) {
		if (p == 0)
			return 1;
		if (p % 2 == 0) {
			long halfP = p / 2;
			long root = modpow(a, halfP);
			return root * root % mod;
		} else
			return a * modpow(a, p - 1) % mod;
	}

}

//高速なScanner
class FastScanner {
	private BufferedReader reader = null;
	private StringTokenizer tokenizer = null;

	public FastScanner(InputStream in) {
		reader = new BufferedReader(new InputStreamReader(in));
		tokenizer = null;
	}

	public String next() {
		if (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public String nextLine() {
		if (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				return reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken("\n");
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}

	public int[] nextIntArray(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = nextInt();
		return a;
	}

	public long[] nextLongArray(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nextLong();
		return a;
	}
}