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

struct node{
    int key;//値を格納する場所
    struct node *prev,*next;//１つ前の値と後ろの値のメモリ位置を格納する場所
};

struct node *nil;//番兵を定義（データは無いが連結リストの基準となるもの）
void init(){//番兵のノードを作成する
    nil = (struct node *)malloc(sizeof(struct node));//構造体のサイズに従ってメモリ容量を確保し、そのメモリの種類を指定する。
    nil -> next = nil;//それぞれのメモリにnilを格納する
    nil -> prev = nil;
}

void insert(int key){//値xが格納されたリストを連結リストの先頭に追加
    struct node *x=(struct node *)malloc(sizeof(struct node));//ポインタ型構造体変数xを持つ構造体のメモリ領域を新たに確保する
    x->key=key;//keyノードにkey（入力された値）を代入
    x->next=nil->next;//リストの先頭に追加するために番兵のnextにある値をxのnextに格納する。
    nil->next->prev=x;//元々番兵のnextに指定されていた構造体のprevにxのアドレスを格納したいので番兵から辿って格納する
    x->prev=nil;//xをリストの先頭に追加する時、番兵の次に位置することになるためxのprevには番兵を入れる
    nil->next=x;//番兵のnextは使用したので最後にxのアドレスに書き換える
    return;
}

void deleteFirst(){//リストの先頭の構造体を削除
    struct node *target=nil->next;//番兵の次の構造体を削除するので、target変数を定義して番兵の次の構造体を設定する。
    nil->next=target->next;//削除する構造体のnextに入っているアドレスを番兵のnextに格納する
    target->next->prev=nil;//削除する構造体のprevに番兵のアドレスを格納する
    free(target);//構造体を削除する
    return;
}

void deleteLast(){//リストの末尾にある構造体を削除
    struct node *target=nil->prev;//番兵のprev（リストの一番最後にある構造体）をtargetにする
    nil->prev=target->prev;//削除する構造体のprevに入っているアドレスを番兵のprevに格納し、１つ前の構造体と番兵をつなげる
    target->prev->next=nil;//削除する構造体の１つ前の構造体に番兵のアドレスを格納する
    free(target);//削除
    return;
}

void delete(int key){//値xを探索しそれを格納している構造体を削除する、削除するのは最初に見つけたもののみ
    struct node *searcher=nil->next;//searcherというポインタ型構造体変数を定義し、番兵の次の構造体から探索を始める。
    while(searcher!=nil &&searcher->key!=key){//searcherが番兵に戻ってくる、もしくは目的のノードを見つけるまで繰り返す。
        searcher=searcher->next;//次の構造体に行く
    }
    if(searcher==nil){//番兵に辿り着いた場合、一周しているので値が見つからなかったと判断し何もせずに終了する。
        return;
    }
    //値を見つけループから抜けた後の削除処理、今いるアドレスの前後の構造体同士をつなげる
    searcher->prev->next=searcher->next;//searcherの前の構造体のnextをsearcherの次の構造体のprevに設定する
    searcher->next->prev=searcher->prev;//searcherの次の構造体のprevをsearcherの前の構造体のnextに設定する
    free(searcher);//searcherにある構造体のメモリを削除する。
    return;
}

int main(void){
    int com_num;//何回コマンドを入力するのかを設定する変数
    int delete_co = 0;//削除回数
    init();//番兵
    scanf("%d",&com_num);
    if(com_num > 2000000){exit(0);}
    for(int i=0;i<com_num;i++){//設定した回数分ループ
        char com[20];//コマンドの文字を格納する配列
        int num;//操作を行う数値
        scanf("%s",com);//コマンドのみで判定できるものから判定する
        if(strcmp(com,"deleteFirst")==0){
            deleteFirst();
        }else if(strcmp(com,"deleteLast")==0){
            deleteLast();
        }else{
            scanf("%d",&num);//数値をコマンドに従って操作する
            if(strcmp(com,"insert")==0){
                insert(num);
            }else if(strcmp(com,"delete")==0){
                delete(num);
                delete_co = delete_co + 1;
            }
        }
        if(delete_co > 20){exit(0);}
    }
    struct node *output=nil->next;//番兵の次、データがある最初の構造体を指定
    while(1){//構造体のkyeノードに格納されている数値を出力していく
        printf("%d",output->key );
        if(output->next!=nil){
            output=output->next;
            printf(" ");//空白
        }else{
            break;
        }
        
    }
    printf("\n");//改行
    return 0;
}
