use std::collections::VecDeque;
use std::env;
use std::fmt::Debug;
use std::io;
use std::io::prelude::*;
//use std::time::{Duration, Instant};

//===================================================
// MACROs need to be defined above the use place ... ?
macro_rules! dprintln {
    ($($x:expr),*) => {{
        if $crate::is_debug_mode() {
            let f = || {println!( $($x),*)};
            f()
        }
    }}
}

/// Backward For-Loop Helper
///  from -> to (exclude `to`)
///
/// # Examples
/// see tests::macro_backward()
///
#[macro_export]
macro_rules! backward_ho {
    ($from:expr, $to:expr) => {{
        (($to + 1)..($from + 1)).rev()
    }};
}
//===================================================

fn main() {
    // Initialize
    set_debug_mode(false);
    for arg in env::args() {
        if arg == "--debug" {
            set_debug_mode(true);
        }
    }
    dprintln!("[DebugMode] {}", "On");

    // Execute
    dprintln!("=================");
    dprintln!("= READ INPUT     ");
    let stdin = io::stdin();
    let input = Input::new(stdin.lock());
    dprintln!("[Input] \n{:?}", input);
    dprintln!("=================");
    dprintln!("= INTERPRET INPUT");
    let q = input.into_quiz();
    dprintln!("[Quiz] \n{:?}", q);
    dprintln!("=================");
    dprintln!("= SOLVE QUIZE    ");
    let a = q.solve();
    dprintln!("[Answer] \n{:?}", a);
    dprintln!("=================");
    dprintln!("= PRINT ANSWER   ");
    a.print();
    dprintln!("=================");
}

#[derive(Debug)]
pub struct ArrayDLinkedList<T>
where
    T: PartialEq + Debug,
{
    array: Vec<ListNode<T>>,
    size: usize,

    vacant_start: Option<usize>,
    vacant_size: usize,

    used_head: Option<usize>,
    used_last: Option<usize>,
    used_len: usize,
}

#[derive(Debug)]
struct ListNode<T>
where
    T: PartialEq + Debug,
{
    element: Option<T>,
    next: Option<usize>,
    prev: Option<usize>,
}

