#pragma region
#define _USE_MATH_DEFINES
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <list>
#include <iomanip>
#include <cstdint>
#include <cstdlib>

using namespace std;
typedef long long ll;
//#define rep(i, s, e) for (int(i) = (s); (i) < (e); ++(i))
#define rep(i, e) for (int(i) = 0; (i) < (e); ++(i))
#define rrep(i, s) for (int(i) = (s) - 1; (i) >= 0; --(i))
#define all(x) x.begin(),x.end()
#pragma endregion

#pragma region MODint
template<int MOD> struct Fp
{
	long long val;
	constexpr Fp(long long v = 0) noexcept : val(v % MOD)
	{
		if (val < 0) val += MOD;
	}
	constexpr int getmod() { return MOD; }
	constexpr Fp operator - () const noexcept
	{
		return val ? MOD - val : 0;
	}
	constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
	constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
	constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
	constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
	constexpr Fp& operator += (const Fp& r) noexcept
	{
		val += r.val;
		if (val >= MOD) val -= MOD;
		return *this;
	}
	constexpr Fp& operator -= (const Fp& r) noexcept
	{
		val -= r.val;
		if (val < 0) val += MOD;
		return *this;
	}
	constexpr Fp& operator *= (const Fp& r) noexcept
	{
		val = val * r.val % MOD;
		return *this;
	}
	constexpr Fp& operator /= (const Fp& r) noexcept
	{
		long long a = r.val, b = MOD, u = 1, v = 0;
		while (b)
		{
			long long t = a / b;
			a -= t * b; swap(a, b);
			u -= t * v; swap(u, v);
		}
		val = val * u % MOD;
		if (val < 0) val += MOD;
		return *this;
	}
	constexpr bool operator == (const Fp& r) const noexcept
	{
		return this->val == r.val;
	}
	constexpr bool operator != (const Fp& r) const noexcept
	{
		return this->val != r.val;
	}
	friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept
	{
		return os << x.val;
	}
	friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept
	{
		if (n == 0) return 1;
		auto t = modpow(a, n / 2);
		t = t * t;
		if (n & 1) t = t * a;
		return t;
	}
};

const int MOD = 1000000007;
using mint = Fp<MOD>; 
#pragma endregion

int main()
{
	string s; cin >> s;
	int n = s.size();
	vector<ll> a(n + 1), c(n + 1), q(n + 1);
	rep(i, n)
	{
		if (s[i] == 'A')++a[i + 1];
		else if (s[i] == 'C')++c[i + 1];
		else if (s[i] == '?')++q[i + 1];
	}
	rep(i, n)
	{
		a[i + 1] += a[i];
		c[i + 1] += c[i];
		q[i + 1] += q[i];
	}
	mint res = 0;
	for (int i = 1; i < n - 1; ++i)
	{
		if (s[i] == 'B')
		{
			res += (mint)(a[i] * (c[n] - c[i + 1]))*modpow(mint(3), q[n]);
			res += (mint)(a[i] * (q[n] - q[i + 1]))*modpow(mint(3), q[n] - 1);
			res += (mint)(q[i] * (c[n] - c[i + 1]))*modpow(mint(3), q[n] - 1);
			res += (mint)(q[i] * (q[n] - q[i + 1]))*modpow(mint(3), q[n] - 2);
		}
		else if (s[i] == '?')
		{
			res += (mint)(a[i] * (c[n] - c[i + 1]))*modpow(mint(3), q[n] - 1);
			res += (mint)(a[i] * (q[n] - q[i + 1]))*modpow(mint(3), q[n] - 2);
			res += (mint)(q[i] * (c[n] - c[i + 1]))*modpow(mint(3), q[n] - 2);
			res += (mint)(q[i] * (q[n] - q[i + 1]))*modpow(mint(3), q[n] - 3);
		}
	}
	cout << res << endl;
}

Measured memory_bytes: 2816