// Original C++ solution (slower):
#include <cassert>

#include <stdio.h>

#include <string>

#include <algorithm>



class user_input{

private:

    static constexpr unsigned int sizeOfAscii = 128;

    bool isBlankChar[sizeOfAscii];

    // 符号なし整数を getchar で読み込んで構成する (もし, 符号付きだとバグる)

    template <typename Tp>

    inline void charToUnsignedInteger(Tp& val) const {

        val = 0; int c; while(true){

            c = getchar_unlocked();

            if(c == EOF) return;

            if(not isBlankChar[c]) break;

        }

        if(c < '0' or c > '9') return;

        do{

            val = 10 * val + c - '0';

            c = getchar_unlocked();

        } while(not (c == EOF or isBlankChar[c]));

    }

public:

    constexpr user_input(void) : isBlankChar(){

        for(unsigned int i = 0; i < sizeOfAscii; ++i) isBlankChar[i] = false;

        isBlankChar[int('\n')] = true; isBlankChar[int('\t')] = true; 

        isBlankChar[int(' ')]  = true; isBlankChar[int('\v')] = true;

    }

    inline const user_input& operator >> (unsigned int& uint_arg) const {

        charToUnsignedInteger<unsigned int>(uint_arg); return *this;

    }

    inline const user_input& operator >> (char& char_arg) const {

        do{

            if((char_arg = getchar_unlocked()) == EOF) return *this;

        } while(isBlankChar[int(char_arg)]);

        return *this;

    }

    inline const user_input& operator >> (std::string& str_arg) const {

        str_arg.erase();

        int c; while(true){ 

            c = getchar_unlocked();

            if(c == EOF) return *this;

            if(not isBlankChar[c]) break;

        }

        constexpr unsigned int buffer_size = 128; 

        char buffer_input[buffer_size]; unsigned int buffer_length = 0;

        do{

            buffer_input[buffer_length++] = c;

            if(buffer_length == buffer_size){

                buffer_length = 0; str_arg.append(buffer_input, buffer_size);

            }

            c = getchar_unlocked();

        } while(c != EOF and (not isBlankChar[c]) );

        str_arg.append(buffer_input, buffer_length);

        return *this;

    }

}; constexpr user_input cin;



template <typename element_t, const unsigned int N>

class dequeic{

    static_assert(N, "Max Size must be greater than zero");

    

    element_t data[2 * N];

    const element_t* left_end = data;

    const element_t* right_end = data + 2 * N;

    element_t *begin_ptr = data + N;

    element_t *end_ptr   = data + N;

public:

    dequeic(void){}

    inline void push_front_with_check(const element_t& val){

        assert(left_end != begin_ptr); *(--begin_ptr) = val;

    }

    inline void push_front(const element_t& val){ *(--begin_ptr) = val; }

    inline void push_back_with_check(const element_t& val){ 

        assert(right_end != end_ptr); *(end_ptr++) = val; 

    }

    inline void push_back(const element_t& val){ *(end_ptr++) = val; }

    inline void pop_front_with_check(void){ assert(begin_ptr != end_ptr); begin_ptr++; }

    inline void pop_front(void){ begin_ptr++; }

    inline void pop_back_with_check(void){ assert(begin_ptr != end_ptr); --end_ptr; }

    inline void pop_back(void){ --end_ptr; }

    

    inline element_t& operator [](int index){

        return *(begin_ptr + index);

    }

    inline element_t& at(int index){

        assert(0 <= index and index < size());

        return *(begin_ptr + index);

    }

    

    inline bool empty(void){ return begin_ptr == end_ptr; }

    unsigned int size(void) const{

        return end_ptr - begin_ptr;

    }

    element_t* const begin(void) const {return begin_ptr;}

    element_t* const end(void) const {return end_ptr;}

};



const unsigned int N = 3e5 + 1;



int main(void){

    std::string s; cin >> s;

    const unsigned int n = s.size();

    dequeic<char, N> dq; for(int i = 0; i < n; ++i) dq.push_back(s[i]);

    bool flag = true;

    unsigned int q; cin >> q;

    while(q--){

        char c; cin >> c;

        if(c == '1') flag = not flag;

        else{

            char k, t; cin >> k >> t;

            if(flag){

                if(k == '1') dq.push_front(t);

                else dq.push_back(t);

            }

            else{

                if(k == '1') dq.push_back(t);

                else dq.push_front(t);

            }

        }

    }

    if(not flag) std::reverse(dq.begin(), dq.end());

    for(auto itr = dq.begin(); itr != dq.end(); ++itr) putchar_unlocked(*itr); putchar_unlocked('\n');

    return 0;

}

// Optimized solution to the same problem (faster):
#include <stdio.h>

#include <algorithm>



constexpr unsigned int N = 2e6;

char buffer[N];

char *ptr = buffer;

constexpr unsigned int S = 5e5;

char Out[2 * S];

char *left = Out + S, *right = Out + S;



int main(void){

    fread(buffer, sizeof(char), N, stdin);

    while('a' <= *ptr) *(right++) = *(ptr++);

    unsigned int q = 0;

    while(*(++ptr) >= '0') q = 10 * q + *ptr - '0';

    bool flag = false;

    while(q--){

        if(*(++ptr) == '1') flag = not flag;

        else{

            if((*(ptr += 2) == '1') ^ flag) *(--left) = *(ptr += 2);

            else *(right++) = *(ptr += 2); 

        }

        ptr++;

    }

    if(flag) std::reverse(left, right);

    fwrite(left, sizeof(char), right - left, stdout);

    return 0;

}

// Fastest known solution for this problem: