//#define NDEBUG
#define _CRT_SECURE_NO_WARNINGS
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <type_traits>

class rep {
	const ::std::size_t f, l;

public:
	using value_type = ::std::size_t;
	using reference = value_type;
	class repitr {
		friend rep;
		value_type i;
		repitr(value_type x) noexcept : i(x) {}

	public:
		void operator++() noexcept { ++i; }
		reference operator*() const noexcept { return i; }
		bool operator!=(const repitr x) const noexcept { return i != x.i; }
	};
	explicit rep(value_type first, value_type last) noexcept
		: f(first), l(last) {}
	repitr begin() const noexcept { return repitr(f); }
	repitr end() const noexcept { return repitr(l); }
};
class revrep {
	const ::std::size_t f, l;

public:
	using value_type = ::std::size_t;
	using reference = value_type;
	class revrepitr {
		friend revrep;
		value_type i;
		revrepitr(value_type x) noexcept : i(x) {}

	public:
		void operator++() noexcept { --i; }
		reference operator*() const noexcept { return i; }
		bool operator!=(const revrepitr x) const noexcept { return i != x.i; }
	};
	explicit revrep(value_type first, value_type last) noexcept
		: f(first), l(last) {}
	revrepitr begin() const noexcept { return revrepitr(l - 1); }
	revrepitr end() const noexcept { return revrepitr(f - 1); }
};
template <class T> bool maxi(T &a, const T &b) {
	return b < a ? 0 : (a = b, 1);
}
template <class T> bool mini(T &a, const T &b) {
	return a < b ? 0 : (a = b, 1);
}
template <class T> bool smaxi(T &a, const T &b) {
	return a < b ? (a = b, 1) : 0;
}
template <class T> bool smini(T &a, const T &b) {
	return b < a ? (a = b, 1) : 0;
}
class customIN {
	int c;
	bool f = 0;
	void get_c() { c = fgetc(stdin); }
	bool vacant() const noexcept { return c == ' ' || c == '\n'; }
	void cueing() {
		while (get_c(), vacant())
			;
	}

public:
	template <class T>
	auto operator>>(T &d) ->
		typename ::std::enable_if<::std::is_signed<T>::value, customIN &>::type {
		d = 0;
		cueing();
		if (c == '-')
			f = 1, get_c();
		do
			d = d * 10 + c - '0';
		while (get_c(), !vacant());
		if (f)
			d = -d, f = 0;
		return *this;
	}
	template <class T>
	auto operator>>(T &d) ->
		typename ::std::enable_if<!::std::is_signed<T>::value, customIN &>::type {
		d = 0;
		cueing();
		do
			d = d * 10 + c - '0';
		while (get_c(), !vacant());
		return *this;
	}
	customIN &operator>>(char &d) {
		cueing();
		d = c;
		return *this;
	}
	customIN &operator>>(double &d) {
		scanf("%lf", &d);
		return *this;
	}
	customIN &operator>>(::std::string &d) {
		d.clear();
		cueing();
		do
			d.push_back(c);
		while (get_c(), !vacant());
		return *this;
	}
} IN;
class customOUT {
	int c;
	bool f = 0;
	::std::array<int, 30> buf;
	void put_c(const int x) const { fputc(x, stdout); }

public:
	template <class T>
	auto operator<<(T d) ->
		typename ::std::enable_if<::std::is_signed<T>::value, customOUT &>::type {
		c = 0;
		if (d < static_cast<T>(0))
			f = 1, d = -d;
		while (d)
			buf[c++] = d % 10 + '0', d /= 10;
		if (!c)
			buf[c++] = '0';
		if (f)
			put_c('-'), f = 0;
		while (c--)
			put_c(buf[c]);
		return *this;
	}
	template <class T>
	auto operator<<(T d) -> typename ::std::enable_if<!::std::is_signed<T>::value,
		customOUT &>::type {
		c = 0;
		while (d)
			buf[c++] = d % 10 + '0', d /= 10;
		if (!c)
			buf[c++] = '0';
		while (c--)
			put_c(buf[c]);
		return *this;
	}
	customOUT &operator<<(char d) {
		put_c(d);
		return *this;
	}
	customOUT &operator<<(const ::std::string &d) {
		for (const auto e : d)
			put_c(e);
		return *this;
	}
	customOUT &operator<<(const char *d) {
		while (*d != '\0')
			put_c(*(d++));
		return *this;
	}
	customOUT &operator<<(double d) {
		/*
		printf("%1.9f",d);
		/*/
		printf("%f", d);
		//*/
		return *this;
	}
	void endl() { put_c('\n'); }
	void space() { put_c(' '); }
	operator int() { return 0; }
} OUT;
template <class T = ::std::size_t> T scan() {
	T ret;
	IN >> ret;
	return ret;
}

