/*
双方向リスト
*/
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

// Node ノード
type Node struct {
	next, prev *Node
	val        int
}

func (n *Node) String() string {
	// newNodeを使って生成するのでどの値もnilにはならない.
	return fmt.Sprintf("prev[%d],val[%d],next[%d]", n.prev.val, n.val, n.next.val)
}

func newNode(val int) *Node {
	var n Node
	n.val = val
	n.prev = &n
	n.next = &n
	return &n
}

// 前に挿入
func (n *Node) insertPrev(p *Node) {
	n.prev.next = p
	p.next = n
	p.prev = n.prev
	n.prev = p
}

// 後ろに挿入
func (n *Node) insertNext(p *Node) {
	p.next = n.next
	n.next.prev = p
	n.next = p
	p.prev = n
}

// 削除
func (n *Node) deleteMe() {
	tmp := n.next
	n.prev.next = tmp
	n.next.prev = n.prev
}

// List リスト
type List struct {
	head *Node
}

func (l *List) String() string {

	var buf bytes.Buffer
	sep := ""
	n := l.head.next
	for n != l.head {
		buf.WriteString(fmt.Sprintf("%s%d", sep, n.val))
		n = n.next
		sep = " "
	}
	return buf.String()
}

func newList() *List {
	var l List
	head := newNode(0)
	l.head = head
	return &l
}

// リストの先頭に継ぎ足す
func (l *List) insert(val int) {
	// headの直後に足す
	n := newNode(val)
	l.head.insertNext(n)
}

func (l *List) deleteFirst() {

	n := l.head.next
	if n == l.head {
		// 空リスト
		return
	}
	l.head.next.deleteMe()
}
func (l *List) deleteLast() {

	n := l.head.prev
	if n == l.head {
		// 空リスト
		return
	}
	l.head.prev.deleteMe()
}
func (l *List) delete(val int) {

	n := l.head.next
	if n == l.head {
		// 空リスト
		return
	}
	for n != l.head {
		if n.val == val {
			n.deleteMe()
			break
		}
		n = n.next
	}
}

// 1)実行時にプロファイルファイルを出力
// $ <progname> -cpuprofile="test.prof" < ../in.txt

// 2)プロファイルを見る
// go tool pprof <progname> test.prof

// 3)ツール内でコマンド
// (pprof) top10

// https://blog.golang.org/profiling-go-programs

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {

	// flag.Parse()
	// if *cpuprofile != "" {
	// 	f, err := os.Create(*cpuprofile)
	// 	if err != nil {
	// 		log.Fatal(err)
	// 	}
	// 	pprof.StartCPUProfile(f)
	// 	defer pprof.StopCPUProfile()
	// }

	scanner := bufio.NewScanner(os.Stdin)
	n := eGetInt(scanner)
	l := newList()
	for i := 0; i < n; i++ {
		commands := eGetFields(scanner)
		command := commands[0]
		var val int
		switch command {
		case "insert":
			val = eAtoi(commands[1])
			l.insert(val)
		case "delete":
			val = eAtoi(commands[1])
			l.delete(val)
		case "deleteFirst":
			l.deleteFirst()
		case "deleteLast":
			l.deleteLast()
		default:
			panic("")
		}
	}
	fmt.Println(l)
}
func eGetLine(r *bufio.Scanner) string {
	if r.Scan() {
		return r.Text()
	}
	err := r.Err()
	if err != nil {
		log.Fatal(err)
	}
	// EOF
	return ""
}
func eGetInt(r *bufio.Scanner) int {
	line := eGetLine(r)
	return eAtoi(line)
}
func eGetFields(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Fields(line)
}
func eGetInts(r *bufio.Scanner) []int {
	fields := eGetFields(r)
	var ints []int
	for _, f := range fields {
		ints = append(ints, eAtoi(f))
	}
	return ints
}
func eAtoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		log.Fatal(err)
	}
	return n
}

type ints []int

func (s ints) String() string {
	var buf bytes.Buffer
	sep := ""
	for _, v := range s {
		buf.WriteString(fmt.Sprintf("%s%d", sep, v))
		sep = " "
	}
	return buf.String()
}

func reverse(a ints) ints {
	r := make(ints, len(a))
	for i := 0; i < len(a); i++ {
		r[i] = a[len(a)-1-i]
	}
	return r
}



Measured memory_bytes: 72992