Problem:
Score : 400 points

Problem Statement

Takahashi has a string S consisting of lowercase English letters.

Starting with this string, he will produce a new one in the procedure given as follows.

The procedure consists of Q operations. In Operation i (1 \leq i \leq Q), an integer T_i is provided, which means the following:

If T_i = 1: reverse the string S.

If T_i = 2: An integer F_i and a lowercase English letter C_i are additionally provided.

If F_i = 1 : Add C_i to the beginning of the string S.

If F_i = 2 : Add C_i to the end of the string S.

Help Takahashi by finding the final string that results from the procedure.

Constraints

1 \leq |S| \leq 10^5

S consists of lowercase English letters.

1 \leq Q \leq 2 \times 10^5

T_i = 1 or 2.

F_i = 1 or 2, if provided.

C_i is a lowercase English letter, if provided.

Input

Input is given from Standard Input in the following format:

S
Q
Query_1
:
Query_Q

In the 3-rd through the (Q+2)-th lines, Query_i is one of the following:

1

which means T_i = 1, and:

2 F_i C_i

which means T_i = 2.

Output

Print the resulting string.

Sample Input 1

a
4
2 1 p
1
2 2 c
1

Sample Output 1

cpa

There will be Q = 4 operations. Initially, S is a.

Operation 1: Add p at the beginning of S. S becomes pa.

Operation 2: Reverse S. S becomes ap.

Operation 3: Add c at the end of S. S becomes apc.

Operation 4: Reverse S. S becomes cpa.

Thus, the resulting string is cpa.

Sample Input 2

a
6
2 2 a
2 1 b
1
2 2 c
1
1

Sample Output 2

aabc

There will be Q = 6 operations. Initially, S is a.

Operation 1: S becomes aa.

Operation 2: S becomes baa.

Operation 3: S becomes aab.

Operation 4: S becomes aabc.

Operation 5: S becomes cbaa.

Operation 6: S becomes aabc.

Thus, the resulting string is aabc.

Sample Input 3

y
1
2 1 x

Sample Output 3

xy

Solution in C# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

namespace AtCoder
{
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;

    class Program
    {
        static void Main()
        {
            var s = System.Console.ReadLine();
            var q = System.Console.ReadLine().ToInt32();
            var revcnt = 0;
            for (int i = 0; i < q; i++)
            {
                var a = System.Console.ReadLine().Split(' ').ToArray();
                //T1
                if (a[0] == "1")
                {
                    revcnt++;
                    continue;
                }
                //T2 F1
                if (a[1] == "1" && revcnt % 2 == 0
                    || a[1] == "2" && revcnt % 2 == 1)
                {
                    s = a[2] + s;
                }
                //T2 F2
                else
                {
                    s = s + a[2];
                }
            }
            //revcntが奇数ならリバース
            if (revcnt % 2 == 1)
            {
                s = string.Concat(s.Reverse());
            }
            Output(s.ToString());
        }
        private static void Output(string str)
        {
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);

            Console.WriteLine(str);

