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

/*
insert x: 連結リストの先頭にキー x を持つ要素を継ぎ足す
delete x: キー x を持つ最初の要素を連結リストから削除する
deleteFirst: リストの先頭の要素を削除する
deleteLast: リストの末尾の要素を削除する
*/

struct doubleList{
	
	struct doubleList *prev;
	int value;
	struct doubleList *next;
	
};
typedef struct doubleList DL;




void insert(int key);	//連結リストの先頭にキー x を持つ要素を継ぎ足す
void delete(int key);	//キー x を持つ最初の要素を連結リストから削除する
void deleteFirst(void);	//リストの先頭の要素を削除する
void deleteLast(void);	//リストの末尾の要素を削除する


void initialize(DL *p);
void displayAll(DL *p);

DL *listHead;

int main(void)
{
	
	int n;
	int i;
	int key;
	
	char order[100];
	char str[100];
	
	//まずリストヘッドの領域を取る。
	listHead = (DL*)malloc(sizeof(DL));
	
	//リストヘッドの初期化
	initialize(listHead);
	
	
	//命令数nの入力
	fgets(order, sizeof(order), stdin);
	sscanf(order, "%d", &n);
	
	for(i=0; i<n; i++){
		
		
		//命令の入力
		fgets(order, sizeof(order), stdin);
		
		//deleteFirstの場合：
		if(strcmp(order, "deleteFirst\n") == 0){
			
			deleteFirst();
			
		}
		
		//deleteLastの場合：
		else if(strcmp(order, "deleteLast\n") == 0){
			
			deleteLast();
			
		}
		
		//それ以外の場合：
		else{
			
			sscanf(order, "%s %d\n", str, &key);
			
			if(strcmp(str, "insert") == 0){
				
				insert(key);
				
			}
			
			else if(strcmp(str, "delete") == 0){
				
				delete(key);
				
			}
			
			else{
				
				//printf("無効な入力です。\n");
				
			}
			
		}
		
	}
	
	displayAll(listHead);
	
	return 0;
	
}



void initialize(DL *p){
	
	p->prev = NULL;
	p->value = 0;
	p->next = NULL;
	
}



void displayAll(DL *p){
	
	while(1){
		
		if(p->next == NULL){
			
			break;
			
		}
		
		printf("%d ", p->value);
		
		p = p->next;
		
	}
	
	printf("\n");
	
}



void insert(int key){
	
	DL *p = (DL*)malloc(sizeof(DL));
	p->prev = NULL;
	p->value = key;
	p->next = listHead;
	
	//リストヘッド（元）のprevに、今作ったポインタを繋げる
	listHead->prev = p;
	
	//リストヘッドを更新する。
	listHead = p;
	
	
}


void delete(int key){
	
	//リストヘッドからチェック開始
	DL *p = listHead;
	
	
	//最終的に削除できたかを管理
	int isDeleted = 0;
	
	while(1){
		
		
		//pの値がkeyと一致した場合：
		if(p->value == key){
			
			//1つ前の要素があるなら（＝最初の要素でなければ）、「1つ前の要素の、次の要素（＝今現在は自分が入っている）へのリンク」に、自分の次の要素を入れる（＝自分をスキップする形にする）
			if(p->prev != NULL){
				
				p->prev->next = p->next;
				
			}
			
			//次の要素があるなら（＝最後の要素でなければ）、「1つ次の要素の、前の要素（＝今現在は自分が入っている）へのリンク」に、自分の前の要素を入れる（＝自分をスキップする形にする）」
			if(p->next != NULL){
				
				p->next->prev = p->prev;
				
			}
			
			//********************************************この時点で、1つ前からも1つ先からも、両方ともから自分はアクセスされない。	→	削除完了。******************************************
			
			
			//削除に成功した、という印。
			isDeleted = 1;
			
			//削除したらループを抜ける。s
			break;
			
		}
		
		
		//次の要素がもうない（＝最後の要素）の場合、ループを抜ける。
		if(p->next == NULL){
			
			break;
			
		}
		
		
		//現在地を1つ進める。
		p = p->next;
		
	}
	
	
	//削除した場合とできなかった場合のメッセージ
	if(isDeleted){
		
		//printf("%d を削除しました\n\n", key);
		
	}
	else{
		
		//printf("%d は見つかりませんでした\n\n", key);
		
	}
	
}


//リストの先頭の要素を削除する
void deleteFirst(void){
	
	if(listHead->next != NULL){
		
		listHead->next->prev = NULL;
		listHead = listHead->next;
		
	}
	else{
		
		listHead = NULL;
		
	}
	
}



//リストの末尾の要素を削除する
void deleteLast(void){
	
	DL *p = listHead;
	
	while(p->next != NULL){
		
		p = p->next;
		
	}
	
	if(p->prev != NULL){
		
		p->prev->next = NULL;
		p = NULL;
		
	}
	else{
		
		p = NULL;
		
	}
	
}