using namespace std;


template<typename T>

class My_Simple_Node {

T node_Value;

My_Simple_Node<T>* nextNode;

My_Simple_Node<T>* prevNode;

public:

My_Simple_Node(T _node_value) : node_Value(_node_value), nextNode(0), prevNode(0) {}

template<typename T> friend class My_Simple_iterator;

template<typename T> friend class My_Simple_stack;

};



template<typename T>

class My_Simple_iterator {

private:

My_Simple_Node<T>* current;

public:

My_Simple_iterator(My_Simple_Node<T>* argument) : current(argument){}


T& operator*() { return current->node_Value; }

bool operator==(const My_Simple_iterator<T>& argument) { return current == argument.current; }

bool operator!=(const My_Simple_iterator<T>& argument) { return current != argument.current; }


My_Simple_iterator<T>& operator++(int)  {//후위++

My_Simple_iterator<T>* return_Value = this;

current = current->nextNode;

return *return_Value;

}


My_Simple_iterator<T>& operator--(int) {//후위 --

My_Simple_iterator<T>* return_Value = this;

current = current->prevNode;

return *return_Value;

}


My_Simple_iterator<T>& operator++() {//전위++

current = current->nextNode;

return *this;

}


My_Simple_iterator<T>& operator--() {//후위--

current = current->prevNode;

return *this;

}


My_Simple_iterator<T>& operator-(int _minuse) {//후위--

while (_minuse--)

this--;

return *this;

}


My_Simple_iterator<T>& operator+(int _plus) {//후위--

while (_plus--)

this++;

return *this;

}


};


template<typename T>

class My_Simple_stack {

private:

class Node;

typedef T* reference_type;

typedef T value_type;

typedef My_Simple_Node<T>* reference_node_type;

typedef My_Simple_Node<T> node_type;


size_t sz;

reference_node_type head;

reference_node_type tail;

public:


typedef My_Simple_iterator<T> iterator;


explicit My_Simple_stack() : sz(0), head(NULL),tail(NULL) {}


explicit My_Simple_stack(My_Simple_stack<value_type>& argument) {

for (My_Simple_stack<value_type>::My_Simple_iterator it = argument.begin();

it != argument.end(); it++)

this->push_back(*it);

}


value_type front() {

return head->node_Value;

}


value_type top() {

return tail->node_Value;

}


value_type pop_front() {

value_type return_Value = head->node_Value;

if (head->nextNode != NULL) {

head = head->nextNode;

delete head->prevNode;

head->prevNode = NULL;

}

else {

delete head;

head = tail = NULL;

}

sz--;

return return_Value;

}


value_type pop_back() {

value_type return_Value = tail->node_Value;

if (tail->prevNode != NULL) {

tail = tail->prevNode;

delete tail->nextNode;

tail->nextNode = NULL;

}else{

delete tail;

head = tail = NULL;

}

sz--;

return return_Value;

}


iterator begin() {

return iterator(head);

}


iterator end() {

return iterator(0);

}


void push_back(value_type& v) {

reference_node_type insert_node = new My_Simple_Node<T>(v);

if (sz == 0) { head = tail = insert_node; }

else if (sz == 1) {

head->nextNode = insert_node;

insert_node->prevNode = head;

tail = insert_node;

}else{

tail->nextNode = insert_node;

insert_node->prevNode = tail;

tail = insert_node;

}

sz++;

}


void push_front(value_type& v) {

reference_node_type insert_node = new My_Simple_Node<T>(v);

if (sz == 0) { head = tail = insert_node; }

else if (sz == 1) {

tail->prevNode = insert_node;

insert_node->nextNode = tail;

head = insert_node;

}

else {

head->prevNode = insert_node;

insert_node->nextNode = head;

head = insert_node;

}

sz++;

}


void clear() {

while (head->nextNode) {

reference_node_type del_obj = head;

head = head->nextNode;

delete del_obj;

}

delete head;

head = tail = NULL;

sz = 0;

}


size_t size() { return sz; }

};


insert하고 erase는 구현을 못했당