            Console.Out.Flush();
        }

    }

    static class Extentions
    {
        #region 拡張メソッド（string）

        public static string LeftB(this string stTarget, int iByteSize)
        {
            return MidB(stTarget, 1, iByteSize);
        }

        public static string MidB(this string stTarget, int iStart)
        {
            System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("utf-8");
            byte[] bBytes = hEncoding.GetBytes(stTarget);

            return hEncoding.GetString(bBytes, iStart - 1, bBytes.Length - iStart + 1);
        }

        public static string MidB(this string stTarget, int iStart, int iByteSize)
        {
            System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("utf-8");
            byte[] bBytes = hEncoding.GetBytes(stTarget);

            return hEncoding.GetString(bBytes, iStart - 1, iByteSize);
        }

        public static string RightB(this string stTarget, int iByteSize)
        {
            System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("utf-8");
            byte[] bBytes = hEncoding.GetBytes(stTarget);

            return hEncoding.GetString(bBytes, bBytes.Length - iByteSize, iByteSize);
        }

        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }

        /// <summary>
        /// カルチャに依存した比較、または大文字と小文字を区別しない比較などの序数による比較を指定できる Contains。
        /// </summary>
        /// <param name="value">対象文字列</param>
        /// <param name="partialValue">部分文字列</param>
        /// <param name="comparison">カルチャ、大文字と小文字の区別、および並べ替え規則を指定する StringComparison</param>
        /// <returns>一致する場合に true を返します。</returns>
        public static bool Contains(this string value, string partialValue, StringComparison comparison = 0)
        {
            return value.IndexOf(partialValue, comparison) >= 0;
        }

        public static bool IsNumeric(this string value)
        {
            return decimal.TryParse(value, out decimal d);
        }
        public static int ToInt32(this String number, int retValue = 0)
        {
            if (!number.IsNumeric()) return retValue;
            return int.Parse(number);
        }

        #endregion
    }

}


#region Template

