#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;
#define N 1505
#define rep(i, n) for (int i = 0; i < (n);i++)
#define FOR for (int j = limit[i]; j < limit[i + 1];j++)
typedef bool Bit[N];
map<string, Bit> Index;
string doc[N];
int limit[105];
int n, lines, m;
void update(string s,int p)
{
string word;
string::iterator it = s.begin();
for (it; it != s.end();it++)
if(isalpha(*it))
*it = tolower(*it);
else
{
*it = ' ';
}
stringstream ss(s);
while(ss>>word)
Index[word][p] = true;
}
int main(){
scanf("%d ", &n);
rep(i,n){
limit[i] = lines;
while(getline(cin,doc[lines]),doc[lines]!="**********"){
update(doc[lines], lines);
lines++;
}
}
limit[n] = lines;
string s;
Bit mark;
bool *A, *B;
scanf("%d ",&m);
while(m--)
{
getline(cin, s);
if(s[0]=='N'){
A = Index[s.substr(4)];
rep(i,n){
bool logo = true;
FOR if (A[j]) { logo = false;
break;
}
FOR mark[j] = logo;
}
}
else if(s.find("AND")!=string::npos)
{
int p=s.find(" AND ");
A=Index[s.substr(0,p)];
B = Index[s.substr(p + 5)];
memset(mark,0,sizeof(mark));
bool hasA, hasB;
rep(i,n)
{
hasA = hasB = false;
FOR if (A[j]) {
hasA = true;
break;
}
FOR if(B[j]){
hasB = true;
break;
}
if(!(hasA&&hasB))
continue;
FOR mark[j] = (A[j] || B[j]);
}
}
else if(s.find("OR")!=string::npos)
{
int p=s.find(" OR ");
A=Index[s.substr(0,p)];
B=Index[s.substr(p+4)];
rep(i, lines) mark[i] = (A[i] || B[i]);
}
else memcpy(mark, Index[s], sizeof(mark));
bool hasOut = false, needOut = false;
rep(i,n){
if(hasOut)
needOut = true;
hasOut = false;
FOR if(mark[j])
{
if(needOut)
{
cout << "----------\n";
needOut = false;
}
cout << doc[j] << "\n";
hasOut = true;
}
}
if(!(needOut||hasOut))
cout << "Sorry, I found nothing.\n";
cout << "==========\n";
}
return 0;
}