#include <iostream>
#include<string>
#include<set>
#include<vector>
using namespace std;
//用一个set<string>来存储规则集r(自动排序去重);用一个vector<string>存储数据集I
//用二维数组vector<vector<int>>index存储符合规则的I元素的下标,每一行对应set中的一个规则
//对于r中每个元素,遍历I中元素判断r是否是其子串,使用find函数来快速判断
//如果符合要求,则将该I中元素的下标存到二维数组中
//最后根据index来输出即可
//易错点:set容器如果使用string来排序和int的规则不同,只看首位数小的靠前,要注意一下
int main() {
    //初始化容器
    int n; cin>>n;
    vector<string>I(n);
    for(int i=0; i<n; i++)
        cin>>I[i];
    int m; cin>>m;
    set<int>rule;//这里从string改成了int
    while(m--) 
    {
        int num; cin>>num;
        //string r=to_string(num);
        rule.insert(num);
    }
    vector<vector<int>>index;//存储下标
    //遍历rule中所有元素
    for(int r: rule)
    {
        //index新开一行存放r对应的所有下标
        index.push_back({});
        //遍历I中所有元素
        for(int i=0; i<n; i++)
        {
            //使用find()函数判断r是否是数据I[i]的子串
            if(I[i].find(to_string(r))!=string::npos)//找到子串
            {
                //记录下标到index容器最后一行中
                index.back().push_back(i);
            }
        }
    }
    //根据index来输出结果
    //先输出总数k
    int k=0;
    for(auto line: index)
        k+=line.size()>0 ? 2*(line.size()+1) : 0 ;
    cout<<k;
    //输出结果
    auto it=rule.begin();
    for(auto line:index)
    {
        if(line.size()==0)//跳过无效规则
        {
            it++;
            continue;
        }
        //输出结果
        cout<<" "<<*it<<" "<<line.size();
        for(auto i :line)
        {
            cout<<" "<<i<<" "<<I[i];
        }
        it++;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")