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 = BufReadInput::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,Copy,Clone,PartialEq,Eq)]
enum Acgt {
    A,
    C,
    G,
    T,
}

#[derive(Debug,Clone,PartialEq,Eq)]
struct AcgtStr(Vec<Acgt>);

#[derive(Debug)]
struct AcgtRep {
    hash_list: Vec<Option<Vec<AcgtStr>>>,
    bit: u32,
    len: usize,
    mask: usize,
}

#[derive(Debug,Clone)]
enum Command {
    Insert(AcgtStr),
    Find(AcgtStr),
}

impl AcgtStr {
    fn new(s: String) -> Self {
        let mut v = Vec::new();
        for c in s.chars() {
            let acgt = match c {
                'A' => Acgt::A,
                'C' => Acgt::C,
                'G' => Acgt::G,
                'T' => Acgt::T,
                _   => panic!("Parse error"),
            };
            v.push(acgt);
        }
        AcgtStr(v)
    }
    fn as_u32(&self) -> u32 {
        //  3          2          1          0
        // 10 9876543210 9876543210 9876543210
        //                                  ** : v[0]
        //                                **   : v[1]
        //          **                         : v[11]
        //      ****                           : v.len (1-12)
        let &AcgtStr(ref v) = self;
        let len = v.len() as u32;
        let mut sum = len << (2*12);
        for i in 0..(len as usize) {
            let bb = match v[i] {
                Acgt::A => 0,
                Acgt::C => 1,
                Acgt::G => 2,
                Acgt::T => 3,
            } << (2 * i);
            sum |= bb;
        }

        sum
    }
}

impl AcgtRep {
    fn new(bit: u32) -> Self {
        let len = 1 << (bit-1);
        let hash_list = vec![None; len];
        let mut mask = 0;
        for _i in 0..(bit-1) {
            mask <<= 1;
            mask +=  1;
        }
        AcgtRep{ hash_list, bit, len, mask }
    }

    fn insert(&mut self, e: AcgtStr) {
        let i = self.calc_hash(&e);
        if let Some(ref mut l) = self.hash_list[i].as_mut() {
            if l.contains(&e) {
                dprintln!("rep: already exists {:?}", e);
            } else {
                dprintln!("rep: insert {}<-{:?}", i, e);
                l.push(e);
            }
            return;
        } 

        if self.hash_list[i].is_none() {
            dprintln!("rep: first insert {}<-{:?}", i, e);
            let mut v = Vec::with_capacity(32);
            v.push(e);
            self.hash_list[i] = Some(v);
        }
    }

    fn find(& self, e: &AcgtStr) -> bool {
        let i = self.calc_hash(&e);
        if let Some(ref l) = self.hash_list[i].as_ref() {
            l.contains(&e)
        } else {
            false
        }
    }

    fn calc_hash(&self, e: &AcgtStr) -> usize {
        let t = e.as_u32();
        let t1 = t >> 17;
        ((t1+t) as usize) & self.mask
    }
}

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

#[derive(Debug)]
struct Answer {
    v: Vec<bool>,     // length=q.n
}

trait IntoQuiz {
    fn into_quiz(self) -> Quiz;
}

impl<I: Input> IntoQuiz for I {
    fn into_quiz(mut self) -> Quiz {
        let n: usize = self.parse_next().unwrap();
        let mut v: Vec<Command> = Vec::with_capacity(n);
        for _i in 0..n {
            let command: String = self.parse_next().expect("Parse cmd error");
            let value: String = self.parse_next().expect("Parse value error");
            let value = AcgtStr::new(value);
            let command_str: &str = &command;
            let command = match command_str {
                "insert" => Command::Insert(value),
                "find"   => Command::Find(value),
                _ => panic!("Iligal command error"),
            };
            v.push(command);
        }
        Quiz { n, v }
    }
}

impl Quiz {
    fn solve(self) -> Answer {
        let mut rep = AcgtRep::new(16);
        dprintln!("rep: {:?}", rep);
        let mut ansv = Vec::with_capacity(self.v.len());

        for command in self.v {
            match command {
                Command::Insert(acgt) => rep.insert(acgt),
                Command::Find(acgt)   => {
                    let res = rep.find(&acgt);
                    ansv.push(res);
                }
            }
        }

        Answer{ v: ansv }
    }
}

impl Answer {
    fn print(self) {
        for e in self.v {
            if e {
                println!("yes");
            } else {
                println!("no");
            }
        }
    }
}

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

//==================================================
// 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 BufReadInput<R: BufRead> {
    input: R,
    tokens: VecDeque<Token>,
}

pub trait Input {
    fn read_next_word(&mut self) -> Option<Token>;

    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
        }
    }

    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)
    }

    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)
    }

    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,
            }
        }
    }
}
impl<R: BufRead> BufReadInput<R> {
    pub fn new(input: R) -> Self {
        let tokens = VecDeque::new();

        BufReadInput { input, tokens }
    }
}

impl<R: BufRead> Input for BufReadInput<R> {
    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,
            }
        }
    }

}

//TODO: Make CaseIterator
// ex) 
//  let mut input: Input ...
//  let mut iter: CaseIterator<Case=Command> = input.rest_into_cases(|i|   
//    let cmd:String = i.parse_next().expect("Parse error cmd");
//    let num:u32    = i.parse_next().expect("Parse error num");
//
//    Command::new(cmd, num)
//  );
//  let case1 = iter.next();
//  let case2 = iter.next();
//  ...


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;
}

//==================================================
// 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 insert_and_find() {
        let mut rep = AcgtRep::new(1024);
        let s1 = AcgtStr::new("ACGT".to_string());
        let s2 = AcgtStr::new("ACGT".to_string());
        let s3 = AcgtStr::new("ACGTACGT".to_string());
        let s4 = AcgtStr::new("ACGTACGT".to_string());
        assert_eq!(false, rep.find(&s2));
        assert_eq!(false, rep.find(&s3));
        rep.insert(s1);
        assert_eq!(true,  rep.find(&s2));
        assert_eq!(false, rep.find(&s3));
        rep.insert(s4);
        assert_eq!(true,  rep.find(&s2));
        assert_eq!(true,  rep.find(&s3));
    }

    #[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);
    }
}



Measured memory_bytes: 74664