import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.stdio;

void main() {
    auto N = readln.chomp.to!int;
    auto S = N.iota.map!(_ => readln.chomp).array;

    auto trie = new Trie!(string)();
    foreach (s; S) trie.insert(s);
    trie.dfs1(trie.root);

    auto Q = readln.chomp.to!int;
    while (Q--) {
        auto x = readln.split;
        auto idx = x[0].to!int - 1;
        auto dict = x[1].to!string;
        auto order = new int[](26);
        foreach (i, a; dict) order[a-'a'] = i.to!int;
        trie.dfs2(trie.root, S[idx], 1, order).writeln;
    }
}

class Trie(T) {

    class Node {
        Edge[] edges;
        bool terminal;
        int data;

        this(bool terminal, int data = 0) {
            this.terminal = terminal;
            this.data = data;
        }
    }

    class Edge {
        Node to;
        T label;

        this(Node to, T label) {
            this.to = to;
            this.label = label;
        }
    }

    Node root;

    this() {
        root = new Node(false);
    }

    bool lookup(T str) {
        return lookup(root, str);
    }

    private bool lookup(Node node, T str) {
        if (node.terminal && str.empty) return true;
        foreach (e; node.edges) {
            if (str.startsWith(e.label)) {
                return lookup(e.to, str[e.label.length..$]);
            }
        }
        return false;
    }

    void insert(T str) {
        if (lookup(str)) return;
        insert(root, str);
    }

    private void insert(Node node, T str) {
        if (str.empty) {
            node.edges ~= new Edge(new Node(true, 1), str);
            return;
        }
        foreach (e; node.edges) {
            int common_prefix = -1;
            foreach (i; 0..min(e.label.length, str.length)) {
                if (e.label[i] != str[i]) break;
                common_prefix = i.to!int;
            }
            if (common_prefix == -1) continue;
            if (common_prefix + 1 == e.label.length) {
                insert(e.to, str[e.label.length..$]);
                return;
            }
            auto new_node = new Node(false);
            auto new_label = e.label[common_prefix+1..$].dup.to!T;
            new_node.edges = [new Edge(e.to, new_label)];
            e.to = new_node;
            e.label = e.label[0..common_prefix+1].dup;
            insert(new_node, str[common_prefix+1..$]);
            return;
        }
        auto new_node = new Node(false);
        node.edges ~= new Edge(new_node, str);
        insert(new_node, str[$..$]);
    }

    void dfs1(Node node) {
        foreach (e; node.edges) {
            dfs1(e.to);
            node.data += e.to.data;
        }
    }

    int dfs2(Node node, T str, int sm, int[] order) {
        if (str.empty) return sm;
        Node next_node;
        int common_prefix = -1;
        foreach (e; node.edges) {
            if (e.label.empty) {
                sm += 1;
                continue;
            }
            int x = order[e.label.front - 'a'];
            int y = order[str.front - 'a'];
            if (x < y) {
                sm += e.to.data;
            } else if (x == y) {
                next_node = e.to;
                common_prefix = e.label.length.to!int;
            }
        }
        return dfs2(next_node, str[common_prefix..$], sm, order);
    }
}
