#include<cstdio>
#include<cstring>
#include<vector>
typedef long long ll;
template<class T>
inline void read(T&x)
{
x=0;bool f=0;char c=getchar();
while((c<‘0‘||c>‘9‘)&&c!=‘-‘) c=getchar();if(c==‘-‘)f=1, c=getchar();
while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
x=f?-x:x;
}
const int MAXN(6000010);
struct Trie
{
int nx[10],now;
std::vector<int>last;
}trie[MAXN];int ktot=1;
int n,leng,k;
ll a,b,c,Ans;char str[100];
void update(int k,int y,int pos)
{
trie[k].now+=y;
if((int)trie[k].last.size()==trie[k].now)
trie[k].last.push_back(pos);
}
void insert(int y,int pos)
{
int k=1;
for(int i=1;i<=leng;i++)
{
if(!trie[k].nx[str[i]-‘a‘]){trie[k].nx[str[i]-‘a‘]=++ktot;trie[ktot].last.push_back(0);}
k=trie[k].nx[str[i]-‘a‘];
update(k,y,pos);
}
}
int query(int limt)
{
int k=1;
for(int i=1;i<=leng;i++)
{
if(!trie[k].nx[str[i]-‘a‘])return -1;
k=trie[k].nx[str[i]-‘a‘];
}
if((int)trie[k].last.size()<=limt)return -1;
else return trie[k].last[limt];
}
int main()
{
// freopen("C.in","r",stdin);
read(n);
for(int i=1;i<=n;i++)
{
read(k);
scanf("%s",str+1);leng=strlen(str+1);
if(k==1)insert(1,i); else
if(k==2)insert(-1,i); else
{
read(a);read(b);read(c);
Ans=((ll)a*Ans+b)%c;
Ans=query(Ans+1);
printf("%lld\n",Ans);
Ans=Ans<0?-Ans:Ans;
// fprintf(stderr,"!\n");
}
// fprintf(stderr,"fuck\n");
}
return 0;
}