// Original C++ solution (slower):


#include<iostream>

#include<string>

#include<cstring>

#include<stdio.h>

#include<algorithm>

#include<functional>

#include<vector>

#include<set>

#include<queue>

#include<list>

#include<stdio.h>

#include<stdlib.h>

#include<map>

#include<cstdio>

#include <iomanip>



#define rep(i,a,b) for(int i=a;i<b;i++)

#define rrep(i,a,b) for(int i=a;i<=b;i++)

#define fore(i,a) for(auto &i:a)





using namespace std;

typedef long long ll;



const int MOD = 1e9 + 7;

string S;



void add(ll &a, ll b) {

	a += b;

	if (a >= MOD)a -= MOD;

}



//i番目までみた時の、状態j

//j=0 ""

//j=1 A

//j=2 AB

//j=3 ABC



ll dp[210000][4];



int main() {



	cin >> S;

	memset(dp, 0, sizeof(dp));



	dp[0][0] = 1;



	//Sを1文字ずつみていく。

	for (int i = 0; i < S.size(); ++i) {

		//Siを使わない。

		for (int j = 0; j < 4; ++j) {

			if (S[i] != '?') {

				add(dp[i + 1][j], dp[i][j]);

			}

			else {

				add(dp[i + 1][j], dp[i][j] * 3 % MOD);

			}

		}



		//Siを使う。



		//状態0はAか？がくれば状態1に遷移する。

		if (S[i] == 'A' || S[i] == '?') add(dp[i + 1][1], dp[i][0]);



		//状態1はBか？がくれば状態2に遷移する。

		if (S[i] == 'B' || S[i] == '?') add(dp[i + 1][2], dp[i][1]);



		//状態2はCか？がくれば状態3に遷移する。

		if (S[i] == 'C' || S[i] == '?') add(dp[i + 1][3], dp[i][2]);

	}

	

	cout << dp[S.size()][3] << endl;

}

// Optimized solution to the same problem (faster):


//include

//------------------------------------------

#include <vector>

#include <list>

#include <map>

#include <set>

#include <deque>

#include <queue>

#include <stack>

#include <bitset>

#include <algorithm>

#include <functional>

#include <numeric>

#include <utility>

#include <sstream>

#include <iostream>

#include <fstream>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <cstdlib>

#include <string>

#include <cstring>

#include <ctime>

#include <climits>

#include <limits>



using namespace std;



//conversion

//------------------------------------------

inline int toInt(string s) { int v; istringstream sin(s); sin >> v; return v; }

template<class T> inline string toString(T x) { ostringstream sout; sout << x; return sout.str(); }



//math

//-------------------------------------------

template<class T> inline T sqr(T x) { return x * x; }



//typedef

//------------------------------------------

typedef vector<int> VI;

typedef vector<VI> VVI;

typedef vector<string> VS;

typedef pair<int, int> PII;

typedef long long LL;



//container util

//------------------------------------------

#define ALL(a)  (a).begin(),(a).end()

#define RALL(a) (a).rbegin(), (a).rend()

#define PB push_back

#define MP make_pair

#define SZ(a) int((a).size())

#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)

#define EXIST(s,e) ((s).find(e)!=(s).end())

#define EXISTch(s,c) ((((s).find_first_of(c)) != std::string::npos)? 1 : 0)//cがあれば1 if(1)

#define SORT(c) sort((c).begin(),(c).end())



#define REP(i,n) for(int i=0;i<(int)n;++i)

#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)



//constant

//--------------------------------------------

const double EPS = 1e-10;

const double PI = acos(-1.0);

const int INF = (int)1000000007;

const LL MOD = (LL)1000000007;//10^9+7

const LL INF2 = (LL)100000000000000000;//10^18



LL dp[200010][4];



void add(LL &a, LL b) {

	a = (a + b) % MOD;

}



//dp i番目までみたときの、状態jをそれまでに完成させた文字列で決めておく



//j=0 ""

//j=1 "A"

//j=2 "AB"

//j=3 "ABC"



int main() {

	string s; cin >> s;





	//dp初期化、場合の数を数える問題なので0で初期化

	for (int i = 0; i < 100010; i++) {

		for (int j = 0; j < 4; j++) {

			dp[i][j] = 0;

		}

	}



	//0番目までみて文字列が何も無い状態が一通り

	dp[0][0] = 1;



	for (int i = 0; i < s.size(); i++) {

		//siを使わない



		for (int j = 0; j < 4; j++) {

			//si=?でないなら、状態i,jの数はそのまま引き継ぐ

			if (s[i] != '?') {

				dp[i + 1][j] = dp[i][j];

			}

			//si=?ならA,B,C 3文字分違う文字列になるので、3倍してやる

			else {

				dp[i + 1][j] = dp[i][j]*3%MOD;

			}

		}





		//siを使って遷移する



		if (s[i] == '?') {

			//""→A



			dp[i + 1][1] += dp[i][0];

			dp[i + 1][1] %= MOD;



			//A→AB



			dp[i + 1][2] += dp[i][1];

			dp[i + 1][2] %= MOD;

			//AB→ABC



			dp[i + 1][3] += dp[i][2];

			dp[i + 1][3] %= MOD;

		}



		if (s[i] == 'A') {

			dp[i + 1][1] += dp[i][0];

			dp[i + 1][1] %= MOD;

		}



		if (s[i] == 'B') {

			dp[i + 1][2] += dp[i][1];

			dp[i + 1][2] %= MOD;

		}



		if (s[i] == 'C') {

			dp[i + 1][3] += dp[i][2];

			dp[i + 1][3] %= MOD;

		}

	}



	cout << dp[s.size()][3] << endl;

	return 0;

}

// Fastest known solution for this problem: