#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define EPS (1e-7)
#define INF (1e9)
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define all(x) x.begin(),x.end()
#define pii pair<int, int>
#define pll pair<long long, long long>
const double PI = acos(-1);
const ll MOD = 1000000007;
// const ll MOD = 998244353;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}
 
template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}
///////////////////////////////////////////////////////////////
 
template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;
 
public:
  u64 a;
 
  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};
 
using mint = modint<MOD>;
 
int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    string S; cin >> S;
    int N = S.size();
 
    vector<ll> A(N+1),B(N+1),C(N+1),D(N+1),BC(N+1),AB(N+1);
 
    rep(i,N) {
        if (S[i] == 'A') A[i+1] = 1LL;
        if (S[i] == 'B') B[i+1] = 1LL;
        if (S[i] == 'C') C[i+1] = 1LL;
        if (S[i] == '?') D[i+1] = 1LL;
    }
    rep(i,N) {
        A[i+1] += A[i];
        B[i+1] += B[i];
        C[i+1] += C[i];
        D[i+1] += D[i];
    }
    mint ans = 0;
    mint k3 = 1;
    rep(i,D[N]-3) k3*=3;
    mint k2 = 1;
    rep(i,D[N]-2) k2*=3;
    mint k1 = 1;
    rep(i,D[N]-1) k1*=3;
    mint k0 = 1;
    rep(i,D[N]) k0 *= 3;
    rep(i,N) {
        if (S[i] == 'A') ans += k2*((D[N] - D[i+1])*(D[N] - D[i+1]-1LL)/2LL);
        if (S[i] == 'B') {
            ans += k2*D[i]*(D[N] - D[i+1]);
            ans += k0*A[i]*(C[N]-C[i+1]);
            BC[i] = C[N]-C[i+1];
            AB[i] = A[i];
        }
        if (S[i] == 'C') ans += k2*(D[i]*(D[i]-1LL)/2LL);
    }
    rep(i,N) {
        AB[i+1] += AB[i];
        BC[N-1-i] += BC[N-i];
    }
    rep(i,N) {
        if (S[i] == '?') {
            ans += k1*(AB[i]+BC[i]);
            ans += k3*D[i]*(D[N]-D[i+1]);
            ans += k1*A[i]*(C[N]-C[i+1]);
        }
    }
 
    cout << ans.a << endl;
} 

Measured memory_bytes: 5200