#include <iostream>
#include <queue>
#include <map>
using namespace std;
long long addr_start=0;
long long num[10005][2];
long long maxn=0;
string finds[10005];
map<string,pair<long long,long long> > m;
map<string,long long>limit;
map<string,string> structt[10005],structt2[10005];
map<string,long long> findd;
map<string,long long> find_small;
map<string,long long> where1,where2;
queue<string> q,q2;
bool check(string sss){
if(sss=="byte"||sss=="short"||sss=="int"||sss=="long"){
return false;
}
return true;
}
void solve_before1(string tt,string nn,string ss,long long &ans1,long long &ans2){
long long lenn=findd[tt];
long long large=0;
long long require=0;
long long last=0;
for(long long i=1;i<=lenn;i++){
require=max(require,where2[structt[i][tt]]);
}
for(long long i=1;i<=lenn;i++){
if(check(structt[i][tt])){
last=where1[structt[i][tt]];
require=max(require,where2[structt[i][tt]]);
long long len=require;
long long large2=large/len*len;
if(large2!=large){
large=large2+len;
}
large+=last;
}else{
require=max(require,limit[structt[i][tt]]);
long long lim=require;
long long len2=large/lim*lim;
if(len2!=large){
large=len2+lim;
}
large+=last;
last=limit[structt[i][tt]];
}
}
ans1=large;
ans2=require;
limit[ss]=max(limit[ss],require);
}
void solve1(string tt,string nn,string ss,long long numm,long long &ans1,long long &ans2){
long long large=0;
long long lim=0;
if(check(tt)){
long long ans1,ans2;
solve_before1(tt,nn,ss,ans1,ans2);
large=ans1;
lim=ans2;
}else{
large=limit[tt];
lim=limit[tt];
limit[ss]=max(limit[ss],limit[tt]);
}
structt[numm][ss]=tt;
structt2[numm][ss]=nn;
findd[ss]++;
ans1=large;
ans2=lim;
long long ans11=ans1/ans2*ans2;
if(ans11!=ans1){
ans1=ans11+ans2;
}
where1[ss]+=ans1;
where2[ss]+=ans2;
}
void solve_before2(string tt,string nn){
if(!check(tt)){
maxn++;
long long lim=limit[tt];
while(!q.empty()){
finds[maxn]+=q.front();
if(q.size()>1){
finds[maxn]+=".";
}
q2.push(q.front());
q.pop();
}
finds[maxn]+=nn;
while(!q2.empty()){
q.push(q2.front());
q2.pop();
}
long long len2=addr_start/lim*lim;
if(len2!=addr_start){
addr_start=len2+lim;
}
long long len=lim+addr_start-1;
finds[maxn]=nn;
num[maxn][0]=addr_start;
long long len3=len/lim*lim;
if(len3!=len){
len=len3+lim;
}
m[nn]=make_pair(addr_start,len);
addr_start=len;
num[maxn][1]=addr_start;
return;
}else{
long long addr3=addr_start/limit[tt]*limit[tt];
if(addr_start!=addr3){
addr_start=addr3+limit[tt];
}
long long limmit=0;
long long last2=0;
for(long long i=1;i<=findd[tt];i++){
maxn++;
limmit=max(limmit,where2[structt[i][tt]]);
long long nnn=addr_start/where2[structt[i][tt]]*where2[structt[i][tt]];
if(nnn!=addr_start){
addr_start=nnn+where2[structt[i][tt]];
}
long long name=addr_start;
last2=where1[structt[i][tt]];
if(check(structt[i][tt])){
maxn--;
q.push(nn);
solve_before2(structt[i][tt],structt2[i][tt]);
}else{
finds[maxn]="";
q.push(structt2[i][tt]);
while(!q.empty()){
q2.push(q.front());
finds[maxn]+=q.front();
if(q.size()!=1){
finds[maxn]+=".";
}
q.pop();
}
while(!q2.empty()&&q2.size()>1){
q.push(q2.front());
q2.pop();
}
find_small[finds[maxn]]=addr_start;
num[maxn][0]=addr_start;
name+=where1[structt[i][tt]];
num[maxn][1]=name;
m[nn]=make_pair(addr_start,name);
addr_start=name;
}
}
return;
}
}
void solve2(string tt,string nn){
long long addr2=addr_start/limit[tt]*limit[tt];
if(addr2!=addr_start){
addr_start=addr2+limit[tt];
}
if(!check(tt)){
maxn++;
long long lim=limit[tt];
long long len=limit[tt]+addr_start-1;
finds[maxn]=nn;
num[maxn][0]=addr_start;
find_small[nn]=addr_start;
m[nn]=make_pair(addr_start,len);
cout<<addr_start<<endl;
addr_start=len;
num[maxn][1]=addr_start;
}else{
q.push(nn);
cout<<addr_start<<endl;
long long addr2;
long long limmit=0;
long long last=0;
long long add2=addr_start/limit[tt]*limit[tt];
if(add2!=addr_start){
addr_start=add2+limit[tt];
}
for(long long i=1;i<=findd[tt];i++){
maxn++;
limmit=max(limmit,where2[structt[i][tt]]);
long long name2=addr_start/where2[structt[i][tt]]*where2[structt[i][tt]];
if(addr_start!=name2){
addr_start=name2+where2[structt[i][tt]];
}
long long name=addr_start;
if(check(structt[i][tt])){
maxn--;
long long now=q.size();
solve_before2(structt[i][tt],structt2[i][tt]);
while(q.size()>now){
q.pop();
}
}else{
finds[maxn]=nn+"."+structt2[i][tt];
find_small[finds[maxn]]=addr_start;
num[maxn][0]=addr_start;
name+=where1[structt[i][tt]];
num[maxn][1]=name;
m[nn]=make_pair(addr_start,name);
addr_start=name;
}
}
}
}
void solve3(string str){
cout<<find_small[str]<<endl;
}
void solve4(long long ad){
long long l=1,r=maxn;
long long flag=0;
while(l<=r){
long long mid=l+r>>1;
if(num[mid][0]<=ad&&ad<=num[mid][1]){
cout<<finds[mid]<<endl;
flag=1;
break;
}else if(ad>num[mid][1]){
l=mid+1;
}else{
r=mid-1;
}
}
if(flag==0&&!(num[l+r>>1][0]<=ad&&ad<=num[l+r>>1][1])){
cout<<"ERR\n";
}else if(flag==0){
cout<<finds[l+r>>1]<<endl;
}
}
signed main(){
long long n;
cin>>n;
where1["byte"]=where2["byte"]=limit["byte"]=1;
where1["short"]=where2["short"]=limit["short"]=2;
where1["int"]=where2["int"]=limit["int"]=4;
where1["long"]=where2["long"]=limit["long"]=8;
for(long long ii=1;ii<=n;ii++){
long long op;
cin>>op;
if(op==1){
string s;
long long k;
cin>>s>>k;
long long ans1=0,ans2=0,last=0,try3=1;
for(long long i=1;i<=k;i++){
string t,n;
cin>>t>>n;
long long try1,try2;
ans1+=last;
long long anss=ans1/try3*try3;
if(anss!=ans1){
ans1=anss+try3;
}
solve1(t,n,s,i,try1,try2);
last=try1-1;
try3=try2;
ans2=max(ans2,try2);
}
ans1+=last;
long long ans11=ans1/ans2*ans2;
if(ans11!=ans1){
ans1=ans11+ans2;
}
cout<<ans1<<" "<<ans2<<endl;
}else if(op==2){
string t,n;
cin>>t>>n;
solve2(t,n);
}else if(op==3){
string s;
cin>>s;
solve3(s);
}else{
long long addr;
cin>>addr;
solve4(addr);
}
}
return 0;
}