#include<bits/stdc++.h>
using namespace std;
#define ERROR "ERR"
struct Type{
string Name;
vector<Type*>Member_Type;
vector<string>Member_Name;
long long Mem_Ali;
long long Mem_Siz;
void clear(){
Member_Type.clear();
Member_Name.clear();
Name.clear();
Mem_Ali=Mem_Siz=0;
}
};
Type Def_Type[260];
long long Type_Num;
map<string,Type*>Name_Type;
struct Element{
string Name;
Type Ele_Type;
long long Address;
void clear(){
Ele_Type.clear();
Address=0;
Name.clear();
}
};
Element Def_Element[260];
long long Element_Num;
map<string,Element*>Name_Element;
long long Address_Pos;
map<pair<long long,long long>,Element*>Add_Ele;
void init(){
Def_Type[1].Name="byte";
Def_Type[2].Name="short";
Def_Type[3].Name="int";
Def_Type[4].Name="long";
Def_Type[1].Mem_Ali=Def_Type[1].Mem_Siz=1;
Def_Type[2].Mem_Ali=Def_Type[2].Mem_Siz=2;
Def_Type[3].Mem_Ali=Def_Type[3].Mem_Siz=4;
Def_Type[4].Mem_Ali=Def_Type[4].Mem_Siz=8;
Name_Type["byte"]=&Def_Type[1];
Name_Type["short"]=&Def_Type[2];
Name_Type["int"]=&Def_Type[3];
Name_Type["long"]=&Def_Type[4];
Type_Num=4;
}
void Type_Create(string Type_Name,long long cnt,string *Name_Member,string *Type_Member){
Type New_Type;
New_Type.clear();
New_Type.Name=Type_Name;
for(int i=1;i<=cnt;++i){
New_Type.Member_Type.push_back(Name_Type[Type_Member[i]]);
New_Type.Member_Name.push_back(Name_Member[i]);
}
long long pos=0;
vector<Type*>::iterator it=New_Type.Member_Type.begin();
for(;it!=New_Type.Member_Type.end();it++){
long long Ali=(*it)->Mem_Ali;
long long Siz=(*it)->Mem_Siz;
New_Type.Mem_Ali=max(New_Type.Mem_Ali,Ali);
if(pos%Ali)pos=(pos/Ali+1)*Ali;
pos+=Siz;
}
if(pos%New_Type.Mem_Ali)pos=(pos/New_Type.Mem_Ali+1)*New_Type.Mem_Ali;
New_Type.Mem_Siz=pos;
Def_Type[++Type_Num]=New_Type;
Name_Type[Type_Name]=&Def_Type[Type_Num];
}
void Element_Create(string Ele_Name,string Ele_Type){
Element New_Ele;
New_Ele.clear();
long long Ali=Name_Type[Ele_Type]->Mem_Ali;
long long Siz=Name_Type[Ele_Type]->Mem_Siz;
if(Address_Pos%Ali)Address_Pos=((Address_Pos/Ali+1)*Ali);
New_Ele.Address=Address_Pos;
New_Ele.Ele_Type=*Name_Type[Ele_Type];
New_Ele.Name=Ele_Name;
Def_Element[++Element_Num]=New_Ele;
Name_Element[Ele_Name]=&Def_Element[Element_Num];
Add_Ele[make_pair(Address_Pos,Address_Pos+Siz-1)]=&Def_Element[Element_Num];
Address_Pos+=Siz;
}
long long Ask_Ele(string Ele_Name){
queue<string>Name;
string tool;
tool.clear();
for(int i=0;i<(long long)Ele_Name.length();i++){
if(Ele_Name[i]=='.'){
Name.push(tool);
tool.clear();
}
else tool+=Ele_Name[i];
}
Name.push(tool);
long long pos=Name_Element[Name.front()]->Address;
Type type=Name_Element[Name.front()]->Ele_Type;
Name.pop();
while(!Name.empty()){
string NaMe=Name.front();
Name.pop();
vector<string>::iterator it1=type.Member_Name.begin();
vector<Type*>::iterator it2=type.Member_Type.begin();
for(;it1!=type.Member_Name.end();it1++,it2++){
if(pos%(*it2)->Mem_Ali)pos=(pos/(*it2)->Mem_Ali+1)*(*it2)->Mem_Ali;
if(*it1==NaMe){
type=**it2;
break;
}
else pos+=(*it2)->Mem_Ali;
}
}
return pos;
}
string Ask_Add(long long Add){
if(Add>=Address_Pos)return ERROR;
Element ELE;
map<pair<long long,long long>,Element*>::iterator it=Add_Ele.begin();
for(;it!=Add_Ele.end();it++){
if(Add<(*it).first.first or Add>(*it).first.second)continue;
ELE=*((*it).second);
break;
}
long long Pos_Aim=Add-ELE.Address,Pos_Start=0,Pos_End;
Type type=ELE.Ele_Type;
string ELE_NAME;
ELE_NAME.clear();
ELE_NAME+=ELE.Name;
while(!type.Member_Name.empty()){
vector<Type*>::iterator it1=type.Member_Type.begin();
vector<string>::iterator it2=type.Member_Name.begin();
for(;it1!=type.Member_Type.end();it1++,it2++){
Pos_End=Pos_Start+(*it1)->Mem_Siz;
if(Pos_Aim<Pos_End and Pos_Aim>=Pos_Start){
ELE_NAME+='.'+*it2;
type=**it1;
break;
}
else{
if(it1+1==type.Member_Type.end())return ERROR;
long long Ali=(*(it1+1))->Mem_Ali;
if(Pos_End%Ali)Pos_End=(Pos_End/Ali+1)*Ali;
if(Pos_Aim<Pos_End)return ERROR;
Pos_Start=Pos_End;
}
}
}
if(ELE_NAME=="")return ERROR;
return ELE_NAME;
}
long long n;
string s,ti,ni;
long long k,ADDR;
string in1[260],in2[260];
void solve(){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
int op;
scanf("%d",&op);
if(op==1){
cin>>s>>k;
for(int i=1;i<=k;++i)cin>>in1[i]>>in2[i];
Type_Create(s,k,in2,in1);
cout<<Def_Type[Type_Num].Mem_Siz<<' '<<Def_Type[Type_Num].Mem_Ali<<endl;
}
if(op==2){
cin>>ti>>ni;
Element_Create(ni,ti);
cout<<Def_Element[Element_Num].Address<<endl;
}
if(op==3){
cin>>s;
cout<<Ask_Ele(s)<<endl;
}
if(op==4){
cin>>ADDR;
cout<<Ask_Add(ADDR)<<endl;
}
}
}
int main(){
init();
solve();
return 0;
}