/*
    using System;
    using System.Collections.Generic;
    using System.Linq;

    // 整数の入力========================================
    string[] input = Console.ReadLine().Split(' ');
    int a = int.Parse(input[0]);
    int b = int.Parse(input[1]);
    int c = int.Parse(Console.ReadLine());
    
    //配列操作========================================
    var a = System.Console.ReadLine().Split(' ').Select((x) => long.Parse(x)).ToArray();

    int[] a = new int[n];
    for (int i = 0; i < n; i++)
    {
        a[i] = int.Parse(input2[i]);
    }
    
    Array.Sort(a);
    Array.Reverse(a);
    
    // 最小公倍数========================================
    public static decimal Lcm(decimal a, decimal b)
    {
        return a * b / Gcd(a, b);
    }

    // ユークリッドの互除法 ========================================
    public static decimal Gcd(decimal a, decimal b)
    {
        if (a < b)
        {
            // 引数を入替えて自分を呼び出す
            return Gcd(b, a);
        }
        while (b != 0)
        {
            var remainder = a % b;
            a = b;
            b = remainder;
        }
        return a;
    }

    // 全bit探索========================================
    
    // input桁のbit列で全探索を行う
    for (int x = 0; x < Math.Pow(2, input.Length); x++)
    {
        var array = new bool[input.Length];

        // 右からk桁目を取り出す
        for (int k = 0; k < input.Length; k++)
        {
            var y = (x >> k) & 1;
            array[k] = y==1;
        }
    }

    // DFS(深さ探索)========================================
    
    static void Main()
    {
        var input = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
        var h = input[0];
        var w = input[1];
        var meiro = new char[w, h];
        var reached = new bool[w, h];
        var sh = 0;
        var sw = 0;
        var gh = 0;
        var gw = 0;
        for (int i = 0; i < h; i++)
        {
            var x = Console.ReadLine();
            for (int j = 0; j < w; j++)
            {
                meiro[j, i] = x[j];
                // スタートとゴール地点を退避
                if (x[j] == 's')
                {
                    sh = i;
                    sw = j;
                }
                if (x[j] == 'g')
                {
                    gh = i;
                    gw = j;
                }
            }
        }

        Search(sw, sh, meiro, reached);

        var ans = "No";
        if (reached[gw, gh] == true)
        {
            ans = "Yes";
        }
        Output(ans);
    }
    private static void Search(int x, int y, char[,] meiro, bool[,] reached)
    {
        // 壁や迷路の外なら脱出
        if (x < 0 || y < 0 || x > meiro.GetLength(0) - 1 || y > meiro.GetLength(1) - 1 || meiro[x, y] == '#') return;
        // 到達済みの場合も脱出
        if (reached[x, y] == true) return;
        // 到達記録
        reached[x, y] = true;

        Search(x + 1, y, meiro, reached);
        Search(x, y + 1, meiro, reached);
        Search(x - 1, y, meiro, reached);
        Search(x, y - 1, meiro, reached);
    }


    // DFS(深さ探索)========================================
    static void Main()
    {
        var input = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
        var r = input[0];
        var c = input[1];
        var meiro = new char[r, c];
        var passed = new bool[r, c];
        var start = Console.ReadLine().Split(' ').Select(x => int.Parse(x) -1).ToList();
        var goal = Console.ReadLine().Split(' ').Select(x => int.Parse(x) -1).ToArray();
        for (int i = 0; i < r; i++)
        {
            var x = Console.ReadLine();
            for (int j = 0; j < c; j++)
            {
                meiro[i, j] = x[j];
            }
        }

        var numMoves = new int[r, c];
        var que = new Queue<int[]>();
        start.Add(0); // 深さ
        que.Enqueue(start.ToArray());
        BFS(que, passed, numMoves, meiro);

        Output(numMoves[goal[0], goal[1]].ToString());
    }
    private static void BFS(Queue<int[]> que, bool[,] passed, int[,] numMoves, char[,] meiro)
    {
        while (que.Count() > 0)
        {
            var p = que.Dequeue();

            var x = p[0];
            var y = p[1];
            // 壁や迷路の外なら脱出
            if (x < 0 || y < 0 || x > meiro.GetLength(0) - 1 || y > meiro.GetLength(1) - 1 || meiro[x, y] == '#') continue;
            // 到達済みの場合も脱出
            if (passed[x, y] == true) continue;
            // 到達記録
            passed[x, y] = true;
            numMoves[x, y] = p[2];
            que.Enqueue(new int[3] { x - 1, y    , p[2] + 1 });
            que.Enqueue(new int[3] { x + 1, y    , p[2] + 1 });
            que.Enqueue(new int[3] { x,     y - 1, p[2] + 1 });
            que.Enqueue(new int[3] { x,     y + 1, p[2] + 1 });
        }
    }

    //二分探索==============================================

    
        static void Main()
        {
            var n = Console.ReadLine().ToInt32();
            var a = System.Console.ReadLine().Split(' ').Select((x) => long.Parse(x)).ToArray();
            var b = System.Console.ReadLine().Split(' ').Select((x) => long.Parse(x)).ToArray();
            var c = System.Console.ReadLine().Split(' ').Select((x) => long.Parse(x)).ToArray();

            long ans = 0;
            for (int i = 0; i < a.Count(); i++)
            {
                var aIdx = LowerBound(a, b[i]) - 1;
                if (aIdx < 0) continue;

                var cIdx = UpperBound(c, b[i]);
                if (cIdx > n - 1) continue;

                //組み合わせ
                long combi = (long)(aIdx + 1) * (long)(n - cIdx);
                ans += combi;
            }
            Output(ans.ToString());

        }
        private static int LowerBound(long[] arr, long target)
        {
            var min = 0;
            var max = arr.Length - 1;

            while (max >= min)
            {
                int mid = min + (max - min) / 2;
                if (arr[mid] < target)
                {
                    min = mid + 1;
                }
                else
                {
                    max = mid - 1;
                }
            }
            //target以上となる最初のインデックスを出力
            return min;
        }
        private static int UpperBound(long[] arr, long target)
        {
            var min = 0;
            var max = arr.Length - 1;

            while (max >= min)
            {
                var mid = (min + max) / 2;
                if (arr[mid] <= target)
                {
                    min = mid + 1;
                }
                else
                {
                    max = mid - 1;
                }
            }
            //target以上となる最初のインデックスを出力
            return min;
        }


    //出力========================================
    Console.WriteLine("");


    var sb = new StringBuilder();
    for (int j = 0; j<n; j++)
    {
        sb.AppendLine(a[j].ToString());
    }
    var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
    Console.SetOut(sw);
    Console.WriteLine(sb.ToString());
    Console.Out.Flush();
*/
#endregion