#include "bits/stdc++.h"
// Begin Header {{{
#define all(x)      x.begin(), x.end()
#define SIZE(x)     static_cast<i64>(x.size())
#define rep(i,n)    for (i64 i = 0, i ## _limit = (n); i < i ## _limit; ++i)
#define reps(i,s,t) for (i64 i = (s), i ## _limit = (t); i <= i ## _limit; ++i)
#define repr(i,s,t) for (i64 i = (s), i ## _limit = (t); i >= i ## _limit; --i)

#ifdef DBG
#define trace(...) _trace(#__VA_ARGS__, __VA_ARGS__);
#else
#define trace(...)
#endif

using namespace std;
using i64 = int_fast64_t;
using pii = pair<i64, i64>;
template<class T, class U>inline bool chmax(T &a, const U &b){return b>a && (a=b, true);}
template<class T, class U>inline bool chmin(T &a, const U &b){return b<a && (a=b, true);}
constexpr int INF  = 0x3f3f3f3f;
constexpr i64 LINF = 0x3f3f3f3f3f3f3f3fLL;

template<class T>
ostream& operator<< (ostream &os, const vector<T> &vec) {
    rep(i, vec.size()) os << vec[i] << (i+1 == vec.size() ? "" : " ");
    return os;
}

template<class T, class U>
ostream& operator<< (ostream &os, const pair<T, U> &p) {
    return os << p.first << ' ' << p.second;
}

template <class T>
void _trace(const char *s, T&& x)
{
    clog << '{';
    while(*s != '\0') clog << *(s++);
    clog << ":" << setw(3) << x << '}' << endl;
}

template <class Head, class... Tail>
void _trace(const char *s, Head&& head, Tail&&... tail)
{
    clog << '{';
    while(*s != ',') clog << *(s++);
    clog << ":" << setw(3) << head << "}, ";
    for (++s; !isgraph(*s); ++s);
    _trace(s, std::forward<Tail>(tail)...);
}
// }}} End Header
// ModInt {{{
template<i64 MOD>
class ModInt {
private:
    i64 n;
public:
    inline ModInt(i64 n = 0) : n((n >= MOD) ? (n % MOD) : (n < 0) ? ((n + MOD) % MOD) : n) {}
    inline ModInt  operator~() const    { return pow(n, MOD-2); }
    inline ModInt& operator+=(ModInt o) { n = (n + o.n) % MOD; return *this; }
    inline ModInt& operator-=(ModInt o) { n = (MOD + n - o.n) % MOD; return *this; }
    inline ModInt& operator*=(ModInt o) { n = (n * o.n) % MOD; return *this; }
    inline ModInt& operator/=(ModInt o) { n = (n * (~o).n) % MOD; return *this; }
    inline bool operator==(ModInt o) const { return n == o.n; }
    inline bool operator!=(ModInt o) const { return !(*this == o); }
    template<class Int> explicit inline operator Int() const { return static_cast<Int>(n); }
    friend ostream& operator<<(ostream &os, ModInt o) { os << o.n; return os; }
    friend istream& operator>>(istream &is, ModInt &o) { is >> o.n; return is; }
    static constexpr inline ModInt pow(i64 n, i64 p) {
        i64 ret = 1;
        for(; p > 0; p >>= 1) {
            if (p & 1) ret = (ret * n) % MOD;
            n = (n * n) % MOD;
        }
        return ret;
    }
};
template<i64 MOD> auto operator+(ModInt<MOD> a, ModInt<MOD> b) { return ModInt<MOD>(a) += b; }
template<i64 MOD> auto operator-(ModInt<MOD> a, ModInt<MOD> b) { return ModInt<MOD>(a) -= b; }
template<i64 MOD> auto operator*(ModInt<MOD> a, ModInt<MOD> b) { return ModInt<MOD>(a) *= b; }
template<i64 MOD> auto operator/(ModInt<MOD> a, ModInt<MOD> b) { return ModInt<MOD>(a) /= b; }
// }}}

using modint = ModInt<int(1e9) + 7>;

string s;
int N;
i64 dp[100010][4];

modint slv(int idx, int cnt)
{
    if (idx >= N) {
        return (cnt == 3) ? 1 : 0;
    }
    if (~dp[idx][cnt]) return dp[idx][cnt];

    modint ans = 0;

    if (cnt == 3) {
        if (s[idx] == '?') {
            ans = slv(idx + 1, cnt) * modint(3);
        } else {
            ans = slv(idx + 1, cnt);
        }
    } else {
        if (s[idx] == '?') {
            ans = slv(idx + 1, cnt) * modint(3) + slv(idx + 1, cnt + 1);
        } else if (s[idx] == ('A' + cnt)) {
            ans = slv(idx + 1, cnt) + slv(idx + 1, cnt + 1);
        } else {
            ans = slv(idx + 1, cnt);
        }
    }

    return dp[idx][cnt] = (i64)ans;
}

signed main()
{
    // ios::sync_with_stdio(false); cin.tie(nullptr);

    cin >> s;
    N = SIZE(s);


    memset(dp, -1, sizeof(dp));
    cout << slv(0, 0) << endl;

    return 0;
}


Measured memory_bytes: 8320