;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (ql:quickload '(:cl-debug-print :fiveam))
  #-swank (set-dispatch-macro-character #\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil (values) t))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(declaim (inline bisect-left))
(defun bisect-left (target value &key (start 0) end (order #'<) (key #'identity))
  "TARGET := vector | function (taking an integer argument)
ORDER := strict order

Analogue of lower_bound of C++ or bisect_left of Python: Returns the smallest
index (or input) i that fulfills TARGET[i] >= VALUE, where '>=' is the
complement of ORDER. In other words, this function returns the leftmost index at
which VALUE can be inserted with keeping the order. Therefore, TARGET must be
monotonically non-decreasing with respect to ORDER.

This function returns END if VALUE exceeds TARGET[END-1]. Note that the range
[START, END) is half-open. END must be explicitly specified if TARGET is
function. KEY is applied to each element of TARGET before comparison."
  (declare (function key order)
           (integer start)
           ((or null integer) end))
  (macrolet
      ((body (accessor &optional declaration)
         `(progn
            (assert (<= start end))
            (if (= start end) end
                (labels
                    ((%bisect-left (left ok)
                       ;; TARGET[OK] >= VALUE always holds (assuming
                       ;; TARGET[END] = +infinity)
                       ,@(list declaration)
                       (let ((mid (ash (+ left ok) -1)))
                         (if (= mid left)
                             (if (funcall order (funcall key (,accessor target left)) value)
                                 ok
                                 left)
                             (if (funcall order (funcall key (,accessor target mid)) value)
                                 (%bisect-left mid ok)
                                 (%bisect-left left mid))))))
                  (%bisect-left start end))))))
    (etypecase target
      (vector
       (let ((end (or end (length target))))
         (body aref (declare ((integer 0 #.most-positive-fixnum) left ok)))))
      (function
       (assert end () "Requires END argument if TARGET is a function.")
       (body funcall)))))

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 998244353)

;; Body
;;;
;;; Arithmetic operations with static modulus
;;;

(defmacro define-mod-operations (&optional (divisor 1000000007))
  `(progn
     (defun mod* (&rest args)
       (reduce (lambda (x y) (mod (* x y) ,divisor)) args))

     (sb-c:define-source-transform mod* (&rest args)
       (if (null args)
           1
           (reduce (lambda (x y) `(mod (* ,x ,y) ,',divisor)) args)))

     (defun mod+ (&rest args)
       (reduce (lambda (x y) (mod (+ x y) ,divisor)) args))

     (sb-c:define-source-transform mod+ (&rest args)
       (if (null args)
           0
           (reduce (lambda (x y) `(mod (+ ,x ,y) ,',divisor)) args)))

     (define-modify-macro incfmod (delta divisor)
       (lambda (x y divisor) (mod (+ x y) divisor)))

     (define-modify-macro decfmod (delta divisor)
       (lambda (x y divisor) (mod (- x y) divisor)))))

(define-mod-operations +mod+)

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (s (read-line))
         (rs (make-array n :element-type 'uint32 :fill-pointer 0))
         (gs (make-array n :element-type 'uint32 :fill-pointer 0))
         (bs (make-array n :element-type 'uint32 :fill-pointer 0))
         (mins (make-array n :element-type 'uint32))
         (maxs (make-array n :element-type 'uint32))
         (mids (make-array n :element-type 'uint32))
         (res 1))
    (declare (uint31 n res)
             (simple-string s))
    (dotimes (i (* 3 n))
      (case (aref s i)
        (#\R (vector-push i rs))
        (#\G (vector-push i gs))
        (#\B (vector-push i bs))))
    (dotimes (i n)
      (setf (aref maxs i) (max (aref rs i) (aref gs i) (aref bs i))
            (aref mins i) (min (aref rs i) (aref gs i) (aref bs i)))
      (setf (aref mids i)
            (cond ((< (aref mins i) (aref rs i) (aref maxs i))
                   (aref rs i))
                  ((< (aref mins i) (aref gs i) (aref maxs i))
                   (aref gs i))
                  ((< (aref mins i) (aref bs i) (aref maxs i))
                   (aref bs i))
                  (t (error "Huh?")))))
    (loop for i below n
          for mid = (aref mids i)
          for left-count = (bisect-left mins mid)
          for right-count = (- n (bisect-left maxs mid))
          do (setq res (mod* res (the uint31 (- left-count i))))
             (setq res (mod* res (the uint31 (- right-count (- n 1 i))))))
    (dotimes (i n)
      (setq res (mod* res (+ i 1))))
    (println res)))

#-swank (main)


Measured memory_bytes: 41956