impl<T> ArrayDLinkedList<T>
where
    T: PartialEq + Debug,
{
    pub fn new(size: usize) -> Self {
        let mut array = Vec::with_capacity(size);

        for i in 0..size {
            let n = ListNode {
                element: None,
                next: Some(i + 1),
                prev: None,
            };
            array.push(n);
        }
        array[size - 1].next = None;
        let vacant_start = Some(0);
        let vacant_size = size;

        let used_head = None;
        let used_last = None;
        let used_len = 0;

        ArrayDLinkedList {
            array,
            size,
            vacant_start,
            vacant_size,
            used_head,
            used_last,
            used_len,
        }
    }

    pub fn len(&self) -> usize {
        self.used_len
    }

    pub fn vacant_space(&self) -> usize {
        self.vacant_size
    }

    fn pop_vacant(&mut self) -> Option<usize> {
        match self.vacant_start {
            Some(idx) => {
                let n = &mut self.array[idx];

                self.vacant_start = n.next;
                self.vacant_size -= 1;

                n.next = None;
                n.prev = None;
                n.element = None;

                Some(idx)
            }
            None => None,
        }
    }

    fn push_vacant(&mut self, idx: usize) {
        let n = &mut self.array[idx];

        n.element = None;
        n.next = self.vacant_start;
        n.prev = None;

        self.vacant_start = Some(idx);
        self.vacant_size += 1;
    }

    pub fn push_front(&mut self, e: T) {
        let idx = self.pop_vacant().expect("Vacant array is empty.");

        let n_next = {
            let n = &mut self.array[idx];

            n.element = Some(e);
            n.next = self.used_head;
            n.prev = None;

            n.next
        };

        if let Some(next_idx) = n_next {
            let nn = &mut self.array[next_idx];
            nn.prev = Some(idx);
        }

        self.used_head = Some(idx);
        if self.used_last.is_none() {
            self.used_last = Some(idx);
        }

        self.used_len += 1;
    }

    pub fn pop_front(&mut self) -> Option<T> {
        if let Some(idx) = self.used_head {
            let element = self.array[idx].element.take();
            if let Some(next_idx) = self.array[idx].next {
                let nn = &mut self.array[next_idx];
                nn.prev = None;
            }

            self.used_head = self.array[idx].next;
            if self.used_head.is_none() {
                self.used_last = None;
            }
            self.used_len -= 1;

            self.push_vacant(idx);

            element
        } else {
            None
        }
    }

    pub fn push_back(&mut self, e: T) {
        let idx = self.pop_vacant().expect("Vacant array is empty.");

        let n_prev = {
            let n = &mut self.array[idx];

            n.element = Some(e);
            n.prev = self.used_last;
            n.next = None;

            n.prev
        };

        if let Some(prev_idx) = n_prev {
            let np = &mut self.array[prev_idx];
            np.next = Some(idx);
        }

        self.used_last = Some(idx);
        if self.used_head.is_none() {
            self.used_head = Some(idx);
        }

        self.used_len += 1;
    }

    pub fn pop_back(&mut self) -> Option<T> {
        if let Some(idx) = self.used_last {
            let element = self.array[idx].element.take();
            if let Some(prev_idx) = self.array[idx].prev {
                let np = &mut self.array[prev_idx];
                np.next = None;
            }

            self.used_last = self.array[idx].prev;
            if self.used_last.is_none() {
                self.used_head = None;
            }
            self.used_len -= 1;

            self.push_vacant(idx);

            element
        } else {
            None
        }
    }

    pub fn drop_first(&mut self, e: T) -> bool {
        let mut next_idx = self.used_head;
        let ee = Some(e);

        while let Some(idx) = next_idx {
            if self.array[idx].element == ee {
                if let Some(idx_prev) = self.array[idx].prev {
                    self.array[idx_prev].next = self.array[idx].next;
                } else {
                    self.used_head = self.array[idx].next;
                }
                if let Some(idx_next) = self.array[idx].next {
                    self.array[idx_next].prev = self.array[idx].prev;
                } else {
                    self.used_last = self.array[idx].prev;
                }

                self.used_len -= 1;

                self.push_vacant(idx);
                return true;
            }
            next_idx = self.array[idx].next;
        }

        false
    }

    pub fn into_vec(mut self) -> Vec<T> {
        let mut v = Vec::new();

        while let Some(e) = self.pop_front() {
            v.push(e);
        }

        v
    }
}

#[derive(Debug)]
enum Command {
    Insert(u32),
    Delete(u32),
    DeleteFirst,
    DeleteLast,
}

#[derive(Debug)]
struct Quiz {
    n: u32,          // 1 <= N <= 2,000,000
    v: Vec<Command>, // length=N
}

#[derive(Debug)]
struct Answer {
    v: Vec<u32>,
}

impl<R: BufRead> Input<R> {
    fn into_quiz(mut self) -> Quiz {
        let n: u32 = self.parse_next().unwrap();
        let mut v = Vec::new();
        for _i in 0..n {
            let input: String = self.parse_next().unwrap();
            let action: &str = &input;
            let command = match action {
                "insert" => {
                    let n: u32 = self.parse_next().unwrap();
                    Command::Insert(n)
                }
                "delete" => {
                    let n: u32 = self.parse_next().unwrap();
                    Command::Delete(n)
                }
                "deleteFirst" => Command::DeleteFirst,
                "deleteLast" => Command::DeleteLast,
                x => panic!("Invalid input found. `{}`", x),
            };

            v.push(command)
        }
        Quiz { n, v }
    }
}

impl Quiz {
    fn solve(self) -> Answer {
        let mut list = ArrayDLinkedList::new(1000000);

        for command in self.v {
            dprintln!("{:?}", command);
            match command {
                Command::Insert(n) => list.push_front(n),
                Command::Delete(n) => {
                    let _ = list.drop_first(n);
                }
                Command::DeleteFirst => {
                    let _ = list.pop_front();
                }
                Command::DeleteLast => {
                    let _ = list.pop_back();
                }
            }
            dprintln!(" len:{}", list.len())
        }

        Answer { v: list.into_vec() }
    }
}

