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 C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Linq;
class P
{
    static int mod = 1000000007;
    static void Main()
    {
        string s = Console.ReadLine();
        int n = s.Length;
        int[,] count = new int[n + 1, 4];
        for (int i = 1; i <= n; i++)
        {
            count[i, 0] = count[i - 1, 0];
            count[i, 1] = count[i - 1, 1];
            count[i, 2] = count[i - 1, 2];
            count[i, 3] = count[i - 1, 3];
            if (s[i - 1] == 'A')
                count[i, 0]++;
            if (s[i - 1] == 'B')
                count[i, 1]++;
            if (s[i - 1] == 'C')
                count[i, 2]++;
            if (s[i - 1] == '?')
                count[i, 3]++;
        }
        long ans = 0;
        if (count[n, 3] >= 3)
        {//'?'を3個使う
            long q = count[n, 3];
            long p = Math.Max(q - 3, 0);
            long t = (q * (q - 1)) % mod;
            t = (t * (q - 2)) % mod;
            t = (t * POW(6, mod - 2)) % mod;
            ans = (ans + (t * POW(3, p)) % mod) % mod;
        }
        if (count[n, 3] >= 2)
        {//'?'を2個使う
            for (int i = 0; i < n; i++)
            {
                long p = Math.Max(count[n, 3] - 2, 0);
                if (s[i] == 'A')
                {
                    long q = count[n, 3] - count[i + 1, 3];
                    ans = (ans + ((q * (q - 1)) / 2 % mod * POW(3, p)) % mod) % mod;
                }
                if (s[i] == 'B')
                {
                    long ql = count[i, 3];
                    long qr = count[n, 3] - count[i + 1, 3];
                    ans = (ans + (ql * qr) % mod * POW(3, p) % mod) % mod;
                }
                if (s[i] == 'C')
                {
                    long q = count[i, 3];
                    ans = (ans + (q * (q - 1)) / 2 % mod * POW(3, p) % mod) % mod;
                }
            }
        }
        long q0 = 0;
        {//'?'を0個使う
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < n; i++)
                if (s[i] != '?')
                    sb.Append(s[i]);
            q0 = Calc(sb.ToString());
            ans += q0 * POW(3, count[n, 3]) % mod;
            ans %= mod;
        }
        long q1 = 0;
        if (count[n, 3] >= 1)
        {//'?'を1個使う
            long q = count[n, 3];
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < n; i++)
            {
                if (s[i] != '?')
                    sb.Append(s[i]);
                else
                    sb.Append('A');
            }
            ans = (ans + (Calc(sb.ToString()) - q0) * POW(3, q - 1) % mod) % mod;
            sb = new StringBuilder();
            for (int i = 0; i < n; i++)
            {
                if (s[i] != '?')
                    sb.Append(s[i]);
                else
                    sb.Append('B');
            }
            ans = (ans + (Calc(sb.ToString()) - q0) * POW(3, q - 1) % mod) % mod;
            sb = new StringBuilder();
            for (int i = 0; i < n; i++)
            {
                if (s[i] != '?')
                    sb.Append(s[i]);
                else
                    sb.Append('C');
            }
            ans = (ans + (Calc(sb.ToString()) - q0) * POW(3, q - 1) % mod) % mod;
        }
        while (ans < 0)
            ans += mod;
        Console.WriteLine(ans);
    }
    static long POW(long a, long n)
    {
        if (n == 0)
            return 1;
        if (n == 1)
            return a % mod;
        long m = n / 2;
        if (n % 2 == 0)
        {
            long temp = POW(a, m);
            return (temp * temp) % mod;
        }
        else
        {
            long temp = POW(a, m);
            return ((temp * temp) % mod * a) % mod;
        }
    }
    static long Calc(string s) //'A''B''C'のみの文字列からABC数を計算
    {
        long[] a = new long[s.Length + 1];
        long[] b = new long[s.Length + 1];
        long[] c = new long[s.Length + 1];
        for (int i = 1; i <= s.Length; i++)
        {
            a[i] = a[i - 1];
            b[i] = b[i - 1];
            c[i] = c[i - 1];
            if (s[i - 1] == 'A')
                a[i]++;
            if (s[i - 1] == 'B')
                b[i]++;
            if (s[i - 1] == 'C')
                c[i]++;
        }
        long[] bc = new long[s.Length];
        for (int i = 0; i < s.Length; i++)
            if (s[i] == 'B')
                bc[i] = c[s.Length] - c[i + 1];
        long[] bcs = new long[s.Length];
        bcs[s.Length - 1] = bc[s.Length - 1];
        for (int i = s.Length - 2; i >= 0; i--)
            bcs[i] = bcs[i + 1] + bc[i];
        long ans = 0;
        for (int i = 0; i < s.Length - 1; i++)
            if (s[i] == 'A')
                ans = (ans + bcs[i + 1] % mod) % mod;
        return ans;
    }
}