#ifndef CLASS_MODINT
#define CLASS_MODINT

#include <cstdint>

template<std::uint32_t mod>
class modint {
private:
	std::uint32_t n;
public:
	modint() : n(0) {};
	modint(std::int64_t n_) : n((n_ >= 0 ? n_ : mod - (-n_) % mod) % mod) {};
	static constexpr std::uint32_t get_mod() { return mod; }
	std::uint32_t get() const { return n; }
	bool operator==(const modint& m) const { return n == m.n; }
	bool operator!=(const modint& m) const { return n != m.n; }
	modint& operator+=(const modint& m) { n += m.n; n = (n < mod ? n : n - mod); return *this; }
	modint& operator-=(const modint& m) { n += mod - m.n; n = (n < mod ? n : n - mod); return *this; }
	modint& operator*=(const modint& m) { n = std::uint64_t(n) * m.n % mod; return *this; }
	modint operator+(const modint& m) const { return modint(*this) += m; }
	modint operator-(const modint& m) const { return modint(*this) -= m; }
	modint operator*(const modint& m) const { return modint(*this) *= m; }
	modint inv() const { return (*this).pow(mod - 2); }
	modint pow(std::uint64_t b) const {
		modint ans = 1, m = modint(*this);
		while (b) {
			if (b & 1) ans *= m;
			m *= m;
			b >>= 1;
		}
		return ans;
	}
};

#endif // CLASS_MODINT

#include <vector>
#include <complex>
#include <iostream>
#include <algorithm>
using namespace std;
using modulo = modint<998244353>;
int N; string S; complex<double> y[524299];
void dft(int sz, complex<double> *x, bool inv) {
	for (int i = sz >> 1; i >= 1; i >>= 1) {
		complex<double> bs = polar(1.0, 2.0 * acos(-1) * i / sz * (inv ? -1.0 : 1.0)), w = 1;
		for (int j = 0; 2 * j < sz; j += i) {
			for (int k = 0; k < i; k++) {
				y[j + k] = x[2 * j + k] + w * x[2 * j + i + k];
				y[j + k + (sz >> 1)] = x[2 * j + k] - w * x[2 * j + i + k];
			}
			w *= bs;
		}
		for (int j = 0; j < sz; j++) x[j] = y[j];
	}
	if (inv) for (int i = 0; i < sz; i++) x[i] /= sz;
}
complex<double> lu[262155], lq[262155], rg[262155], rq[262155], ug[262155], uq[262155], qg[262155], qq[262155];
long long solve(int l, int r) {
	if (r - l <= 2) return 0;
	int m = (l + r) >> 1, sz = 1, maxintv = max(m - l, r - m);
	while (sz < maxintv * 2) sz *= 2;
	fill(lu, lu + sz, complex<double>(0));
	fill(lq, lq + sz, complex<double>(0));
	fill(rg, rg + sz, complex<double>(0));
	fill(rq, rq + sz, complex<double>(0));
	fill(ug, ug + sz, complex<double>(0));
	fill(uq, uq + sz, complex<double>(0));
	fill(qg, qg + sz, complex<double>(0));
	fill(qq, qq + sz, complex<double>(0));
	for (int i = l; i < m; ++i) {
		if (S[i] == 'U') lu[i - l] = 1;
		if (S[i] == '?') lq[i - l] = 1;
	}
	for (int i = m; i < r; ++i) {
		if (S[i] == 'G') rg[i - m] = 1;
		if (S[i] == '?') rq[i - m] = 1;
	}
	dft(sz, lu, false);
	dft(sz, lq, false);
	dft(sz, rg, false);
	dft(sz, rq, false);
	for (int i = 0; i < sz; ++i) {
		ug[i] = lu[i] * rg[i];
		uq[i] = lu[i] * rq[i];
		qg[i] = lq[i] * rg[i];
		qq[i] = lq[i] * rq[i];
	}
	dft(sz, ug, true);
	dft(sz, uq, true);
	dft(sz, qg, true);
	dft(sz, qq, true);
	long long ans = 0;
	for (int i = l; i < r; ++i) {
		int pos = i * 2 - l - m;
		if (0 <= pos && pos <= r - l - 2 && (S[i] == 'M' || S[i] == '?')) {
			long long subans = 0;
			subans += int(ug[pos].real() + 0.5) * 9;
			subans += int(uq[pos].real() + 0.5) * 3;
			subans += int(qg[pos].real() + 0.5) * 3;
			subans += int(qq[pos].real() + 0.5) * 1;
			ans += subans * (S[i] == 'M' ? 3 : 1);
		}
	}
	ans += solve(l, m);
	ans += solve(m, r);
	return ans;
}
int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	cin >> S;
	N = S.size();
	long long ans = solve(0, N);
	modulo mult = 1;
	for (int i = 0; i < N; ++i) {
		if (S[i] == '?') mult *= 3;
	}
	mult *= modulo(27).inv();
	mult *= modulo(ans);
	cout << mult.get() << endl;
	return 0;
}


Measured memory_bytes: 40556