#include<bits/stdc++.h>
using namespace std;

class FrontMiddleBackQueue {
public:
    struct node{
        node* pre;
        node* nxt;
        int val;
    };

    class li{
        public:
        node * header;
        node * tail;
        int sum;
        li(){
            header = new node();
            tail = new node();
            header -> nxt = tail;
            tail->pre = header;
            header -> val = -1;
            tail -> val = -1;
            sum = 0;
        }
        void add_node(node * previous, node * nxt, node * wait_insert){
            wait_insert -> pre = previous;
            wait_insert -> nxt = nxt;
            previous->nxt = wait_insert;
            nxt->pre = wait_insert;
            sum++;
        }
        void add_front(node * x){
            // x -> pre = header;
            // x -> nxt = header->nxt;
            // header->nxt->pre = x;
            // header->nxt = x;
            add_node(header,header->nxt,x);
        }

        void add_back(node * x){
            // x -> nxt = tail;
            // x -> pre = tail -> pre;
            // tail -> pre -> nxt = x;
            // tail -> pre = x;
            add_node(tail->pre,tail,x);
        }

        void add_middle(node *x){
            int cnt = sum / 2;
            node * cur = header;
            while(cnt){
                cur = cur->nxt;
                cnt--;
            }
            add_node(cur,cur->nxt,x);
        }
        void traverse(){
            node * cur = header;
            while(cur != tail){
                cur = cur->nxt;
                cout<<cur->val<<endl;
            }
        }
        void retranverse(){
            node *cur = tail;
            while(cur!=header){
                cur = cur->pre;
                cout<<cur->val<<endl;
            }
        }
        int del_node(int idx){
            if(idx > sum || idx == 0) return -1;
            int cnt = idx;
            node * cur = header;
            // cout<<cnt<<endl;
            while(cnt){
                cur = cur->nxt;
                cnt--;
            }
            cur -> pre -> nxt = cur -> nxt;
            cur -> nxt -> pre = cur -> pre;
            int val = cur->val;
            delete(cur);
            sum--;
            return val;
        }
    };
    li *que;
    FrontMiddleBackQueue() {
        que = new li();
    }
    
    void pushFront(int val) {
        node *tmp = new node();
        tmp->val = val;
        que->add_front(tmp);
    }
    
    void pushMiddle(int val) {
        node * tmp = new node();
        tmp -> val = val;
        que->add_middle(tmp);
    }
    
    void pushBack(int val) {
       node *tmp = new node();
       tmp -> val = val; 
       que -> add_back(tmp);
    }
    
    int popFront() {
        return que->del_node(1);
    }
    
    int popMiddle() {
        if(que->sum % 2 == 1)
            return que->del_node((que->sum) / 2 + 1);
        else
            return que->del_node((que->sum) / 2);
    }
    
    int popBack() {
        return que->del_node(que->sum);
    }
};

int main(){
    FrontMiddleBackQueue * q = new FrontMiddleBackQueue();
    q->pushFront(1);
    q->pushBack(2);
    q->pushMiddle(3);
    q->pushMiddle(4);
    // q->que->traverse();
    // q->que->retranverse();
    cout<<q->popFront()<<endl;
    cout<<q->popMiddle()<<endl;
    cout<<q->popMiddle()<<endl;
    cout<<q->popBack()<<endl;
    cout<<q->popFront()<<endl;

    return 0;
}