#include <iostream>
#include<string>
#include<sstream>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=105;
struct Selector{
int row;//行数
int rank;//层级
string label;//标签
string id;//标签内容
};
int n,m;
Selector sel[MAXN];
string html,css;
int main(int argc, char** argv) {
cin>>n>>m;
getchar();
for(int i=1;i<=n;i++){
getline(cin,html);
sel[i].row=i;
istringstream ss(html);
string str;
ss>>str;
int cd;
for(cd=0;str[cd]=='.';cd++);
sel[i].rank=cd/2;//计算层级
sel[i].label=str.substr(cd);//获取标签('...'之后的字符串)
transform(sel[i].label.begin(),sel[i].label.end(),
sel[i].label.begin(),::tolower);//将标签转换成小写字母
while(ss>>str){
if(str[0]=='#')
sel[i].id=str;
}
}
for(int i=0;i<m;i++){
getline(cin,css);
istringstream ss(css);
vector<string>query;//动态的序列容器,动态数组
string str;
while(ss>>str){
if(str[0]!='#'){
transform(str.begin(),str.end(),str.begin(), ::tolower);
}
query.push_back(str);
}
//查询条件的最后一个标签或属性是关键字
int ans[MAXN];//存储满足条件的行数
int cnt=0;//计数
int num;//实际满足条件的个数
vector<string>::reverse_iterator it=query.rbegin();//反向迭代器
for(int j=1;j<=n;j++){
if(sel[j].id==*it||sel[j].label==*it){
ans[cnt++]=j;
}
}
num=cnt;
for(int c=0;c<cnt;c++){
it=query.rbegin()+1;
int mrank=sel[ans[c]].rank;
for(int j=ans[c]-1;it!=query.rend()&&j>0;j--){
if(sel[j].rank<mrank&&(*it==sel[j].label||*it==sel[j].id)){
it++;
mrank=sel[j].rank;
}
}
if(it!=query.rend()){
ans[c]=0;
num--;
}
}
cout<<num;
for(int j=0;j<cnt;j++){
if(ans[j]){
cout<<" "<<ans[j];
}
}
cout<<endl;
}
return 0;
}