//4681418 2011-09-30 12:26:14 Accepted 1823 140MS 7520K 3762 B C++ nkhelloworld
//4681419 2011-09-30 12:26:40 Accepted 1823 203MS 7588K 3762 B G++ nkhelloworld
/*
二维线段树,一个线段树中套一个线段树,求区间最大值
再次强调要注意区间范围是不是反着的,如h1 > h2时应swap
注意读入浮点数的时候可能产生精度误差,*10再转int可能就错了
此题,如果不加eps,在C++下可以AC,在G++下是WA
*/
#include <cstdio>
#include <iostream>
#define eps 1e-4
using namespace std;
#define MAXH 110
#define MAXA 1010
struct SUBTREE
{
int lt,rt;
double maxval;
};
struct MAINTREE
{
int lt,rt;
SUBTREE subtree[MAXA*4];
}tree[MAXH*4];
void buildsubtree(int paroot,int root,int lt,int rt)
{
tree[paroot].subtree[root].lt = lt;
tree[paroot].subtree[root].rt = rt;
tree[paroot].subtree[root].maxval = -1.0;
if(lt == rt) return ;
int mid = (lt + rt)>>1;
buildsubtree(paroot,root<<1,lt,mid);
buildsubtree(paroot,root<<1|1,mid+1,rt);
}
void buildmaintree(int root,int lt,int rt)
{
tree[root].lt = lt; tree[root].rt = rt;
buildsubtree(root,1,0,1000);
if(lt == rt) return ;
int mid = (lt + rt)>>1;
buildmaintree(root<<1,lt,mid);
buildmaintree(root<<1|1,mid+1,rt);
}
void update2(int paroot,int root,int h,int active,double love)
{
if(tree[paroot].subtree[root].maxval < love) tree[paroot].subtree[root].maxval = love;
if(tree[paroot].subtree[root].lt == tree[paroot].subtree[root].rt) return ;
int mid = (tree[paroot].subtree[root].lt + tree[paroot].subtree[root].rt)>>1;
if(active <= mid) update2(paroot,root<<1,h,active,love);
else update2(paroot,root<<1|1,h,active,love);
}
void update(int root,int h,int active,double love)
{
update2(root,1,h,active,love);
if(tree[root].lt == tree[root].rt) return ;
int mid = (tree[root].lt + tree[root].rt)>>1;
if(h <= mid) update(root<<1,h,active,love);
else update(root<<1|1,h,active,love);
}
double query2(int paroot,int root,int h1,int h2,int a1,int a2)
{
if(tree[paroot].subtree[root].lt == a1 && tree[paroot].subtree[root].rt == a2)
return tree[paroot].subtree[root].maxval;
int mid = (tree[paroot].subtree[root].lt + tree[paroot].subtree[root].rt)>>1;
if(a2 <= mid)
return query2(paroot,root<<1,h1,h2,a1,a2);
else if(a1 > mid)
return query2(paroot,root<<1|1,h1,h2,a1,a2);
else
return max(query2(paroot,root<<1,h1,h2,a1,mid), query2(paroot,root<<1|1,h1,h2,mid+1,a2) );
}
double query(int root,int h1,int h2,int a1,int a2)
{
if(tree[root].lt == h1 && tree[root].rt == h2) return query2(root,1,h1,h2,a1,a2);
int mid = (tree[root].lt + tree[root].rt)>>1;
if(h2 <= mid) return query(root<<1,h1,h2,a1,a2);
else if(h1 > mid) return query(root<<1|1,h1,h2,a1,a2);
else return max( query(root<<1,h1,mid,a1,a2), query(root<<1|1,mid+1,h2,a1,a2) );
}
int main()
{
int m,i,j,h1,h2;
double a,love,a1,a2;
char op[5];
while(scanf("%d",&m),m)
{
buildmaintree(1,0,100);
while(m--)
{
scanf("%s",op);
if(op[0] == 'I')
{
scanf("%d%lf%lf",&h1,&a,&love);
h1 = h1 - 100;
a += eps;
update(1,h1,(int)(a*10),love);
}
else
{
scanf("%d%d%lf%lf",&h1,&h2,&a1,&a2);
if(h1 > h2) swap(h1,h2);
if(a1 > a2) swap(a1,a2);
h1 -= 100; h2 -= 100;
a1 += eps; a2 += eps;
double ans = query(1,h1,h2,(int)(a1*10),(int)(a2*10));
if(ans < 0)
printf("-1\n");
else
printf("%.1f\n",ans);
}
}
}
return 0;
}