use std::ops::DivAssign;
use std::ops::MulAssign;
use std::ops::SubAssign;
use std::collections::BinaryHeap;
use std::str::FromStr;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::ops::Neg;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Add;
use std::ops::{AddAssign, Sub};
use std::cmp::max;
use std::collections::VecDeque;
use std::cmp::min;
use std::collections::{HashMap, BTreeSet};
use std::cmp::Ordering;
use std::fmt::Debug;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer.trim().to_owned()
}
fn read_lines<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
fn read_tabulate<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split_whitespace().map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
macro_rules! read_map {
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
}
macro_rules! read {
    (mut $ident: ident: [$ty:ty]) => {
        let mut $ident = read_values::<$ty>();
    };
    ($ident: ident: [$ty:ty]) => {
        let $ident = read_values::<$ty>();
    };
    (mut $ident: ident: [[$ty:ty]; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    ($ident: ident: [[$ty:ty]; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$ty:ty; $size:expr]) => {
        let mut $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$ty:ty; $size:expr]) => {
        let $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    ($($token: tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        read_from_iter!(iter; $($token)*);
    };
}
macro_rules! read_from_iter {
    ($iter:expr; mut $ident:ident:$ty:ty, $($rest:tt)*) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; $ident:ident:$ty:ty, $($rest:tt)*) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; mut $ident:ident:$ty:ty) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter:expr; $ident:ident:$ty:ty) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter: expr; ) => {};
}
struct KeyValue<K, V> {
    key: K,
    value: V
}
impl <K: PartialOrd, V> PartialEq for KeyValue<K, V> {
    fn eq(&self, other: &Self) -> bool {
        self.key.eq(&other.key)
    }
}
impl <K: PartialOrd, V> Eq for KeyValue<K, V> {}
impl <K: PartialOrd, V> PartialOrd for KeyValue<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K: PartialOrd, V> Ord for KeyValue<K, V> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.key.partial_cmp(&other.key).ok_or("Can't Compare").unwrap()
    }
}
#[derive(Copy, Clone, Debug)]
enum Digit {
    Num(char),
    Any
}
impl Digit {
    fn is_match(&self, digit: char) -> bool {
        match self {
            &Digit::Num(c) => c == digit,
            &Digit::Any => true
        }
    }
}
#[derive(Clone, Debug)]
struct Pattern {
    digits: Vec<Digit>
}
impl Pattern {
    fn is_match(&self, address: &Address) -> bool {
        (0 .. 8).into_iter().all(|d| self.digits[d].is_match(address.digits[d]))
    }
}
impl Pattern {
    fn from_str(pattern: &String) -> Pattern {
        Pattern{digits: pattern.chars().map(|c| {
            match c {
                '?' => Digit::Any,
                d if d.is_digit(10) => Digit::Num(c),
                _ => panic!()
            }
        }).collect()}
    }
}
#[derive(Clone, Debug)]
struct Packet {
    from: Address, to: Address
}
#[derive(Clone, Debug)]
enum Rule {
    Permit{from: Pattern, to: Pattern},
    Deny{from: Pattern, to: Pattern},
}
impl Rule {
    fn is_match(&self, packet: &Packet) -> bool {
        match self.clone() {
            Rule::Permit{from: from, to: to} => from.is_match(&packet.from) && to.is_match(&packet.to),
            Rule::Deny{from: from, to: to} => from.is_match(&packet.from) && to.is_match(&packet.to),
        }
    }
}
#[derive(Clone, Debug)]
struct Address {
    digits: Vec<char>
}
impl Address {
    fn from_str(address: &String) -> Address {
        Address{digits: address.chars().collect()}
    }
}

fn main() {
    loop {
        read!(n: usize, m: usize);
        if n == 0 && m == 0 {break;}
        read_map!(rules: [{
            read!(rule_type: String, from: String, to: String);
            match &rule_type[..] {
                "permit" => Rule::Permit{from: Pattern::from_str(&from), to: Pattern::from_str(&to)},
                "deny" => Rule::Deny{from: Pattern::from_str(&from), to: Pattern::from_str(&to)},
                _ => panic!()
            }
        }; n]);
        let mut permitted = Vec::new();
        for _ in 0 .. m {
            read!(from: String, to: String, message: String);
            let packet = Packet{from: Address::from_str(&from), to: Address::from_str(&to)};
            if let Some(&Rule::Permit{from:_, to:_}) = rules.iter().rev().find(|rule| rule.is_match(&packet)) {
                permitted.push((from, to, message));
            }
        }
        println!("{}", permitted.len());
        for (from, to, message) in permitted {
            println!("{} {} {}", from, to, message);
        }
    }
}


Measured memory_bytes: 5056