impl Answer {
    fn print(self) {
        println!("{}", concat_vec_to_string(&self.v));
    }
}

// =====================================================
// =
// =====================================================

//==================================================
// Stdin Reader
#[derive(Debug)]
pub enum Token {
    Word(String),
    LineBreak,
}

impl Token {
    pub fn is_word(&self) -> bool {
        match *self {
            Token::Word(ref _x) => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub struct Input<R: BufRead> {
    input: R,
    tokens: VecDeque<Token>,
}

impl<R: BufRead> Input<R> {
    pub fn new(input: R) -> Self {
        let tokens = VecDeque::new();

        Input { input, tokens }
    }

    pub fn read_next_word(&mut self) -> Option<Token> {
        loop {
            match self.tokens.pop_front() {
                None => {
                    // Read Input
                    let mut line = String::new();
                    let n = self.input.read_line(&mut line).expect("Read Error.");
                    if n == 0 {
                        return None;
                    }
                    let mut line_tokens = tokenaize(line);
                    self.tokens.append(&mut line_tokens);
                }
                Some(Token::LineBreak) => (),
                x => return x,
            }
        }
    }

    pub fn parse_next<T>(&mut self) -> Option<T>
    where
        T: std::str::FromStr,
    {
        if let Some(Token::Word(str)) = self.read_next_word() {
            match str.parse() {
                Ok(x) => Some(x),
                _ => None,
            }
        } else {
            None
        }
    }

    pub fn parse_next_vec<T>(&mut self, size: usize) -> Option<Vec<T>>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::new();

        for _i in 0..size {
            if let Some(t) = self.parse_next() {
                v.push(t);
            } else {
                return None;
            }
        }

        Some(v)
    }

    pub fn parse_next_vec2<T>(&mut self, size2: usize, size1: usize) -> Option<Vec<Vec<T>>>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::new();

        for _i in 0..size2 {
            if let Some(t) = self.parse_next_vec(size1) {
                v.push(t);
            } else {
                return None;
            }
        }

        Some(v)
    }

    pub fn parse_all_remaining_into_vec<T>(&mut self) -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::new();

        loop {
            match self.parse_next() {
                Some(x) => v.push(x),
                None => return v,
            }
        }
    }
}

fn tokenaize(str: String) -> VecDeque<Token> {
    let mut v = VecDeque::new();

    for w in str.split_whitespace() {
        v.push_back(Token::Word(w.to_string()));
    }
    v.push_back(Token::LineBreak);
    v
}

//==================================================
// Utility Functions
pub fn concat_vec_to_string<T>(v: &Vec<T>) -> String
where
    T: std::fmt::Display,
{
    let mut string = String::with_capacity(v.len() * 2);

    if let Some((h, t)) = v.split_first() {
        string = h.to_string();

        for obj in t {
            string.push(' ');
            string.push_str(&obj.to_string()); 
        }
    }

    return string;


//    let mut string = String::new();
//
//    if let Some((h, t)) = v.split_first() {
//        string = h.to_string();
//
//        for obj in t {
//            string = format!("{} {}", string, obj);
//        }
//    }
//
//    return string;
}

//==================================================
// Debug Switch
static mut S_DEBUG_MODE: bool = false;
fn is_debug_mode() -> bool {
    unsafe { S_DEBUG_MODE }
}

fn set_debug_mode(mode: bool) {
    unsafe {
        S_DEBUG_MODE = mode;
    }
}