#include <cstdint>

template <::std::uint_fast32_t MODULO> class modint {
	using uint32 = ::std::uint_fast32_t;
	using uint64 = ::std::uint_fast64_t;

public:
	using value_type = uint32;
	uint32 a;
	modint() noexcept : a(0) {}
	modint(const uint32 x) noexcept : a(x) {}
	uint32 value() const noexcept { return a; }
	modint operator+(const modint &o) const noexcept {
		return a + o.a < MODULO ? modint(a + o.a) : modint(a + o.a - MODULO);
	}
	modint operator-(const modint &o) const noexcept {
		return modint(a < o.a ? a + MODULO - o.a : a - o.a);
	}
	modint operator*(const modint &o) const noexcept {
		return modint(static_cast<uint64>(a) * o.a % MODULO);
	}
	modint operator/(const modint &o) const {
		return modint(static_cast<uint64>(a) * ~o % MODULO);
	}
	modint &operator+=(const modint &o) noexcept { return *this = *this + o; }
	modint &operator-=(const modint &o) noexcept { return *this = *this - o; }
	modint &operator*=(const modint &o) noexcept { return *this = *this * o; }
	modint &operator/=(const modint &o) { return *this = *this / o; }
	modint operator~() const noexcept { return pow(MODULO - 2); }
	modint operator-() const noexcept { return a ? modint(MODULO - a) : *this; }
	modint operator++() noexcept { return a == MODULO - 1 ? a = 0 : ++a, *this; }
	modint operator--() noexcept { return a ? --a : a = MODULO - 1, *this; }
	bool operator==(const modint &o) const noexcept { return a == o.a; }
	bool operator!=(const modint &o) const noexcept { return a != o.a; }
	bool operator<(const modint &o) const noexcept { return a < o.a; }
	bool operator<=(const modint &o) const noexcept { return a <= o.a; }
	bool operator>(const modint &o) const noexcept { return a > o.a; }
	bool operator>=(const modint &o) const noexcept { return a >= o.a; }
	explicit operator bool() const noexcept { return a; }
	explicit operator uint32() const noexcept { return a; }
	modint pow(uint32 x) const noexcept {
		uint64 t = a, u = 1;
		while (x) {
			if (x & 1)
				u = u * t % MODULO;
			t = (t * t) % MODULO;
			x >>= 1;
		}
		return modint(u);
	}
};


using int32 = ::std::int_fast32_t;
using int64 = ::std::int_fast64_t;
using uint32 = ::std::uint_fast32_t;
using uint64 = ::std::uint_fast64_t;
using intl32 = ::std::int_least32_t;
using intl64 = ::std::int_least64_t;
using uintl32 = ::std::uint_least32_t;
using uintl64 = ::std::uint_least64_t;

#include <algorithm>
#include <utility>
#include <vector>
#include <string>

template <class T> using vec_alias = ::std::vector<T>;

int main() {
	using mint = modint<1000000007>;
	::std::string s;
	IN >> s;
	mint a = 0, ab = 0, abc = 0, cnt = 1;

	for (const auto c : s) {
		if (c == 'A') {
			a += cnt;
		}
		if (c == 'B') {
			ab += a;
		}
		if (c == 'C') {
			abc += ab;
		}
		if (c == '?') {
			abc = abc * 3 + ab;
			ab = ab * 3 + a;
			a = a * 3 + cnt;
			cnt *= 3;
		}
	}

	OUT << abc.a << '\n';
	return 0;
}


Measured memory_bytes: 512