#include <bits/stdc++.h>
#define ll long long
#define fast ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define pii pair<int,int>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define pll pair<ll,ll>
#define fi first
#define se second
#define MASK(i) (1ll<<i)
#define bit(mask,i) ((mask>>i)&1)
#define el '\n'
#define debug cout << "NOBUG" << endl;
#define pb push_back
#define ALL(vec) vec.begin(),vec.end()
#define File(NAME) freopen(NAME".inp" , "r" , stdin); freopen(NAME".out", "w" , stdout);

using namespace std;
const int mod = 1e9+7 , oo = 0x3f3f3f3f;
const ll ooll = 0x3f3f3f3f3f3f3f3f;

template <class X , class Y>
bool maximize(X &x , Y y) {
    if(x < y) {
        x = y;
        return true;
    }
    return false;
}
template <class X , class Y>
bool minimize(X &x , Y y) {
    if(x > y) {
        x = y;
        return true;
    }
    return false;
}
template <class X , class Y>
void add_mod(X &x , Y y , int mod) {
    x += y;
    if(x >= mod) x-=mod;
    if(x < 0) x += mod;
}

const int NUMBER_OF_NODES = 1e6+5;

struct Node {
    int child[26] , next[26];
    int fail;
    vector <int> found;
}node[NUMBER_OF_NODES];

struct AC {
    int curCnt = 0;
    inline int newNode() {
        curCnt++;

        Node &curNode = node[curCnt];

        for(int c = 0 ; c < 26 ; c++) {
            curNode.child[c] = -1;
            curNode.next[c] = -1;
        }
        curNode.fail = -1;
        curNode.found.clear();

        return curCnt;
    }

    int root = newNode();

    void add(string s , int id) {
        int p = root;
        for(char c : s) {
            if(node[p].child[c-'a'] == -1) node[p].child[c-'a'] = newNode();
            p = node[p].child[c-'a'];
        }
        node[p].found.pb(id);
    }

    void bfs() {
        node[root].fail = root;
        for(int c = 0 ; c < 26 ; c++) {
            node[root].next[c] = (node[root].child[c] != -1 ? node[root].child[c] : root);
        }

        queue <int> q;
        q.push(root);

        while(q.size()) {
            int u = q.front();q.pop();

            for(int c = 0 ; c < 26 ; c++)if(node[u].child[c] != -1) {
                int v = node[u].child[c];

                node[v].fail = (u == root ? root : node[node[u].fail].next[c]);
                for(int c = 0 ; c < 26 ; c++) {
                    node[v].next[c] = (node[v].child[c] != -1 ? node[v].child[c] : node[node[v].fail].next[c]);
                }

                for(int x : node[node[v].fail].found) {
                    node[v].found.pb(x);
                }

                q.push(v);
            }
        }
    }
}Aho;

// found do not very necessary , if you have to count the number of appearance of Si , just do back dfs like in kmp
// i do not sure about if found can cause mle to my code , so just do not use it
// it is so risky

int main() {
    fast
    File("TASK");
    int n; cin >> n;
    for(int i = 1 ; i <= n ; i++) {
        string s; cin >> s;
        Aho.add(s , i);
    }

    Aho.bfs();

    string t; cin >> t;
    int p = Aho.root;
    for(int i = 0 ; i < t.size(); i++) {
        int c = t[i]-'a';
        p = node[p].next[c];
        cout << p << ':';
        for(int x : node[p].found) cout << x << ' ';
        cout << el;
    }
    return 0;
}
/*
input:
6
di
du
didu
dudua
duadi
didi
diduduadi
output:
2|
3|1
5|
6|3 2
7|
8|2
9|4
11|
12|5 1
*/