//==================================================
// Usage
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn macro_backward() {
        let mut v = Vec::new();
        for i in backward_ho!(5, 1) {
            v.push(i);
        }
        assert_eq!(vec![5, 4, 3, 2], v);
    }

    #[test]
    fn linked_list_front() {
        let mut list = ArrayDLinkedList::new(100);
        list.push_front("aaa".to_string());
        list.push_front("bbb".to_string());
        assert_eq!(list.len(), 2);
        assert_eq!(list.vacant_space(), 100 - 2);
        assert_eq!(list.pop_front(), Some("bbb".to_string()));
        assert_eq!(list.pop_front(), Some("aaa".to_string()));
        assert_eq!(list.pop_front(), None);
        assert_eq!(list.len(), 0);
        assert_eq!(list.vacant_space(), 100);
    }
    #[test]
    fn linked_list_back() {
        let mut list = ArrayDLinkedList::new(100);
        list.push_back("aaa".to_string());
        list.push_back("bbb".to_string());
        assert_eq!(list.len(), 2);
        assert_eq!(list.vacant_space(), 100 - 2);
        assert_eq!(list.pop_back(), Some("bbb".to_string()));
        assert_eq!(list.pop_back(), Some("aaa".to_string()));
        assert_eq!(list.pop_back(), None);
        assert_eq!(list.len(), 0);
        assert_eq!(list.vacant_space(), 100);
    }
    #[test]
    fn linked_list_writefront_readback() {
        let mut list = ArrayDLinkedList::new(100);
        list.push_front("aaa".to_string());
        list.push_front("bbb".to_string());
        assert_eq!(list.len(), 2);
        assert_eq!(list.vacant_space(), 100 - 2);
        assert_eq!(list.pop_back(), Some("aaa".to_string()));
        assert_eq!(list.pop_back(), Some("bbb".to_string()));
        assert_eq!(list.pop_back(), None);
        assert_eq!(list.len(), 0);
        assert_eq!(list.vacant_space(), 100);
    }
    #[test]
    fn linked_list_writeback_readfront() {
        let mut list = ArrayDLinkedList::new(100);
        list.push_back("aaa".to_string());
        list.push_back("bbb".to_string());
        assert_eq!(list.len(), 2);
        assert_eq!(list.vacant_space(), 100 - 2);
        assert_eq!(list.pop_front(), Some("aaa".to_string()));
        assert_eq!(list.pop_front(), Some("bbb".to_string()));
        assert_eq!(list.pop_front(), None);
        assert_eq!(list.len(), 0);
        assert_eq!(list.vacant_space(), 100);
    }
    #[test]
    fn linked_list_mix() {
        let size = 5usize;
        let mut list = ArrayDLinkedList::new(size);
        list.push_back("aaa".to_string());
        list.push_front("xxx".to_string());
        list.push_back("bbb".to_string());
        list.push_front("yyy".to_string());
        assert_eq!(list.len(), 4);
        assert_eq!(list.vacant_space(), size - 4);
        assert_eq!(list.pop_back(), Some("bbb".to_string()));
        assert_eq!(list.pop_front(), Some("yyy".to_string()));
        assert_eq!(list.pop_back(), Some("aaa".to_string()));
        assert_eq!(list.pop_front(), Some("xxx".to_string()));
        assert_eq!(list.pop_back(), None);
        assert_eq!(list.pop_front(), None);
        assert_eq!(list.len(), 0);
        assert_eq!(list.vacant_space(), size);
    }
    #[test]
    fn linked_list_drop_first() {
        let size = 5usize;
        let mut list = ArrayDLinkedList::new(size);
        list.push_back("aaa".to_string());
        list.push_back("bbb".to_string());
        list.push_back("aaa".to_string());
        list.push_back("bbb".to_string());
        list.push_back("aaa".to_string());
        assert_eq!(list.len(), 5);
        assert_eq!(list.vacant_space(), size - 5);
        println!("{:?}", list);
        list.drop_first("aaa".to_string());
        println!("{:?}", list);
        assert_eq!(list.len(), 4);
        list.drop_first("aaa".to_string());
        assert_eq!(list.len(), 3);
        assert_eq!(list.vacant_space(), size - 3);
        assert_eq!(list.pop_back(), Some("aaa".to_string()));
        assert_eq!(list.pop_back(), Some("bbb".to_string()));
        assert_eq!(list.pop_back(), Some("bbb".to_string()));
        assert_eq!(list.pop_back(), None);
        assert_eq!(list.len(), 0);
        assert_eq!(list.vacant_space(), size);
    }
}



Measured memory_bytes: 61180