Problem:
Score : 700 points

Problem Statement

You are given a string S consisting of a,b and c. Find the number of strings that can be possibly obtained by repeatedly performing the following operation zero or more times, modulo 998244353:

Choose an integer i such that 1\leq i\leq |S|-1 and the i-th and (i+1)-th characters in S are different. Replace each of the i-th and (i+1)-th characters in S with the character that differs from both of them (among a, b and c).

Constraints

2 \leq |S| \leq 2 × 10^5

S consists of a, b and c.

Input

Input is given from Standard Input in the following format:

S

Output

Print the number of strings that can be possibly obtained by repeatedly performing the operation, modulo 998244353.

Sample Input 1

abc

Sample Output 1

3

abc, aaa and ccc can be obtained.

Sample Input 2

abbac

Sample Output 2

65

Sample Input 3

babacabac

Sample Output 3

6310

Sample Input 4

ababacbcacbacacbcbbcbbacbaccacbacbacba

Sample Output 4

148010497

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

#define NDEBUG
#include <cassert>

typedef long long ll;
typedef long double Double;
typedef unsigned long long ull;
typedef pair<int,int> ii;
typedef pair<ll,ll> llll;
typedef pair<double,double> dd;

typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ii> vii;
typedef vector<vector<ii>> vvii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<long double> vD;

#define sz(a)  int((a).size())
#define pb  push_back
#define FOR(var,from,to) for(int var=(from);var<=(to);++var)
#define rep(var,n)  for(int var=0;var<(n);++var)
#define rep1(var,n)  for(int var=1;var<=(n);++var)
#define repC2(vari,varj,n)  for(int vari=0;vari<(n)-1;++vari)for(int varj=vari+1;varj<(n);++varj)
#define ALL(c)  (c).begin(),(c).end()
#define RALL(c)  (c).rbegin(),(c).rend()
#define tr(i,c)  for(auto i=(c).begin(); i!=(c).end(); ++i)
#define found(s,e)  ((s).find(e)!=(s).end())
#define mset(arr,val)  memset(arr,val,sizeof(arr))
#define mid(x,y) ((x)+((y)-(x))/2)
#define IN(x,a,b) ((a)<=(x)&&(x)<=(b))
#define cons make_pair


ll gcd(ll a, ll b) { while(a) swap(a, b%=a); return b; }

const ll MOD = 998244353LL;

ll ADD(ll x, ll y) { return (x+y) % MOD; }
ll SUB(ll x, ll y) { return (x-y+MOD) % MOD; }
ll MUL(ll x, ll y) { return x*y % MOD; }
ll POW(ll x, ll e) { ll v=1; for(; e; x=MUL(x,x), e>>=1) if (e&1) v = MUL(v,x); return v; }
ll DIV(ll x, ll y) { /*assert(y%MOD!=0);*/ return MUL(x, POW(y, MOD-2)); }

ll solve2(vi& s){
    assert(s.size() == 2);
    assert(s[0] != s[1]);
    return 2;
}
ll solve3(vi& s){
    assert(s.size() == 3);
    queue<vi> q;
    set<vi> visited;
    q.push(s);
    while (!q.empty()){
        vi t = q.front(); q.pop();
        if (found(visited, t)) continue;
        visited.insert(t);
        if (t[0] != t[1]) {
            int r = 3 - t[0] - t[1];
            q.push(vi{ r, r, t[2] });
        }
        if (t[1] != t[2]) {
            int r = 3 - t[1] - t[2];
            q.push(vi{ t[0], r, r });
        }
    }
    return visited.size();
}
ll solveL(int L, vi& s){
    int m = accumulate(ALL(s), 0) % 3;
    bool has_cont = false;
    rep(i,L-1){
        if (s[i] == s[i+1]) { has_cont = true; break; }
    }

    vector<vector<ll>> dp(3, vector<ll>(3, 0));
    rep(i,3) dp[i][i] = 1;
    rep(i,L-1){
        vector<vector<ll>> dp2(3, vector<ll>(3, 0));
        rep(n,3) rep(r,3){
            ll prev = dp[n][r];
            rep(i,3) {
                if (i == n) continue;
                int ri = (r+i)%3;
                dp2[i][ri] = ADD(dp2[i][ri], prev);
            }
        }
        dp = dp2;
    }

    ll Q = 0;
    rep(n,3) Q += dp[n][m];
    Q = Q % MOD;

    ll P = POW(3, L-1);
    return SUB(ADD(P, has_cont?0:1), Q);
}
ll solve(string& S){
    int L = S.size();
    set<char> sc(ALL(S));
    if (sc.size() == 1) return 1;

    vi s(L);
    rep(i,L) {
        sc.insert(S[i]);
        s[i] = (S[i] - 'a');
    }

    switch (L) {
        case 2:
            return solve2(s);
        case 3:
            return solve3(s);
        default:
            return solveL(L, s);
    }
}

int main() {
    string S; cin >> S;
    cout << solve(S) << endl;
    return 0;
}