Problem:
Max Score: 250 Points

Problem Statement

Mr.X, who the handle name is T, looked at the list which written N handle names, S_1, S_2, ..., S_N.

But he couldn't see some parts of the list. Invisible part is denoted ?.

Please calculate all possible index of the handle name of Mr.X when you sort N+1 handle names (S_1, S_2, ..., S_N and T) in lexicographical order.

Note: If there are pair of people with same handle name, either one may come first.

Input

The input is given from standard input in the following format.

N
S_1
S_2
:
S_N
T

Output

Calculate the possible index and print in sorted order. The output should be separated with a space. Don't print a space after last number.

Put a line break in the end.

Constraints

1 ≤ N ≤ 10000

1 ≤ |S_i|, |T| ≤ 20 (|A| is the length of A.)

S_i consists from lower-case alphabet and ?.

T consists from lower-case alphabet.

Scoring

Subtask 1 [ 130 points ]

There are no ?'s.

Subtask 2 [ 120 points ]

There are no additional constraints.

Sample Input 1

2
tourist
petr
e

Sample Output 1

1

There are no invisible part, so there are only one possibility.
The sorted handle names are e, petr, tourist, so e comes first.

Sample Input 2

2
?o?r?s?
?et?
e

Solution in Rust (1.15.1) (judge verdict: Accepted)

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::Read;
#[allow(dead_code)]
fn getline() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok().unwrap();
    ret
}
fn get_word() -> String {
    let mut stdin = std::io::stdin();
    let mut u8b: [u8; 1] = [0];
    loop {
        let mut buf: Vec<u8> = Vec::with_capacity(16);
        loop {
            let res = stdin.read(&mut u8b);
            if res.unwrap_or(0) == 0 || u8b[0] <= b' ' {
                break;
            } else {
                buf.push(u8b[0]);
            }
        }
        if buf.len() >= 1 {
            let ret = String::from_utf8(buf).unwrap();
            return ret;
        }
    }
}

#[allow(dead_code)]
fn get<T: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }

fn comp(s: &[char], t: &[char], o: Ordering) -> bool {
    let mut pos = 0;
    let lim = match o {
        Ordering::Less => 'a',
        Ordering::Greater => 'z',
        _ => panic!(),
    };
    loop {
        if pos >= s.len() && pos >= t.len() {
            return true;
        }
        if pos >= t.len() {
            return o == Ordering::Greater;
        }
        if pos >= s.len() {
            return o == Ordering::Less;
        }
        if s[pos] == '?' {
            if t[pos] != lim {
                return true;
            }
        }
        if s[pos] != t[pos] {
            return s[pos].cmp(&t[pos]) == o;
        }
        pos += 1;
    }
}

fn solve() {
    let n = get();
    let s: Vec<Vec<_>> = (0 .. n).map(|_| get_word().chars().collect())
        .collect();
    let t: Vec<_> = get_word().chars().collect();
    let mut le = 0;
    let mut ge = 0;
    for i in 0 .. n {
        if comp(&s[i], &t, Ordering::Less) {
            le += 1;
        }
        if comp(&s[i], &t, Ordering::Greater) {
            ge += 1;
        }
    }
    for i in n - ge .. le + 1 {
        print!("{}{}", i + 1, if i == le { "\n" } else { " " });
    }
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}