We have 3N colored balls with IDs from 1 to 3N. A string S of length 3N represents the colors of the balls. The color of Ball i is red if S_i is `R`, green if S_i is `G`, and blue if S_i is `B`. There are N red balls, N green balls, and N blue balls.

Takahashi will distribute these 3N balls to N people so that each person gets one red ball, one blue ball, and one green ball. The people want balls with IDs close to each other, so he will additionally satisfy the following condition:

* Let a_j < b_j < c_j be the IDs of the balls received by the j-th person in ascending order.
* Then, \sum_j (c_j-a_j) should be as small as possible.



Find the number of ways in which Takahashi can distribute the balls. Since the answer can be enormous, compute it modulo 998244353. We consider two ways to distribute the balls different if and only if there is a person who receives different sets of balls.

Constraints

* 1 \leq N \leq 10^5
* |S|=3N
* S consists of `R`, `G`, and `B`, and each of these characters occurs N times in S.

Input

Input is given from Standard Input in the following format:


N
S


Output

Print the number of ways in which Takahashi can distribute the balls, modulo 998244353.

Examples

Input

3
RRRGGGBBB


Output

216


Input

5
BBRGRRGRGGRBBGB


Output

960
import java.io.*;
import java.util.Arrays;
import java.util.StringJoiner;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    static int N;
    static String S;

    public static void main(String[] args) {
        FastScanner sc = new FastScanner(System.in);
        N = sc.nextInt();
        S = sc.next();

        System.out.println(solve());
    }

    static int solve() {
        int ans = 1;
        // 特にatomicにしたいわけではなくinc/decできる箱くらいの気持ち
        // ぽいんたないからね...
        AtomicInteger r = new AtomicInteger(), g = new AtomicInteger(), b = new AtomicInteger();
        AtomicInteger rg = new AtomicInteger(), rb = new AtomicInteger(), gb = new AtomicInteger();
        for (int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);
            if( c == 'R' ) {
                ans = calc(r, g, b, rg, rb, gb, ans);

            } else if( c == 'G' ) {
                ans = calc(g, r, b, rg, gb, rb, ans);
                
            } else {
                ans = calc(b, g, r, gb, rb, rg, ans);
            }
        }

        ans = mul(ans, fact(N));
        return ans;
    }

    static int calc(AtomicInteger a, AtomicInteger b, AtomicInteger c, AtomicInteger ab, AtomicInteger ac, AtomicInteger bc, int ans) {
        // くっつくやつがいたらくっつける
        // くっつける対象の自由度分ansを増やす
        if( bc.get() > 0 ) {
            ans = mul(ans, bc.getAndDecrement());

        } else if( b.get() > 0 ) {
            ans = mul(ans, b.getAndDecrement());
            ab.incrementAndGet();

        } else if( c.get() > 0 ) {
            ans = mul(ans, c.getAndDecrement());
            ac.incrementAndGet();

        } else {
            a.incrementAndGet();
        }
        return ans;
    }

    static int MOD = 998244353;

    static int fact(int n) {
        int ret = 1;
        for (int i = 2; i <= n; i++) {
            ret = mul(ret, i);
        }
        return ret;
    }

    static int mul(int a, int b) {
        long c = (long)a * b;
        c %= MOD;
        return (int)c;
    }

    @SuppressWarnings("unused")
    static class FastScanner {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        FastScanner(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
            tokenizer = null;
        }

        String next() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        String nextLine() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    return reader.readLine();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken("\n");
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int[] nextIntArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++) a[i] = nextInt();
            return a;
        }

        int[] nextIntArray(int n, int delta) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++) a[i] = nextInt() + delta;
            return a;
        }

        long[] nextLongArray(int n) {
            long[] a = new long[n];
            for (int i = 0; i < n; i++) a[i] = nextLong();
            return a;
        }
    }

    static void writeLines(int[] as) {
        PrintWriter pw = new PrintWriter(System.out);
        for (int a : as) pw.println(a);
        pw.flush();
    }

    static void writeLines(long[] as) {
        PrintWriter pw = new PrintWriter(System.out);
        for (long a : as) pw.println(a);
        pw.flush();
    }

    static void writeSingleLine(int[] as) {
        PrintWriter pw = new PrintWriter(System.out);
        for (int i = 0; i < as.length; i++) {
            if (i != 0) pw.print(" ");
            pw.print(as[i]);
        }
        pw.println();
        pw.flush();
    }

    static int max(int... as) {
        int max = Integer.MIN_VALUE;
        for (int a : as) max = Math.max(a, max);
        return max;
    }

    static int min(int... as) {
        int min = Integer.MAX_VALUE;
        for (int a : as) min = Math.min(a, min);
        return min;
    }

    static void debug(Object... args) {
        StringJoiner j = new StringJoiner(" ");
        for (Object arg : args) {
            if (arg == null) j.add("null");
            else if (arg instanceof int[]) j.add(Arrays.toString((int[]) arg));
            else if (arg instanceof long[]) j.add(Arrays.toString((long[]) arg));
            else if (arg instanceof double[]) j.add(Arrays.toString((double[]) arg));
            else if (arg instanceof Object[]) j.add(Arrays.toString((Object[]) arg));
            else j.add(arg.toString());
        }
        System.err.println(j.toString());
    }

    static void printSingleLine(int[] array) {
        PrintWriter pw = new PrintWriter(System.out);
        for (int i = 0; i < array.length; i++) {
            if (i != 0) pw.print(" ");
            pw.print(array[i]);
        }
        pw.println();
        pw.flush();
    }

    static int lowerBound(int[] array, int value) {
        int lo = 0, hi = array.length, mid;
        while (lo < hi) {
            mid = (hi + lo) / 2;
            if (array[mid] < value) lo = mid + 1;
            else hi = mid;
        }
        return lo;
    }

    static int upperBound(int[] array, int value) {
        int lo = 0, hi = array.length, mid;
        while (lo < hi) {
            mid = (hi + lo) / 2;
            if (array[mid] <= value) lo = mid + 1;
            else hi = mid;
        }
        return lo;
    }
}
