#include<bits/stdc++.h>
using namespace std;
int jue(int now){
if(now<0)return -now;
return now;
}
struct edge{
int a,b,c;
};
int kind[100005];
string name[100005];
int ans[100005];
int nxt[6000005][26];
int y[6000005];
edge each[100005];
vector<int>x[6000005];
vector<pair<int,int> >z[100005];
int last=0;
int which[100005];
int top=0;
int query(string s){
int now=0;
for(int i=0;i<s.size();i++){
if(!nxt[now][(int)(s[i]-'a')])nxt[now][(int)(s[i]-'a')]=++top;
now=nxt[now][(int)(s[i]-'a')];
}
return now;
}
void up(string s,int had){
int now=0;
for(int i=0;i<s.size();i++){
if(!nxt[now][(int)(s[i]-'a')])nxt[now][(int)(s[i]-'a')]=++top;
now=nxt[now][(int)(s[i]-'a')];
y[now]++;
for(int j=0;j<x[now].size();j++)z[x[now][j]].push_back(make_pair(y[now],had));
}
return;
}
void down(string s,int had){
int now=0;
for(int i=0;i<s.size();i++){
if(!nxt[now][(int)(s[i]-'a')])nxt[now][(int)(s[i]-'a')]=++top;
now=nxt[now][(int)(s[i]-'a')];
y[now]--;
for(int j=0;j<x[now].size();j++)z[x[now][j]].push_back(make_pair(y[now],had));
}
return;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
ans[i]=-1;
scanf("%d",&kind[i]);
if(kind[i]<=2)cin>>name[i];
else {
which[i]=last;
last=i;
string s;
cin>>s;
scanf("%d%d%d",&each[i].a,&each[i].b,&each[i].c);
int at=query(s);
x[at].push_back(i);
}
}
for(int i=1;i<=n;i++){
if(kind[i]==1)up(name[i],i);
else if(kind[i]==2)down(name[i],i);
else{
for(int j=0;j<z[i].size();j++){
if(z[i][j].first>(jue(ans[which[i]])*each[i].a+each[i].b)%each[i].c){
ans[i]=z[i][j].second;
break;
}
}
printf("%d\n",ans[i]);
}
}
return 0;
}