Problem:
Doubly Linked List

Your task is to implement a double linked list.

Write a program which performs the following operations:

insert x: insert an element with key x into the front of the list.

delete x: delete the first element which has the key of x from the list. If there is not such element, you need not do anything.

deleteFirst: delete the first element from the list.

deleteLast: delete the last element from the list.

Input

The input is given in the following format:

n

command1

command2

...

commandn

In the first line, the number of operations n is given. In the following n lines, the above mentioned operations are given in the following format:

insert x

delete x

deleteFirst

deleteLast

Output

Print all the element (key) in the list after the given operations. Two consequtive keys should be separated by a single space.

Constraints

The number of operations ≤ 2,000,000

The number of delete operations ≤ 20

0 ≤ value of a key ≤ 109

The number of elements in the list does not exceed 106

For a delete, deleteFirst or deleteLast operation, there is at least one element in the list.

Sample Input 1

7
insert 5
insert 2
insert 3
insert 1
delete 3
insert 6
delete 5

Sample Output 1

6 1 2

Sample Input 2

9
insert 5
insert 2
insert 3
insert 1
delete 3
insert 6
delete 5
deleteFirst
deleteLast

Sample Output 2

1

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 双方向連結リスト構造体
struct list {
    int key;
    struct list *prev;
    struct list *next;
};

struct list *first;
struct list *last;

void init(void)
{
    first = NULL;
    last = NULL;
}

// 連結リストの先頭からキー値を出力する
void disp(void)
{
    struct list *p = first;
    
    if ( p == NULL ) {
        return;
    }

    while ( 1 ) {
        printf("%d", p->key);
        if ( p == last ) {
            printf("\n");
        } else {
            printf(" ");
        }
        if ( p->next == NULL ) {
            break;
        }
        p = p->next;
    }
}

// 連結リストの先頭にキー x を持つ要素を継ぎ足す。
void insert(int x)
{
    struct list *li;

    li = (struct list*)malloc(sizeof(struct list));
    li->key = x;
    li->prev = NULL;
    li->next = NULL;

    //リスト空？
    if ( first == NULL ) {
        first = li;
        last = li;
    } else {
        first->prev = li;
        li->next = first;
        first = li;
    }
}

// リストの先頭の要素を削除する。
void deleteFirst(void)
{
    struct list *p;
    
    if ( first == last ) {
        free(first);
        init();
    } else {
        p = first->next;
        p->prev = NULL;
        free(first);
        first = p;
    }
}

// リストの末尾の要素を削除する。
void deleteLast(void)
{
    struct list *p;
    
    if ( first == last ) {
        free(last);
        init();
    } else {
        p = last->prev;
        p->next = NULL;
        free(last);
        last = p;
    }
}


// キー x を持つ最初の要素を連結リストから削除する。
// そのような要素が存在しない場合は何もしない。
void delete(int x)
{
    struct list *p;
    struct list *p1;
    struct list *p2;
    
    p = first;
    
    while( 1 ) {
        if ( p->key == x ) {
            // リストの位置ごとの処理
            if ( p == first ) {
                deleteFirst();
            } else if ( p == last ) {
                deleteLast();
            } else {
                // ポインタの繋ぎかえ
                p1 = p->prev;
                p1->next = p->next;
                p2 = p->next;
                p2->prev = p1;
                free(p);
            }
            break;
        }
        if ( p->next == NULL ) {
            break;
        }
        p = p->next;
    }
}


int main(void)
{
    int n;
    char line[256];
    char *tp;

    scanf("%d\n", &n);

    init();

    for ( int i = 0; i < n; i++ ) {
        memset(line ,'\0', sizeof(line));
        fgets(line, sizeof(line), stdin);
        tp = strtok(line, " \n");
        if ( strcmp(tp, "insert") == 0 ) {
            tp = strtok(NULL, "\n");
            insert(atoi(tp));
        } else if ( strcmp(tp, "deleteFirst") == 0 ) {
            deleteFirst();
        } else if ( strcmp(tp, "deleteLast") == 0 ) {
            deleteLast();
        } else {
            tp = strtok(NULL, "\n");
            delete(atoi(tp));
        }
    }

    disp();

    return 0;
}