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 Kotlin (1.0.0) (judge verdict: Wrong Answer)

import java.util.*

const val P = 998244353L

data class FiniteField(val x: Long) {
  constructor(xi: Int): this(xi.toLong())
  operator fun plus(o: FiniteField) = FiniteField((x + o.x) % P)
  operator fun plus(o: Int) = this + FiniteField(o)
  operator fun minus(o: FiniteField) = FiniteField((x + P - o.x) % P)
  operator fun minus(o: Int) = this - FiniteField(o)
}

fun solveBruteForce(s: String): Int {
  val q = ArrayDeque<String>()
  q.offerLast(s)
  val set = mutableSetOf<String>()
  set.add(s)
  while (q.isNotEmpty()) {
    val state = q.pollFirst()
    for (i in 0 until (state.length - 1)) {
      if (state[i] != state[i + 1]) {
        val c1 = state[i]
        val c2 = state[i + 1]
        ('a'..'c').forEach {
          if (c1 != it && c2 != it) {
            val nextBuilder = StringBuilder(state)
            nextBuilder[i] = it
            nextBuilder[i + 1] = it
            val next = nextBuilder.toString()
            if (!set.contains(next)) {
              q.offerLast(next)
              set.add(next)
            }
          }
        }
      }
    }
  }
  return set.size
}

fun cToI(c: Char) = c - 'a'

fun main(args: Array<String>) {
  val s = readLine()!!
  if (s.length <= 3) {
    println(solveBruteForce(s))
    return
  }
  val n = s.length
  // [element index][mod][last]
  val dp1 = Array(n, { Array(3, { LongArray(3, { 0L }) }) })
  val dp2 = Array(n, { Array(3, { LongArray(3, { 0L }) }) })
  for (x in 0..2) {
    dp1[0][x][x] = 1L
    dp2[0][x][x] = 1L
  }
  for (k in 0 until n - 1) {
    for (m in 0..2) {
      for (x in 0..2) {
        for (y in 0..2) {
          dp1[k + 1][(m + y) % 3][y] += dp1[k][m][x]
          dp1[k + 1][(m + y) % 3][y] %= P
          if (x != y) {
            dp2[k + 1][(m + y) % 3][y] += dp2[k][m][x]
            dp2[k + 1][(m + y) % 3][y] %= P
          }
        }
      }
    }
  }
  val sMod = s.map(::cToI).sum() % 3
  val t1 = dp1[n - 1][sMod].sum() % P
  val t2 = dp2[n - 1][sMod].sum() % P
  val sCount = !(0 until n - 1).any { s[it] == s[it + 1] }
  val ans = (t1 + P - t2 + if (sCount) 1 else 0) % P
  println(ans)
}