Fedya and Sasha are friends, that's why Sasha knows everything about Fedya.Fedya keeps his patience in an infinitely large bowl. But, unlike the bowl, Fedya's patience isn't infinite, that is why let $$$v$$$ be the number of liters of Fedya's patience, and, as soon as $$$v$$$ becomes equal to $$$0$$$, the bowl will burst immediately. There is one tap in the bowl which pumps $$$s$$$ liters of patience per second. Notice that $$$s$$$ can be negative, in that case, the tap pumps out the patience. Sasha can do different things, so he is able to change the tap's speed. All actions that Sasha does can be represented as $$$q$$$ queries. There are three types of queries:  "1 t s"  — add a new event, means that starting from the $$$t$$$-th second the tap's speed will be equal to $$$s$$$.  "2 t"  — delete the event which happens at the $$$t$$$-th second. It is guaranteed that such event exists.  "3 l r v" — Sasha wonders: if you take all the events for which $$$l \le t \le r$$$ and simulate changes of Fedya's patience from the very beginning of the $$$l$$$-th second till the very beginning of the $$$r$$$-th second inclusive (the initial volume of patience, at the beginning of the $$$l$$$-th second, equals to $$$v$$$ liters) then when will be the moment when the bowl will burst. If that does not happen, then the answer will be $$$-1$$$. Since Sasha does not want to check what will happen when Fedya's patience ends, and he has already come up with the queries, he is asking you to help him and find the answer for each query of the $$$3$$$-rd type.It is guaranteed that at any moment of time, there won't be two events which happen at the same second.

The first line contans one integer $$$q$$$ ($$$1 \le q \le 10^5$$$)  — the number of queries. Each of the next $$$q$$$ lines have one of the following formats:   1 t s ($$$1 \le t \le 10^9$$$, $$$-10^9 \le s \le 10^9$$$), means that a new event is added, which means that starting from the $$$t$$$-th second the tap's speed will be equal to $$$s$$$.  2 t ($$$1 \le t \le 10^9$$$), means that the event which happens at the $$$t$$$-th second must be deleted. Guaranteed that such exists.  3 l r v ($$$1 \le l \le r \le 10^9$$$, $$$0 \le v \le 10^9$$$), means that you should simulate the process from the very beginning of the $$$l$$$-th second till the very beginning of the $$$r$$$-th second inclusive, and to say when will the bowl burst.  It is guaranteed that $$$t$$$, $$$s$$$, $$$l$$$, $$$r$$$, $$$v$$$ in all the queries are integers. Also, it is guaranteed that there is at least one query of the $$$3$$$-rd type, and there won't be a query of the $$$1$$$-st type with such $$$t$$$, that there already exists an event which happens at that second $$$t$$$.

For each query of the $$$3$$$-rd type, print in a new line the moment when the bowl will burst or print $$$-1$$$ if it won't happen. Your answer will be considered correct if it's absolute or relative error does not exceed $$$10^{-6}$$$. Formally, let your answer be $$$a$$$, and the jury's answer be $$$b$$$. Your answer is accepted if and only if $$$\frac{|a - b|}{\max{(1, |b|)}} \le 10^{-6}$$$.

NoteIn the first example all the queries of the $$$3$$$-rd type cover all the events, it's simulation is following:

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>

using namespace std;

const long long MAX_N = 1 << 18;

long long sum[2 * MAX_N];
long long minVal[2 * MAX_N];
long long posSum[2 * MAX_N];
long long value[2 * MAX_N];
map<int, int> M;

void update(long long node, long long low, long long high, long long nlow, long long nhigh, long long val) {
    if (nhigh < low || nlow > high) return;
    if (low >= nlow && high <= nhigh) {
        value[node] = val;
        sum[node] = (long long) val * (posSum[high + 1] - posSum[low]);
        if (val >= 0) {
            minVal[node] = 0;
        } else {
            minVal[node] = sum[node];
        }
        return;
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    update(node * 2 + 1, low, mid, nlow, nhigh, val);
    update(node * 2 + 2, mid + 1, high, nlow, nhigh, val);
    minVal[node] = min(minVal[node * 2 + 1], sum[node * 2 + 1] + minVal[node * 2 + 2]);
    sum[node] = sum[node * 2 + 1] + sum[node * 2 + 2];
}

double findPos(long long node, long long low, long long high, long long val) {
    if (low == high) {
        if (val == 0) return (double) posSum[low];
        if (value[node] >= 0) return -1.0;
        return posSum[low] + val / (double) (-value[node]);
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    if (-minVal[node * 2 + 1] >= val)
        return findPos(node * 2 + 1, low, (low + high) / 2, val);
    return findPos(node * 2 + 2, (low + high) / 2 + 1, high, val + sum[node * 2 + 1]);
}

pair<double, long long> get(long long node, long long low, long long high, long long nlow, long long nhigh, long long val) {
    if (nhigh < low || nlow > high) return {-1.0, 0};
    if (low >= nlow && high <= nhigh) {
        if (-minVal[node] >= val) {
            return {findPos(node, low, high, val), 0};
        }
        return {-1.0, sum[node]};
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    auto res = get(node * 2 + 1, low, mid, nlow, nhigh, val);
    if (res.first > -0.5)
        return res;
    auto ret = get(node * 2 + 2, mid + 1, high, nlow, nhigh, res.second + val);
    ret.second += res.second;
    return ret;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long q; cin >> q;
    vector<int> type(q);
    vector<int> a(q);
    vector<int> b(q);
    vector<int> c(q);
    vector<int> t; t.clear();
    for (long long i = 0; i < q; ++i) {
        cin >> type[i];
        if (type[i] == 1) cin >> a[i] >> b[i], t.push_back(a[i]);
        else if (type[i] == 2) cin >> a[i];
        else cin >> a[i] >> b[i] >> c[i], t.push_back(a[i]), t.push_back(b[i]);
    }

    sort(t.begin(), t.end());
    t.push_back(t.back() + 1);
    vector<int> nt = t;
    t.clear();
    for (long long i = 0; i < nt.size(); ++i)
        if (i == 0 || nt[i] != nt[i - 1])
            t.push_back(nt[i]);
    M.clear();
    for (long long i = 0; i < t.size(); ++i) {
        posSum[i] = t[i];
        M[t[i]] = i;
    }
    for (int i = t.size(); i < 2 * MAX_N; ++i)
        posSum[i] = posSum[i - 1];

    set<pair<int, int>> S; S.clear();
    S.insert({t.back(), 1e9});
    for (long long i = 0; i < q; ++i) {
        if (type[i] == 1) {
            auto it = S.lower_bound({a[i], 0});
            update(0, 0, MAX_N - 1, M[a[i]], M[(*it).first] - 1, b[i]);
            S.insert({a[i], b[i]});
        } else if (type[i] == 2) {
            auto it = S.lower_bound({a[i], -1e9 - 1});
            long long val = 0;
            if (it != S.begin()) {
                --it;
                val = (*it).second;
                ++it;
            }
            ++it;
            update(0, 0, MAX_N - 1, M[a[i]], M[(*it).first] - 1, val);
            --it;
            S.erase(it);
        } else {
            auto it = S.lower_bound({a[i], -1e9 -1});
            if (it == S.end() || (*it).first > b[i] || c[i] == 0) {
                printf("%.7lf\n", c[i] == 0 ? a[i] : -1.0);
            } else {
                auto pos = get(0, 0, MAX_N - 1, M[(*it).first], M[b[i]], c[i]);
                printf("%.7lf\n", (pos.first > b[i] ? -1.0 : pos.first));
            }
        }
    }

    return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define mp make_pair
#define fi first
#define se second
const int L=1,R=1000000000;
int n,tot,ord,l,r,p,mid,ans;
long long v,nw;
set<pair<int,int> > s;
set<pair<int,int> >::iterator it;

struct node
{
	int ls,rs;
	long long val,lazk,lazb;
	bool laz;
}t[6000001];

void pushdown(int i,int l,int r)
{
	if (!t[i].ls) t[i].ls=(++tot);
	if (!t[i].rs) t[i].rs=(++tot);
	if (!t[i].laz&&t[i].lazb==0) return;
	int mid=(l+r)>>1;
	if (t[i].laz)
	{
		t[t[i].ls].laz=t[t[i].rs].laz=1;
		t[t[i].ls].lazk=t[t[i].rs].lazk=t[i].lazk;
		t[t[i].ls].lazb=t[t[i].rs].lazb=t[i].lazb;
		if (t[i].lazk>0) t[t[i].ls].val=1ll*l*t[i].lazk+t[i].lazb,t[t[i].rs].val=1ll*(mid+1)*t[i].lazk+t[i].lazb;
		else t[t[i].ls].val=1ll*mid*t[i].lazk+t[i].lazb,t[t[i].rs].val=1ll*r*t[i].lazk+t[i].lazb;
		t[i].laz=0; t[i].lazk=t[i].lazb=0; return;
	}
	t[t[i].ls].val+=t[i].lazb; t[t[i].rs].val+=t[i].lazb;
	t[t[i].ls].lazb+=t[i].lazb; t[t[i].rs].lazb+=t[i].lazb;
	t[i].lazb=0;
}

long long getmin(long long a,long long b) {return a<b?a:b;}

void add(int i,int l,int r,int ql,int qr,long long v)
{
	if (ql>qr) return;
	if (l==ql&&r==qr) {t[i].val+=v,t[i].lazb+=v; return;}
	pushdown(i,l,r); int mid=(l+r)>>1;
	if (qr<=mid) add(t[i].ls,l,mid,ql,qr,v); else
	if (ql>mid) add(t[i].rs,mid+1,r,ql,qr,v); else
	add(t[i].ls,l,mid,ql,mid,v),add(t[i].rs,mid+1,r,mid+1,qr,v);
	t[i].val=getmin(t[t[i].ls].val,t[t[i].rs].val);
}

void change(int i,int l,int r,int ql,int qr,long long k,long long b)
{
	if (ql>qr) return;
	if (l==ql&&r==qr)
	{
		if (k>0) t[i].val=k*l+b; else t[i].val=k*r+b;
		t[i].laz=1; t[i].lazk=k; t[i].lazb=b; return;
	}
	pushdown(i,l,r); int mid=(l+r)>>1;
	if (qr<=mid) change(t[i].ls,l,mid,ql,qr,k,b); else
	if (ql>mid) change(t[i].rs,mid+1,r,ql,qr,k,b); else
	change(t[i].ls,l,mid,ql,mid,k,b),change(t[i].rs,mid+1,r,mid+1,qr,k,b);
	t[i].val=getmin(t[t[i].ls].val,t[t[i].rs].val);
}

long long query(int i,int l,int r,int ql,int qr)
{
	if (ql>qr) return 0;
	if (ql==l&&qr==r) return t[i].val;
	int mid=(l+r)>>1;
	if (t[i].laz)
	{
		if (t[i].lazk>0) return t[i].lazk*ql+t[i].lazb;
		else return t[i].lazk*qr+t[i].lazb;
	}
	if (qr<=mid)
	{
		if (!t[i].ls) return t[i].lazb;
		return query(t[i].ls,l,mid,ql,qr)+t[i].lazb;
	}
	if (ql>mid)
	{
		if (!t[i].rs) return t[i].lazb;
		return query(t[i].rs,mid+1,r,ql,qr)+t[i].lazb;
	}
	long long ansl,ansr;
	if (t[i].ls) ansl=query(t[i].ls,l,mid,ql,mid); else ansl=0;
	if (t[i].rs) ansr=query(t[i].rs,mid+1,r,mid+1,qr); else ansr=0;
	return getmin(ansl,ansr)+t[i].lazb;
}

int main()
{
	s.clear(); s.insert(mp(0,0)); s.insert(mp(1000000001,0));
	scanf("%d",&n); tot=1;
	while (n--)
	{
		scanf("%d",&ord);
		if (ord==1)
		{
			scanf("%d%I64d",&p,&v);
			it=s.lower_bound(mp(p,-1000000001)); r=(*it).fi; it--;
			if (p==1) nw=0; else nw=query(1,L,R,p-1,p-1);
			change(1,L,R,p,r-1,v,v*(1-p)+nw);
			add(1,L,R,r,R,1ll*(r-p)*(v-(*it).se));
			s.insert(mp(p,v));
		} else
		if (ord==2)
		{
			scanf("%d",&p);
			it=s.lower_bound(mp(p,-1000000001));
			it--; l=(*it).se; it++; it++; r=(*it).fi; it--;
			if (p==1) nw=0; else nw=query(1,L,R,p-1,p-1);
			change(1,L,R,p,r-1,l,1ll*l*(1-p)+nw);
			add(1,L,R,r,R,1ll*(r-p)*(l-(*it).se));
			s.erase(mp(p,(*it).se));
		} else
		{
			scanf("%d%d%I64d",&l,&r,&v); int lll=l;
			if (v==0) {printf("%d\n",l); continue;}
			if (l==r) {puts("-1"); continue;} r--;
			it=s.lower_bound(mp(l,-1000000001)); bool bo=0;
			if ((*it).fi!=l)
			{
				p=l; long long v=0; bo=1;
				it=s.lower_bound(mp(p,-1000000001)); int r=(*it).fi; it--;
				if (p==1) nw=0; else nw=query(1,L,R,p-1,p-1);
				change(1,L,R,p,r-1,v,v*(1-p)+nw);
				add(1,L,R,r,R,1ll*(r-p)*(v-(*it).se));
				s.insert(mp(p,v));
			}
			if (l>1) v=query(1,L,R,l-1,l-1)-v; else v=-v;
			ans=-2;
			while (l<=r)
			{
				mid=(l+r)>>1;
				if (query(1,L,R,lll,mid)<=v) ans=mid,r=mid-1; else l=mid+1;
			}
			if (ans==-2) puts("-1"); else
			{
				nw=query(1,L,R,ans,ans);
				it=s.lower_bound(mp(ans,-1000000001)); if ((*it).fi!=ans) it--;
				printf("%.6lf\n",ans+1.0*(v-nw)/(1.0*(*it).se)+1);
			}
			if (bo)
			{
				p=lll;
				it=s.lower_bound(mp(p,-1000000001));
				it--; l=(*it).se; it++; it++; r=(*it).fi; it--;
				if (p==1) nw=0; else nw=query(1,L,R,p-1,p-1);
				change(1,L,R,p,r-1,l,1ll*l*(1-p)+nw);
				add(1,L,R,r,R,1ll*(r-p)*(l-(*it).se));
				s.erase(mp(p,(*it).se));
			}
		}
	}
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
	int x=0,w=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')w=0,ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
#define ll long long
const int N=1e5+5;

int ls[N],rs[N],tim[N],spd[N],tL[N],tR[N],spdR[N],rd[N],tot,rt;
ll res[N],mn[N];

void up(int x){
	tL[x]=tR[x]=tim[x];spdR[x]=spd[x];mn[x]=res[x]=0;
	if(ls[x]){
		tL[x]=tL[ls[x]];
		mn[x]=min(mn[x],mn[ls[x]]);
		res[x]+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
		mn[x]=min(mn[x],res[x]);
	}
	if(rs[x]){
		tR[x]=tR[rs[x]];spdR[x]=spdR[rs[x]];
		res[x]+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
		mn[x]=min(mn[x],res[x]+mn[rs[x]]);
		res[x]+=res[rs[x]];
		mn[x]=min(mn[x],res[x]);
	}
}
void split(int x,int k,int &a,int &b){
	if(!x){a=b=0;return;}
	if(tim[x]<=k)a=x,split(rs[x],k,rs[a],b),up(a);
	else b=x,split(ls[x],k,a,ls[b]),up(b);
}
int merge(int x,int y){
	if(!x||!y)return x|y;
	if(rd[x]<rd[y])return rs[x]=merge(rs[x],y),up(x),x;
	else return ls[y]=merge(x,ls[y]),up(y),y;
}

double query(int x,int r,ll v){
	if(!x)return -1;
//	printf("v=%lld\n",v);
	if(ls[x]){
		if(v+mn[ls[x]]<=0)return query(ls[x],tim[x],v);
		v+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
//		printf("v=%lld\n",v);
		if(v<=0)return tim[x]-1.0*v/spdR[ls[x]];
	}
	if(rs[x]){
		v+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
//		printf("v=%lld\n",v);
		if(v<=0)return tL[rs[x]]-1.0*v/spd[x];
		if(v+mn[rs[x]]<=0)return query(rs[x],r,v);
		v+=res[rs[x]];
	}
	v+=1ll*spdR[x]*(r-tR[x]);
//	printf("v=%lld\n",v);
	if(v<=0)return r-1.0*v/spdR[x];
	return -1;
}

void dfs(int x){
	if(ls[x])dfs(ls[x]);
//	printf("x=%d tim[x]=%d spd[x]=%d tL[x]=%d tR[x]=%d spdR[x]=%d mn[x]=%lld res[x]=%lld\n",x,tim[x],spd[x],tL[x],tR[x],spdR[x],mn[x],res[x]);
	if(rs[x])dfs(rs[x]);
	up(x);
}

int main(){

	int querycnt=0;

	int q=gi();while(q--){
		int op=gi();
		if(op==1){
			tim[++tot]=gi();spd[tot]=gi();rd[tot]=rand()*rand();
			int x,y;split(rt,tim[tot],x,y);
			up(tot);rt=merge(x,merge(tot,y));
		}else if(op==2){
			int t=gi(),x,y,z;
			split(rt,t,x,z);split(x,t-1,x,y);
			rt=merge(x,z);
		}else{
			int l=gi(),r=gi(),v=gi(),x,y,z;
			if(!v){printf("%d\n",l);continue;}
			split(rt,r,x,z);split(x,l-1,x,y);
//			dfs(y);
//			if(!y||v+min(mn[y],res[y]+1ll*spdR[y]*(r-tR[y]))>0)puts("-1");
//			else
				printf("%.6lf\n",query(y,r,v));
			rt=merge(x,merge(y,z));
//			++querycnt;
//			if(querycnt==101)return 0;
		}
	}
	return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 100100
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
struct Data{int k,t;ll s,mxs;};
Data operator+(Data a,Data b)
{
	Data c;c.k=b.k;
	c.s=a.s+b.s;c.t=a.t+b.t;
	c.mxs=max(a.mxs,b.mxs+a.s);
	return c;
}
struct Node
{
	int ff,ch[2];
	int k,t,len;
	Data a;
	Data Pre(){return (Data){k,len,1ll*k*len,max(1ll*k*len,0ll)};}
}t[MAX];
int rt,tot;
void pushup(int x){t[x].a=t[lson].a+t[x].Pre()+t[rson].a;}
void rotate(int x)
{
	int y=t[x].ff,z=t[y].ff;
	int k=t[y].ch[1]==x;
	if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
	t[y].ch[k]=t[x].ch[k^1];if(t[x].ch[k^1])t[t[x].ch[k^1]].ff=y;
	t[x].ch[k^1]=y;t[y].ff=x;
	pushup(y);pushup(x);
}
void Splay(int x,int goal)
{
	while(t[x].ff!=goal)
	{
		int y=t[x].ff,z=t[y].ff;
		if(z!=goal)
			(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
		rotate(x);
	}
	if(!goal)rt=x;
}
void Insert(int a,int s)
{
	int x=rt,f=0;
	while(233)
	{
		if(t[x].t>a)f=x,x=lson;
		else f=x,x=rson;
		if(!x)break;
	}
	int k=t[f].t<a;x=++tot;
	if(f)t[f].ch[k]=x;t[x].ff=f;
	t[x].t=a;t[x].k=s;
	Splay(x,0);
}
int Find(int a)
{
	int x=rt;
	while(233)
	{
		if(t[x].t==a)return x;
		if(t[x].t<a)x=rson;
		else x=lson;
	}
}
int Next(int a,int p)
{
	int x=rt,u=0;bool fl=false;
	while(233)
	{
		if(t[x].t==a){fl=true;break;}
		int k=t[x].t<a;
		if(p^k)u=x;
		if(!t[x].ch[k])break;
		x=t[x].ch[k];
	}
	if(!fl)return u;
	if(!t[x].ch[p])return u;
	else x=t[x].ch[p];
	while(t[x].ch[p^1])x=t[x].ch[p^1];
	return x;
}
void Adding(int a,int s)
{
	Insert(a,s);
	int nw=Find(a),lt=Next(a,0),nt=Next(a,1);
	Splay(lt,0);t[lt].len=a-t[lt].t;pushup(lt);
	Splay(nw,0);t[nw].len=t[nt].t-a;pushup(nw);
}
void Delete(int a)
{
	int uL=Next(a,0),uR=Next(a,1);
	Splay(uL,0);Splay(uR,uL);
	t[uR].ch[0]=0;
	pushup(uR);
	t[uL].len=t[uR].t-t[uL].t;
	pushup(uL);
}
double Query(int l,int r,ll V)
{
	if(!V)return l;
	int uL=Next(l,0),uR=Next(r,1),QwQ;
	Splay(uL,0);Splay(uR,uL);
	int nw=t[uR].ch[0];QwQ=nw;
	if(t[nw].a.mxs<V)return -1;
	while(t[QwQ].ch[0])QwQ=t[QwQ].ch[0];
	int u=nw;Data now=(Data){0,0,0,0};
	double ret=t[QwQ].t;
	while(233)
	{
		Data pre=now+t[t[u].ch[0]].a+t[u].Pre();
		if(pre.mxs<V)now=pre,u=t[u].ch[1],ret+=pre.t;
		else
		{
			Data qwq=now+t[t[u].ch[0]].a;
			if(qwq.mxs<V)return 1.0*(V-qwq.s)/t[u].k+t[u].t;
			u=t[u].ch[0];
		}
		if(!u)return -1;
	}
}
int main()
{
	Insert(0,0);Insert(2e9+1,0);
	int Q=read();
	while(Q--)
	{
		int opt=read();
		if(opt==1)
		{
			int a=read(),s=read();
			Adding(a,-s);
		}
		else if(opt==2)Delete(read());
		else
		{
			int l=read(),r=read(),V=read();
			double s=Query(l,r,V);
			if(s>r)puts("-1");
			else printf("%.10lf\n",s);
		}
	}
	return 0;
}

#include <bits/stdc++.h>
#define pb push_back
#define x first
#define y second

using namespace std;
typedef long long INT;
typedef pair <int, int> pii;
typedef vector <int> VI;

#define NN 100100
int arr[NN<<1];
struct Query {
	int a, b, c;
	Query(int a=0, int b=0, int c=0) : a(a), b(b), c(c) {}
} q[NN];

#define ls (u<<1)
#define rs (ls|1)
#define mid (L+R>>1)
const int inf=0x3f3f3f3f;

INT sum[NN<<3], mn[NN<<3];
int flag[NN<<3];

void push_up(int u){
	sum[u]=sum[ls]+sum[rs];
	mn[u]=min(mn[ls], sum[ls]+mn[rs]);
}

void build(int u, int L, int R){
	flag[u]=inf;
	if(L+1==R) return ;
	build(ls, L, mid);
	build(rs, mid, R);
}

void update(int u, int L, int R, int x){
	flag[u]=x;
	sum[u]=(INT)x*(arr[R]-arr[L]);
	mn[u]=min(0LL, sum[u]);
}

void push_down(int u, int L, int R){
	if(flag[u]^inf){
		update(ls, L, mid, flag[u]);
		update(rs, mid, R, flag[u]);
		flag[u]=inf;
	}
}

void update(int u, int L, int R, int l, int r, int x){
	if(r<=L || R<=l) return ;
	if(l<=L && R<=r){
		update(u, L, R, x);
		return ;
	}
	push_down(u, L, R);
	update(ls, L, mid, l, r, x);
	update(rs, mid, R, l, r, x);
	push_up(u);
}

double ans;
set <pii> s;
int find(int u, int L, int R, int l, int r, INT &cur){
	if(r<=L || R<=l) return 0;
	if(l<=L && R<=r){
		if(cur+mn[u]>0){
			cur+=sum[u];
			return 0;
		}
		if(L+1==R){
			auto it=s.lower_bound(pii(R, -inf));
			it--;
			ans=arr[L]-(double)cur/(it->y);
			return 1;
		}
		push_down(u, L, R);
		if(cur+mn[ls]<=0) return find(ls, L, mid, l, r, cur);
		cur+=sum[ls];
		return find(rs, mid, R, l, r, cur);
	}
	push_down(u, L, R);
	return find(ls, L, mid, l, r, cur) || find(rs, mid, R, l, r, cur);
}

int main (){
#ifndef ONLINE_JUDGE
	freopen ("in.in", "r", stdin);
	freopen ("out.out", "w", stdout);
#endif

	int m;
	cin >> m;

	int n=0;
	for(int i=0; i<m; i++){
		int tp;
		scanf("%d", &tp);
		if(tp==1){
			q[i].a=-1;
			scanf("%d %d", &q[i].b, &q[i].c);
			arr[n++]=q[i].b;
		}
		else if(tp==2){
			q[i].a=-2;
			scanf("%d", &q[i].b);
			arr[n++]=q[i].b;
		}
		else {
			scanf("%d %d %d", &q[i].a, &q[i].b, &q[i].c);
			arr[n++]=q[i].a;
			arr[n++]=q[i].b;
		}
	}

	arr[n++]=0;
	arr[n++]=inf;

	sort(arr, arr+n);
	n=unique(arr, arr+n)-arr;

	for(int i=0; i<m; i++){
		if(q[i].a>0) q[i].a=lower_bound(arr, arr+n, q[i].a)-arr;
		q[i].b=lower_bound(arr, arr+n, q[i].b)-arr;
	}

	s.insert(pii(0, 0));
	s.insert(pii(--n, 0));

	build(1, 0, n);

	for(int i=0; i<m; i++){
		if(q[i].a==-1){
			auto it=s.lower_bound(pii(q[i].b, -inf));
			update(1, 0, n, q[i].b, it->x, q[i].c);
			s.insert(pii(q[i].b, q[i].c));
		}
		else if(q[i].a==-2){
			auto it=s.lower_bound(pii(q[i].b, -inf));
			auto pre=it; pre--;
			auto nxt=it; nxt++;
			update(1, 0, n, q[i].b, nxt->x, pre->y);
			s.erase(it);
		}
		else {
			INT cur=q[i].c;
			if(cur==0){
				printf("%d\n", arr[q[i].a]);
				continue;
			}
			if(q[i].a==q[i].b){
				puts("-1");
				continue;
			}
			auto it=s.lower_bound(pii(q[i].a, -inf));
			int nxt=it->x;
			it--;
			int pre=it->x, val=it->y;
			update(1, 0, n, pre, nxt, 0);
			if(find(1, 0, n, q[i].a, q[i].b, cur)) printf("%.9lf\n", ans);
			else puts("-1");
			update(1, 0, n, pre, nxt, val);
		}
	}

	return 0;
}

// #pragma GCC optimize("Ofast")

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;

#define X first
#define Y second

//#include <boost/unordered_map.hpp>
//using namespace boost;

/*
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
rbtree T;
*/

namespace io{
    const int L = (1 << 20) + 1;

    char buf[L], *S , *T, c;

    char getchar() {
        if(__builtin_expect(S == T, 0)) {
            T = (S = buf) + fread(buf, 1, L, stdin);
            return (S == T ? EOF : *S++);
        }
        return *S++;
    }

    int inp() {
        int x = 0, f = 1; char ch;
        for(ch = getchar(); !isdigit(ch); ch = getchar())
            if(ch == '-') f = -1;
        for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
        return x * f;
    }

    unsigned inpu()
    {
        unsigned x = 0; char ch;
        for(ch = getchar(); !isdigit(ch); ch = getchar());
        for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
        return x;
    }

    ll inp_ll() {
        ll x = 0; int f = 1; char ch;
        for(ch = getchar(); !isdigit(ch); ch = getchar())
            if(ch == '-') f = -1;
        for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
        return x * f;
    }

    char B[25], *outs=B+20, *outr=B+20;
    template<class T>
    inline void print(register T a,register char x=0){
        if(x) *--outs = x, x = 0;

        if(!a)*--outs = '0';
        else
            while(a)
                *--outs = (a % 10) + 48, a /= 10;

        if(x)
            *--outs = x;

        fwrite(outs, outr - outs , 1, stdout);
        outs = outr;
    }
};

using io :: print;
using io :: inp;
using io :: inpu;
using io :: inp_ll;

using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;

ll power(ll a, ll b, ll p)
{
    if (!b) return 1;
    ll t = power(a, b/2, p);
    t = t*t%p;
    if (b&1) t = t*a%p;
    return t;
}

ll gcd(ll a, ll b)
{
    return b ? gcd(b, a%b) : a;
}

template<class T>
inline void freshmin(T &a, const T &b)
{
    if (a > b) a = b;
}

template<class T>
inline void freshmax(T &a, const T &b)
{
    if (a < b) a = b;
}

const int MAXN = 100010;
const int MOD = 1000000007;
const f80 MI = f80(1)/MOD;
const int INF = 1000000000;

int tot;

struct node
{
    node *Lc, *Rc;
    int flag, set;
    ll sum, Lsum;
}nodes[MAXN*70];

node *new_node()
{
    return &nodes[++ tot];
}

void clear(node *p, int L, int R)
{
    if (p->flag)
    {
        int m = (L+R)/2;
        p->flag = 0;
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        p->Lc->flag = p->Rc->flag = 1;
        p->Lc->set = p->Rc->set = p->set;
        p->Lc->sum = (ll)(m-L+1)*p->set;
        p->Lc->Lsum = p->set >= 0 ? 0 : p->Lc->sum;
        p->Rc->sum = (ll)(R-m)*p->set;
        p->Rc->Lsum = p->set >= 0 ? 0 : p->Rc->sum;
    }
}

void update(node *p)
{
    if (!p->Lc) p->Lc = new_node();
    if (!p->Rc) p->Rc = new_node();
    p->sum = p->Lc->sum+p->Rc->sum;
    p->Lsum = min(p->Lc->Lsum, p->Lc->sum+p->Rc->Lsum);
}

void modify(node *p, int L, int R, int x, int y, int v)
{
    if (L == x && R == y)
    {
        p->flag = 1;
        p->set = v;
        p->sum = (ll)(R-L+1)*v;
        p->Lsum = v >= 0 ? 0 : p->sum;
        return;
    }
    clear(p, L, R);
    int m = (L+R)/2;
    if (y <= m)
    {
        if (!p->Lc) p->Lc = new_node();
        modify(p->Lc, L, m, x, y, v);
    }
    else if (x > m)
    {
        if (!p->Rc) p->Rc = new_node();
        modify(p->Rc, m+1, R, x, y, v);
    }
    else
    {
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        modify(p->Lc, L, m, x, m, v);
        modify(p->Rc, m+1, R, m+1, y, v);
    }
    update(p);
}

pair<ld, ll> query(node *p, int L, int R, int x, int y, ll v)
{
    if (L == x && R == y)
    {
        if (p->Lsum+v > 0)
            return pair<ld, ll>(-1, p->sum);
        if (L == R)
            return pair<ld, ll>(L-(ld)v/p->sum, p->sum);
        if (p->flag)
            return pair<ld, ll>(L-(ld)v/(p->sum/(R-L+1)), p->sum);
        int m = (L+R)/2;
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        auto Lans = query(p->Lc, L, m, x, m, v);
        if (Lans.first > 0)
            return Lans;
        else
        {
            auto Rans = query(p->Rc, m+1, R, m+1, y, Lans.second+v);
            return pair<ld, ll>(Rans.first, Lans.second+Rans.second);
        }
    }
    clear(p, L, R);
    int m = (L+R)/2;
    if (y <= m)
    {
        if (!p->Lc) p->Lc = new_node();
        return query(p->Lc, L, m, x, y, v);
    }
    else if (x > m)
    {
        if (!p->Rc) p->Rc = new_node();
        return query(p->Rc, m+1, R, x, y, v);
    }
    else
    {
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        auto Lans = query(p->Lc, L, m, x, m, v);
        if (Lans.first > 0)
            return Lans;
        else
        {
            auto Rans = query(p->Rc, m+1, R, m+1, y, Lans.second+v);
            return pair<ld, ll>(Rans.first, Lans.second+Rans.second);
        }
    }
}

int main()
{

    int q = inp();
    map<int, int> H;
    int L = 1, R = 1000000010;
    H[L-1] = H[R+1] = 0;
    node *root = new_node();
    while (q --)
    {
        int t = inp();
        if (t == 1)
        {
            int x = inp();
            int y = inp();
            H[x] = y;
            auto it = H.find(x);
            ++ it;
            modify(root, L, R-1, x, min(it->X, R)-1, y);
        }
        else if (t == 2)
        {
            int x = inp();
            auto it = H.find(x);
            auto ity = it;
            ++ ity;
            auto itx = it;
            -- itx;
            modify(root, L, R-1, x, min(ity->X, R)-1, itx->Y);
            H.erase(x);
        }
        else if (t == 3)
        {
            int x = inp();
            int y = inp();
            int v = inp();
            if (v == 0)
                printf("%d\n", x);
            else
            {
                auto it = H.lower_bound(x);
                x = it->X;
                if (x >= y)
                    puts("-1");
                else
                {
                    auto ans = query(root, L, R-1, x, y-1, v);
                    if (ans.first < 0)
                        puts("-1");
                    else
                       printf("%.8f\n", ans.first);
                }
            }
        }
    }

    return 0;
}

#pragma GCC optimize("Ofast")

using namespace std;

#define _CRT_SECURE_NO_WARNINGS
#include <set>
#include <map>
#include <string>
#include <vector>
#include <deque>
#include <algorithm>
#include <iomanip>
#include <list>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <queue>
#include <math.h>
#ifdef _DEBUG
#include <fstream>
ifstream cin("input.txt");
ofstream cout("output.txt");
#else
#include <iostream>
#endif

const int MAGIC_CONST = 1e9 + 20;

class segment_tree
{
private:
	int n;
	int target_l, target_r;
	long long value;
	long long now_count_sum = 0;
	double answer;
	double now_count_answer;
	vector<long long> length;
	vector<long long> sums;
	vector<long long> mins;
	vector<long long> push;
	vector<long long> crane_value;
	vector<bool> push_exists;

	long long get_sum_in_v(int v)
	{
		if (push_exists[v])
			return length[v] * push[v];
		return sums[v];
	}

	long long get_min_sum_in_v(int v)
	{
		if (push_exists[v])
			return min(length[v] * push[v], 0ll);
		return mins[v];
	}

	void do_push(int v, bool is_leaf)
	{
		if (push_exists[v])
		{
			sums[v] = length[v] * push[v];
			mins[v] = min(0ll, sums[v]);
			if (!is_leaf)
			{
				push[v << 1] = push[v];
				push_exists[v << 1] = true;
				push[(v << 1) + 1] = push[v];
				push_exists[(v << 1) + 1] = true;
			}
			else
			{
				crane_value[v] = push[v];
			}
			push[v] = 0;
			push_exists[v] = false;
		}
	}

	void update(int v, bool is_leaf)
	{
		if (!is_leaf)
		{
			int vl = v << 1;
			int vr = vl + 1;
			long long sumsl = get_sum_in_v(vl);
			long long sumsr = get_sum_in_v(vr);
			long long minsl = get_min_sum_in_v(vl);
			long long minsr = get_min_sum_in_v(vr);
			sums[v] = sumsl + sumsr;
			mins[v] = min(0ll, min(minsl, sumsl + minsr));
		}
	}

	void build(vector<long long>& dif, int v, int l, int r)
	{
		if (l == r)
		{
			length[v] = dif[l];
			return;
		}
		int vl = v << 1;
		int vr = (v << 1) + 1;
		int mid = (l + r) / 2;
		build(dif, vl, l, mid);
		build(dif, vr, mid + 1, r);
		length[v] = length[vl] + length[vr];
	}

	void set_on_segment(int v, int l, int r)
	{
		if (l >= target_l && r <= target_r)
		{
			push[v] = value;
			push_exists[v] = true;
			do_push(v, l == r);
			return;
		}
		do_push(v, l == r);

		int vl = v << 1;
		int vr = vl + 1;
		int mid = (l + r) >> 1;

		if (mid >= target_l && l <= target_r)
			set_on_segment(vl, l, mid);
		if (r >= target_l && mid + 1 <= target_r)
			set_on_segment(vr, mid + 1, r);

		update(v, l == r);
	}

	void count_answer(int v, int l, int r)
	{
		if (answer > -0.5)
			return;

		do_push(v, l == r);

		if (l >= target_l && r <= target_r)
		{
			long long min_sum = get_min_sum_in_v(v);

			if (min_sum + now_count_sum > value)
			{
				now_count_answer += length[v];
				now_count_sum += get_sum_in_v(v);
				return;
			}

			begin_down(v, l, r);
			return;
		}

		int vl = v << 1;
		int vr = vl + 1;
		int mid = (l + r) >> 1;

		if (mid >= target_l && l <= target_r)
			count_answer(vl, l, mid);
		if (r >= target_l && mid + 1 <= target_r)
			count_answer(vr, mid + 1, r);
	}

	void begin_down(int v, int l, int r)
	{
		do_push(v, l == r);

		if (l == r)
		{
			if (crane_value[v] == 0)
				return;
			double lt = (value - now_count_sum) / ((double)crane_value[v]);
			answer = now_count_answer + lt;
		}
		else
		{
			int vl = v << 1;
			int vr = vl + 1;
			int mid = (l + r) >> 1;

			auto minsum_l = get_min_sum_in_v(vl);

			if (minsum_l + now_count_sum > value)
			{
				now_count_answer += length[vl];
				now_count_sum += get_sum_in_v(vl);
				begin_down(vr, mid + 1, r);
			}
			else
			{
				begin_down(vl, l, mid);
			}
		}
	}

public:
	segment_tree(vector<long long>& dif)
	{
		n = dif.size();
		length.resize(4 * n);
		sums.resize(4 * n);
		mins.resize(4 * n);
		push_exists.resize(4 * n);
		push.resize(4 * n);
		crane_value.resize(4 * n);
		build(dif, 1, 0, n - 1);
	}

	void set_crane(int l, int r, int val)
	{
		target_l = l;
		target_r = r;
		value = val;
		set_on_segment(1, 0, n - 1);
	}

	double get_answer(int l, int r, int val)
	{
		target_l = l;
		target_r = r;
		value = val;
		answer = -1;
		now_count_sum = 0;
		now_count_answer = 0;
		count_answer(1, 0, n - 1);
		return answer;
	}
};

class query
{
public:
	long long type, t, l, r, v;

	query()
	{
		cin >> type;
		if (type == 1)
			cin >> t >> v;
		if (type == 2)
			cin >> t;
		if (type == 3)
			cin >> l >> r >> v;
	}
};

void solve()
{
	int n;
	cin >> n;
	vector<query>a(n);

	vector<int>coords;

	for (auto q1 : a)
	{
		switch (q1.type)
		{
		case 1:
		case 2:
			coords.push_back(q1.t);
			break;
		case 3:
			coords.push_back(q1.l);
			coords.push_back(q1.r);
			break;
		}
	}

	coords.push_back(MAGIC_CONST);
	coords.push_back(0);

	sort(coords.begin(), coords.end());
	coords = vector<int>(coords.begin(), unique(coords.begin(), coords.end()));
	auto get_num = [&](int x) {
		return lower_bound(coords.begin(), coords.end(), x) - coords.begin();
	};

	vector<long long> difference(coords.size());
	for (int i = 1; i < coords.size(); i++)
		difference[i] = coords[i] - coords[i - 1];

	segment_tree st(difference);

	map<int, int> active_coordinates;
	active_coordinates[MAGIC_CONST] = 0;
	active_coordinates[0] = 0;

	for (auto q1 : a)
	{
		if (q1.type == 1)
		{
			int cur_l = get_num(q1.t) + 1;
			int cur_r = get_num(active_coordinates.upper_bound(q1.t)->first);
			active_coordinates[q1.t] = q1.v;
			st.set_crane(cur_l, cur_r, q1.v);
		}
		if (q1.type == 2)
		{
			int cur_l = get_num(q1.t) + 1;
			int cur_r = get_num(active_coordinates.upper_bound(q1.t)->first);
			auto tmp_iter = active_coordinates.lower_bound(q1.t)--;
			tmp_iter--;
			int val = tmp_iter->second;
			tmp_iter++;
			active_coordinates.erase(tmp_iter);
			st.set_crane(cur_l, cur_r, val);
		}
		if (q1.type == 3)
		{
			if (q1.v == 0)
			{
				cout << q1.l << "\n";
				continue;
			}
			int cur_l = get_num(active_coordinates.lower_bound(q1.l)->first) + 1;
			int cur_r = get_num(q1.r);
			if (cur_l > cur_r)
			{
				cout << -1 << "\n";
				continue;
			}
			auto ans = st.get_answer(cur_l, cur_r, -q1.v);
			if (ans < -0.5)
			{
				cout << -1 << "\n";
			}
			else
			{
				cout << fixed << setprecision(15) << ans + coords[cur_l - 1] << "\n";
			}
		}
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	srand(58164);
	bool f = true;

	solve();
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=1<<30;
map<int,int> mp;
typedef pair<int,int> pp;
struct node {
	int ch[2],pri,mx,mi;
	pp val;
	ll sum,mn;
}t[100005];
int sz=0;
int read() {
	char c=getchar(); int x=0,f=1;
	while (c<'0' || c>'9') {
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
int newnode(int T,int S) {
	++sz;
	t[sz].ch[0]=t[sz].ch[1]=0;
	t[sz].val=make_pair(T,S);
	t[sz].pri=rand();
	t[sz].mx=t[sz].mi=sz;
	t[sz].sum=0;
	return sz;
}
ll calc(int x,int y) {
	return 1LL*t[x].val.second*(t[y].val.first-t[x].val.first);
}
void update(int x) {
	if (t[x].ch[1]) t[x].mx=t[t[x].ch[1]].mx;
	else t[x].mx=x;
	if (t[x].ch[0]) t[x].mi=t[t[x].ch[0]].mi;
	else t[x].mi=x;
	t[x].mn=0;
	t[x].mn=min(t[x].mn,t[t[x].ch[0]].mn);
	t[x].sum=t[t[x].ch[0]].sum;
	if (t[x].ch[0]) t[x].sum+=calc(t[t[x].ch[0]].mx,x);
	t[x].mn=min(t[x].mn,t[x].sum);
	if (t[x].ch[1]) t[x].sum+=calc(x,t[t[x].ch[1]].mi);
	t[x].mn=min(t[x].mn,t[x].sum+t[t[x].ch[1]].mn);
	t[x].sum+=t[t[x].ch[1]].sum;
	t[x].mn=min(t[x].mn,t[x].sum);
}
int merge(int x,int y) {
	if (!x || !y) return x^y;
	if (t[x].pri>t[y].pri) {
		t[x].ch[1]=merge(t[x].ch[1],y);
		update(x);
		return x;
	}
	else {
		t[y].ch[0]=merge(x,t[y].ch[0]);
		update(y);
		return y;
	}
}
void split(int now,pp k,int &x,int &y) {
	if (!now) x=y=0;
	else {
		if (t[now].val<=k) {
			x=now;
			split(t[x].ch[1],k,t[x].ch[1],y);
		}
		else {
			y=now;
			split(t[y].ch[0],k,x,t[y].ch[0]);
		}
		update(now);
	}
}
void insert(int &root,int T,int S) {
	int x,y;
	split(root,make_pair(T,S),x,y);
	root=merge(merge(x,newnode(T,S)),y);
}
void destroy(int &root,int T,int S) {
	int x,y,z;
	split(root,make_pair(T,S),y,z);
	split(y,make_pair(T,S-1),x,y);
	root=merge(x,z);
}
double find(int &root,int l,int r,ll v) {
	if (!v) return l;
	int x,y,z;
	split(root,make_pair(r,inf),y,z);
	split(y,make_pair(l-1,inf),x,y);
	if (!y) {
		root=merge(merge(x,y),z);
		return -1;
	}
	int now=y;
	while (now) {
		ll vv=v;
		if (vv+t[t[now].ch[0]].mn<=0 || vv+t[t[now].ch[0]].sum<=0) now=t[now].ch[0];
		else {
			vv+=t[t[now].ch[0]].sum;
			if (t[now].ch[0]) {
				vv+=calc(t[t[now].ch[0]].mx,now);
				if (vv<=0) break;
			}
			if (t[now].ch[1]) {
				vv+=calc(now,t[t[now].ch[1]].mi);
				if (vv<=0) break;
			}
			v+=t[now].sum-t[t[now].ch[1]].sum;
			now=t[now].ch[1];
		}
	}
	if (!now) {
		root=merge(merge(x,y),z);
		return -1;
	}
	if (t[now].ch[0]) {
		v+=t[t[now].ch[0]].sum;
		int p=t[t[now].ch[0]].mx;
		ll tmp=calc(p,now);
		if (v+tmp<=0) {
			root=merge(merge(x,y),z);
			return t[p].val.first-v*1.0/t[p].val.second;
		}
		v+=tmp;
	}
	root=merge(merge(x,y),z);
	return t[now].val.first-v*1.0/t[now].val.second;
}
int main() {
	srand((unsigned)time(NULL));
	int q=read(),root=0,x,y,z;
	for (int i=1; i<=q; i++) {
		int opt=read();
		if (opt==1) {
			int T=read(),S=read();
			insert(root,T,S);
			mp[T]=S;
		}
		else if (opt==2) {
			int T=read();
			destroy(root,T,mp[T]);
		}
		else {
			int l=read(),r=read(),v=read();
			insert(root,r,inf);
			printf("%.13f\n", find(root,l,r,v));
			destroy(root,r,inf);
		}
	}
	return 0;
}

#include<bits/stdc++.h>
#include<ext/rope>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define mst(a,b) memset(a,b,sizeof(a))
#define ALL(x) x.begin(),x.end()
#define pii pair<int,int>
#define mp make_pair
#define lowbit(x) (x&(-x))
#define X first
#define Y second
using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const long double eps = 1e-8;
const long double pi = acos(-1.0);
const int N = 4e5 + 5;
const int mod = 1e9 + 7;
const int maxn = 1e7 + 5;
vector<int>t;
struct Q{
    int op;
    ll l,r,v;//t s
}q[N];
set<ll>S;
ll tag[N];
ll mi[N];
inline void push_down(int o){
    if(tag[o]){
        tag[o << 1] += tag[o];
        tag[o << 1 | 1] += tag[o];
        if(mi[o << 1] != INF)
        mi[o << 1] += tag[o];
        if(mi[o << 1 | 1] != INF)
        mi[o << 1 | 1] += tag[o];
        tag[o] = 0;
    }
}
inline void push_up(int o){
    mi[o] = min(mi[o << 1],mi[o << 1 | 1]);
}
inline void update(int o,int l,int r,int L,int R,ll v){
    if(L <= l && r <= R){
        if(mi[o] == INF)return;
        tag[o] += v;
        mi[o] += v;
        return;
    }
    push_down(o);
    int mid = (r + l) >> 1;
    if(L <= mid)update(o << 1,l,mid,L,R,v);
    if(R > mid)update(o << 1 | 1,mid + 1,r,L,R,v);
    push_up(o);
}
inline void dd(int o,int l,int r,int pos,ll v){
    if(l == r){
        mi[o] = v;
        return;
    }
    push_down(o);
    int mid = (r + l) >> 1;
    if(pos <= mid)dd(o << 1,l,mid,pos,v);
    else dd(o << 1 | 1,mid + 1,r,pos,v);
    push_up(o);
}

inline ll qfuck(int o,int l,int r,int L,int R){
    if(L <= l && r <= R){
        return mi[o];
    }
    push_down(o);
    int mid = (r + l) >> 1;
    ll ans = INF;
    if(L <= mid)ans = min(ans,qfuck(o << 1,l,mid,L,R));
    if(R > mid)ans = min(ans,qfuck(o << 1 | 1,mid + 1,r,L,R));
    push_up(o);
    return ans;
}
inline int query(int o,int l,int r,int L,int R,ll d){
//    if(qfuck(1,l,r,L,R) > d)return -1;
//    --L;
//    while(L + 1 < R){
//        int mid = (R + L) >> 1;
//        if(qfuck(1,l,r,L,mid) <= d){
//            R = mid;
//        }
//        else L = mid;
//    }
//    return R;
//    assert(d <= INF);
    if(L > r || R < l)return -1;
    if(l == r){
        if(mi[o] <= d){
            return l;
        }
        else return -1;
    }
    if(L <= l && r <= R){
        if(mi[o] > d)return -1;
    }
    push_down(o);
    int mid = (r + l) >> 1;
    int t1 = -1;
    if(R <= mid)t1 = query(o << 1,l,mid,L,R,d);
    if(t1 != -1){
        push_up(o);
        return t1;
    }
    if(L > mid)t1 = query(o << 1 | 1,mid + 1,r,L,R,d);
    if(t1 != -1){
        push_up(o);
        return t1;
    }
    int q1 = query(o << 1,l,mid,L,R,d);
    if(q1 != -1){
        push_up(o);
        return q1;
    }
    q1 = query(o << 1 | 1,mid + 1,r,L,R,d);
    push_up(o);
    return q1;
}
inline ll ask(int o,int l,int r,int pos){
    if(l == r){
        return mi[o];
    }
    push_down(o);
    int mid = (r + l) >> 1;
    ll t1 = 0;
    if(pos <= mid)t1 = ask(o << 1,l,mid,pos);
    else t1 = ask(o << 1 | 1,mid + 1,r,pos);
    push_up(o);
    return t1;
}
gp_hash_table<int,int>G;
inline int id(int x){
    return G[x];
}
ll VVV[N];
int main() {
#ifdef local
    freopen("input", "r", stdin);
//    freopen("out.txt","w",stdout);
#endif
    int fx;
    cin>>fx;
    for(int i = 1; i <= fx; i++){
        scanf("%d",&q[i].op);
        if(q[i].op == 1){
            scanf("%lld%lld",&q[i].l,&q[i].v);
            t.push_back(q[i].l);
        }
        else if(q[i].op == 2){
            scanf("%lld",&q[i].l);
            t.push_back(q[i].l);
        }
        else {
            scanf("%lld%lld%lld",&q[i].l,&q[i].r,&q[i].v);
            t.push_back(q[i].l);
        }
    }
    t.push_back(1e9 + 1);
    S.insert(1e9 + 1);
    sort(t.begin(),t.end());
    t.erase(unique(t.begin(),t.end()),t.end());
    for(int i = 0; i < t.size(); i++)G[t[i]] = i + 1;
    mst(mi,0x3f);
    int tn = t.size();
    for(int i = 1; i <= fx; i++){
        if(q[i].op == 1){
            auto it = S.lower_bound(q[i].l);
            ll pre = 0;
            ll dx = 0;
            ll te = *it;
            VVV[id(q[i].l)] = q[i].v;
            if(it == S.begin()){
                dx = (te - q[i].l) * q[i].v;
                dd(1,1,tn,id(q[i].l),dx);
            }
            else {
                auto ct = it;
                --ct;
                pre = ask(1,1,tn,id(*ct));
                ll newp = (q[i].l - (*ct)) * VVV[id(*ct)];
                if(ct == S.begin()){
                    dd(1,1,tn,id(*ct),newp);
                }
                else {
                    auto ot = ct;
                    --ot;
                    dd(1,1,tn,id(*ct),newp + ask(1,1,tn,id(*ot)));
                }
                dd(1,1,tn,id(q[i].l),(te - q[i].l) * q[i].v + ask(1,1,tn,id(*ct)));
            }
            S.insert(q[i].l);
            update(1,1,tn,id(q[i].l) + 1,tn,ask(1,1,tn,id(q[i].l)) - pre);
        }
        else if(q[i].op == 2){
            auto it = S.lower_bound(q[i].l);
            ll pre = ask(1,1,tn,id(*it));
            dd(1,1,tn,id(*it),INF);
            ll now = 0;
            if(it != S.begin()){
                auto st = it;
                ++st;
                auto pt = it;
                --pt;
                update(1,1,tn,id(*pt),id(*pt),((*st) - (*it)) * VVV[id(*pt)]);
                now = ask(1,1,tn,id(*pt));
            }
            update(1,1,tn,id(q[i].l),tn,now - pre);
            S.erase(q[i].l);
        }
        else {
            auto it = S.lower_bound(q[i].l);
            if(q[i].v <= 0){
                printf("%lld\n",q[i].l);
                continue;
            }
            ll pre = 0;
            if(it != S.begin()){
                auto ft = it;
                --ft;
                pre = ask(1,1,tn,id(*ft));
            }
            ll pos = query(1,1,tn,id(*it),tn,pre - q[i].v);
            if(pos == -1){
                puts("-1");
                continue;
            }
            double ans = 0;
            ll sc = 0;
            auto gggg = S.lower_bound(t[pos - 1]);
            if(gggg != S.begin()){
                --gggg;
                sc = ask(1,1,tn,id(*gggg));
            }
            ll gv = q[i].v;
            gv += sc - pre;
            assert(VVV[pos] != 0);
            ans = (long double)gv / -VVV[pos];
            if(ans + t[pos - 1] <= q[i].r)
                printf("%.10f\n",ans + t[pos - 1]);
            else puts("-1");
        }
    }
}

#include<bits/stdc++.h>
using namespace std;
#define mid (l+r)/2
const long long maxn=1000005;
long long i,i0,n,m;
vector<long long>v;
struct node
{
    long long siz,v,sum,mp;
}tree[maxn*4];
node operator+(node a,node b)
{
    node c;
    c.siz=a.siz+b.siz;
    c.v=(int)1e9+7;
    c.sum=a.sum+b.sum;
    c.mp=min(a.mp,a.sum+b.mp);
    return c;
}
void b_tree(long long l,long long r,long long p)
{
    if(l==r)tree[p]={((l==v.size())?0:(v[l]-v[l-1])),0,0,0};
    else
    {
        b_tree(l,mid,p*2),b_tree(mid+1,r,p*2+1);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
void p_tree(long long p)
{
    if(tree[p].v==(int)1e9+7)return;
    tree[p*2]={tree[p*2].siz,tree[p].v,tree[p*2].siz*tree[p].v,min(0ll,tree[p*2].siz*tree[p].v)};
    tree[p*2+1]={tree[p*2+1].siz,tree[p].v,tree[p*2+1].siz*tree[p].v,min(0ll,tree[p*2+1].siz*tree[p].v)};
    tree[p].v=(int)1e9+7;
}
void c_tree(long long l,long long r,long long p,long long a,long long b,long long v)
{
    if(l==a&&r==b)tree[p]={tree[p].siz,v,tree[p].siz*v,min(0ll,tree[p].siz*v)};
    else
    {
        p_tree(p);
        if(b<=mid) c_tree(l,mid,p*2,a,b,v);
        else if(a>=mid+1)c_tree(mid+1,r,p*2+1,a,b,v);
        else c_tree(l,mid,p*2,a,mid,v),c_tree(mid+1,r,p*2+1,mid+1,b,v);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
long long q_tree(long long l,long long r,long long p,long long a)
{
    if(l==r)return tree[p].v;
    else
    {
        p_tree(p);
        if(a<=mid)return q_tree(l,mid,p*2,a);
        else return q_tree(mid+1,r,p*2+1,a);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
long long gsz;
double q0_tree(long long l,long long r,long long p,long long a,long long b,long long v)
{
    double ans=1e9+7;
    if(l==a&&r==b)
    {
        if(l!=r)p_tree(p);
        if(v+tree[p].mp+gsz<=0)
        {
            if(l!=r)
            {
                ans=q0_tree(l,mid,p*2,l,mid,v);
                if(ans>1e9+6)ans=tree[p*2].siz+q0_tree(mid+1,r,p*2+1,mid+1,r,v);
            }
            else ans=(double)(-v-gsz)/tree[p].v;
        }
        else gsz+=tree[p].sum;
        if(l!=r)tree[p]=tree[p*2]+tree[p*2+1];
    }
    else
    {
        p_tree(p);
        if(b<=mid)ans=q0_tree(l,mid,p*2,a,b,v);
        else if(a>=mid+1)ans=tree[p*2].siz+q0_tree(mid+1,r,p*2+1,a,b,v);
        else
        {
            ans=q0_tree(l,mid,p*2,a,mid,v);
            if(ans>1e9+6)ans=tree[p*2].siz+q0_tree(mid+1,r,p*2+1,mid+1,b,v);
        }
        tree[p]=tree[p*2]+tree[p*2+1];
    }
    return ans;
}
struct op
{
    long long op,t,l,r,v,s;
}a[100005];
void cal(long long &t){t=lower_bound(v.begin(),v.end(),t)-v.begin()+1;}
set<long long>s;
int main()
{
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i].op);
        if(a[i].op==1)scanf("%d %lld",&a[i].t,&a[i].s),v.push_back(a[i].t);
        if(a[i].op==2)scanf("%d",&a[i].t),v.push_back(a[i].t);
        if(a[i].op==3)scanf("%d %d %lld",&a[i].l,&a[i].r,&a[i].v),v.push_back(a[i].l),v.push_back(a[i].r);
    }
    v.push_back(0),v.push_back((long long)1e9+7);
    sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
    long long ll=1,rr=v.size();
    b_tree(ll,rr,1);
    s.insert(ll),s.insert(rr);
    for(i=1;i<=n;i++)
    {
        if(a[i].op==1)
        {
            cal(a[i].t);
            auto it=s.upper_bound(a[i].t);
            c_tree(ll,rr,1,a[i].t,*it-1,a[i].s);
            s.insert(a[i].t);
        }
        if(a[i].op==2)
        {
            cal(a[i].t);
            auto it=s.upper_bound(a[i].t);
            a[i].r=*it,a[i].l=*(----it);
            a[i].s=q_tree(ll,rr,1,a[i].l);
            c_tree(ll,rr,1,a[i].l,a[i].r-1,a[i].s);
            s.erase(a[i].t);
        }
        if(a[i].op==3)
        {
            gsz=0;
            double ans=a[i].l;
            cal(a[i].l),cal(a[i].r);
            a[i].l=*s.lower_bound(a[i].l);
            if(a[i].r-1<a[i].l)
            {
                if(a[i].v)ans=-1;
            }
            else
            {
                if(a[i].v)ans=q0_tree(ll,rr,1,a[i].l,a[i].r-1,a[i].v);
                if(ans>1e9+6)ans=-1;
            }
            printf("%.7f\n",ans);
        }
    }
    return 0;
}

#include <bits/stdc++.h>
#include <type_traits>
using namespace std;

using ll=int64_t;
#define int ll

#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define REP(i,b) FOR(i,0,b)
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(x) x.begin(),x.end()
auto& errStream=cerr;
#ifdef LOCAL
#define cerr (cerr<<"-- line "<<__LINE__<<" -- ")
#else
class CerrDummy{}cerrDummy;
template<class T>
CerrDummy& operator<<(CerrDummy&cd,const T&){
	return cd;
}
using charTDummy=char;
using traitsDummy=char_traits<charTDummy>;
CerrDummy& operator<<(CerrDummy&cd,basic_ostream<charTDummy,traitsDummy>&(basic_ostream<charTDummy,traitsDummy>&)){
	return cd;
}
#define cerr cerrDummy
#endif
#define REACH cerr<<"reached"<<endl
#define DMP(x) cerr<<#x<<":"<<x<<endl
#define ZERO(x) memset(x,0,sizeof(x))
#define ONE(x) memset(x,-1,sizeof(x))

using pi=pair<int,int>;
using vi=vector<int>;
using ld=long double;

template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator <<(ostream& os,const vector<T>& v){
	os<<"{";
	REP(i,(int)v.size()){
		if(i)os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"(";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<")";
}

ll read(){
	ll i;
	scanf("%"  SCNd64,&i);
	return i;
}

void printSpace(){
	printf(" ");
}

void printEoln(){
	printf("\n");
}

void print(ll x,int suc=1){
	printf("%" PRId64,x);
	if(suc==1)
		printEoln();
	if(suc==2)
		printSpace();
}

template<class T>
void print(const vector<T>&v){
	REP(i,v.size())
		print(v[i],i==int(v.size())-1?1:2);
}

string readString(){
	static char buf[3341000];
	scanf("%s",buf);
	return string(buf);
}

char* readCharArray(){
	static char buf[3341000];
	static int bufUsed=0;
	char* ret=buf+bufUsed;
	scanf("%s",ret);
	bufUsed+=strlen(ret)+1;
	return ret;
}

template<class T,class U>
void chmax(T& a,U b){
	if(a<b)
		a=b;
}

template<class T,class U>
void chmin(T& a,U b){
	if(b<a)
		a=b;
}

template<class T>
T Sq(const T& t){
	return t*t;
}

#define CAPITAL
void Yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void No(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

constexpr ll TEN(int n){
	return n==0?1:TEN(n-1)*10;
}

template<class T>
vector<T> Uniqued(const vector<T>&vv){
	auto v(vv);
	sort(ALL(v));
	v.erase(unique(ALL(v)),v.end());
	return v;
}
template<class T>
void MakeUniqued(vector<T>&v){
	sort(ALL(v));
	v.erase(unique(ALL(v)),v.end());
}

const int unused=-inf;

struct Node{
	int mn,sum;
};

Node LazyNode(int lz,int len){
	Node res;
	if(lz>=0)
		res.mn=0;
	else
		res.mn=lz*len;
	res.sum=lz*len;
	return res;
};

Node Merge(const Node&x,const Node&y){
	return Node{min(x.mn,x.sum+y.mn),x.sum+y.sum};
}

struct SegTree{
	int s;
	vi pos,len;
	vi lz;
	vector<Node> ns;
	SegTree(vi pp){
		pos=pp;
		int n=pos.size();
		s=1;
		while(s<n)s*=2;
		pos.resize(s+1,pos.back());
		//cerr<<pos<<endl;

		ns.resize(s*2,Node{0,0});
		lz.resize(s*2,unused);
		len.resize(s*2);
		InitLen(0,s,1);
	}
	void InitLen(int l,int r,int i){
		if(i<s){
			InitLen(l,(l+r)/2,i*2);
			InitLen((l+r)/2,r,i*2+1);
		}
		len[i]=pos[r]-pos[l];
	}
	Node GetNode(int i){
		return lz[i]==unused?ns[i]:LazyNode(lz[i],len[i]);
	}
	void Propagate(int i){
		if(lz[i]==unused)return;
		lz[i*2]=lz[i*2+1]=lz[i];
		ns[i]=LazyNode(lz[i],len[i]);
		lz[i]=unused;
	}
	void Update(int i){
		assert(lz[i]==unused);
		ns[i]=Merge(GetNode(i*2),GetNode(i*2+1));
	}
	void Set(int b,int e,int v,int l,int r,int i){
		if(e<=l||r<=b)return;
		if(b<=l&&r<=e){
			cerr<<i<<" "<<l<<" "<<r<<" "<<v<<endl;
			lz[i]=v;
			return;
		}
		Propagate(i);
		Set(b,e,v,l,(l+r)/2,i*2);
		Set(b,e,v,(l+r)/2,r,i*2+1);
		Update(i);
	}
	void Set(int b,int e,int v){
		cerr<<b<<" "<<e<<" "<<v<<endl;
		Set(b,e,v,0,s,1);
	}
	bool Calc(int b,int e,int&v,double&ans,int l,int r,int i){
		if(e<=l||r<=b)return false;
		if(b<=l&&r<=e){
			Node x=GetNode(i);
			cerr<<i<<" "<<l<<" "<<r<<" "<<x.mn<<" "<<x.sum<<" "<<len[i]<<" "<<lz[i]<<endl;
			if(v+x.mn<=0){
				if(i>=s){
					assert(lz[i]<0);
					ans=pos[l]+double(v)/(-lz[i]);
				}else{
					Propagate(i);
					if(Calc(b,e,v,ans,l,(l+r)/2,i*2))
						return true;
					bool w=Calc(b,e,v,ans,(l+r)/2,r,i*2+1);
					assert(w);
				}
				return true;
			}else{
				v+=x.sum;
				return false;
			}
		}
		Propagate(i);
		if(Calc(b,e,v,ans,l,(l+r)/2,i*2))
			return true;
		if(Calc(b,e,v,ans,(l+r)/2,r,i*2+1))
			return true;
		return false;
	}
	double Calc(int b,int e,int v){
		cerr<<b<<" "<<e<<" "<<v<<endl;
		double ans=-1;
		Calc(b,e,v,ans,0,s,1);
		return ans;
	}
};

struct Query{
	int t,a,b,c;
};

signed main(){
	int n=read();
	vector<Query> qs(n);
	const int Vmin=-1,Vmax=TEN(9)+1;
	vi pos{Vmin,Vmax};
	REP(i,n){
		int t=read();
		qs[i].t=t;
		if(t==1){
			qs[i].a=read();
			qs[i].b=read();
			pos.PB(qs[i].a);
		}else if(t==2){
			qs[i].a=read();
			pos.PB(qs[i].a);
		}else if(t==3){
			qs[i].a=read();
			qs[i].b=read();
			qs[i].c=read();
			//pos.PB(qs[i].a);
			pos.PB(qs[i].b);
		}
	}

	MakeUniqued(pos);
	const auto idx=[&](int x){
		return lower_bound(ALL(pos),x)-pos.begin();
	};
	cerr<<pos<<endl;

	SegTree seg(pos);

	set<pi> waf;
	waf.insert(pi(idx(Vmin),0));
	waf.insert(pi(idx(Vmax),0));
	set<int> evs;

	REP(i,n){
		if(qs[i].t==1){
			int p=idx(qs[i].a),q=qs[i].b;
			auto itr=waf.insert(pi(p,q)).first;
			seg.Set(p,next(itr)->first,q);

			evs.insert(qs[i].a);
		}else if(qs[i].t==2){
			int p=idx(qs[i].a);
			auto itr=waf.lower_bound(pi(p,-inf));
			itr=waf.erase(itr);
			seg.Set(p,itr->first,prev(itr)->second);

			evs.erase(qs[i].a);
		}else{
			cerr<<qs[i].a<<" "<<qs[i].b<<" "<<qs[i].c<<endl;
			double ans=-1;
			if(qs[i].c==0){
				ans=qs[i].a;
			}else{
				auto itr=evs.lower_bound(qs[i].a);
				if(itr!=evs.end()&&*itr<qs[i].b){
					int p=idx(*itr),q=idx(qs[i].b);
					ans=seg.Calc(p,q,qs[i].c);
				}
			}
			if(ans<0){
				print(-1);
			}else{
				printf("%.10f\n",ans);
			}
		}
	}
}

#include <bits/stdc++.h>
using namespace std;
typedef long long INT;
#define INF 0x3f3f3f3f3f3f3f3f

int xju[200005];
map<int,int> liss;
int dy[200005];
int lscnt=0;

typedef struct n0de{
	n0de *l,*r;
	INT wc;
	INT mn,fi;
	n0de(){
		l=r=0;
		mn=fi=0;
		wc=INF;
	}
}*node;

inline node newnode(){
	return new n0de();
}

inline void change(node now,int nl,int nr,int l,int r,INT x){
	if(!now->l){
		now->l=newnode();
	}
	if(!now->r){
		now->r=newnode();
	}
	if(now->wc!=INF){
		int m=(nl+nr)>>1;
		now->l->fi=now->wc*(dy[m+1]-dy[nl]);
		now->l->mn=(now->l->fi>=0?0:now->l->fi);
		now->l->wc=now->wc;
		now->r->fi=now->wc*(dy[nr+1]-dy[m+1]);
		now->r->mn=(now->l->fi>=0?0:now->r->fi);
		now->r->wc=now->wc;
		now->wc=INF;
	}
	if(nl>=l&&nr<=r){
		now->wc=x;
		now->fi=now->wc*(dy[nr+1]-dy[nl]);
		now->mn=(now->fi>=0?0:now->fi);
		return;
	}
	if(nr<l||nl>r){
		return;
	}
	int m=(nl+nr)>>1;
	change(now->l,nl,m,l,r,x);
	change(now->r,m+1,nr,l,r,x);
	now->fi=now->l->fi+now->r->fi;
	now->mn=min(now->l->mn,now->l->fi+now->r->mn);
}

inline pair<INT,INT> chmin(node now,int nl,int nr,int l,int r){
	if(l>r){
		return make_pair(0,0);
	}
	if(!now->l){
		now->l=newnode();
	}
	if(!now->r){
		now->r=newnode();
	}
	if(now->wc!=INF){
		int m=(nl+nr)>>1;
		now->l->fi=now->wc*(dy[m+1]-dy[nl]);
		now->l->mn=(now->l->fi>=0?0:now->l->fi);
		now->l->wc=now->wc;
		now->r->fi=now->wc*(dy[nr+1]-dy[m+1]);
		now->r->mn=(now->l->fi>=0?0:now->r->fi);
		now->r->wc=now->wc;
		now->wc=INF;
	}
	if(nl>=l&&nr<=r){
		return make_pair(now->mn,now->fi);
	}
	if(nr<l||nl>r){
		return make_pair(0,0);
	}
	int m=(nl+nr)>>1;
	pair<INT,INT> x=chmin(now->l,nl,m,l,r);
	pair<INT,INT> y=chmin(now->r,m+1,nr,l,r);
	return make_pair(min(x.first,x.second+y.first),x.second+y.second);
}

node root;

inline pair<INT,INT> Chmin(int l,int r){
	if(l>r){
		return make_pair(0,0);
	}
	int L=liss[l];
	map<int,int>::iterator rr=liss.upper_bound(r);
	rr--;
	int R=rr->second,rrr=rr->first;
	pair<INT,INT> x=chmin(root,0,lscnt-1,L,R-1);
	pair<INT,INT> y=chmin(root,0,lscnt-1,R,R);
	return make_pair(min(x.first,x.second+y.first/xju[R]*(r-rrr)),x.second+y.second/xju[R]*(r-rrr));
}

int q;
set<pair<int,INT> > evs;
#define spit set<pair<int,INT> >::iterator
int mmm[100005],lll[100005],rrr[100005],sss[100005];

int main(){
	root=newnode();
	evs.insert(make_pair(1000000000,0));
	evs.insert(make_pair(0,0));
	scanf("%d",&q);
	liss[0];
	liss[1000000000];
	for(int i=0;i<q;i++){
		scanf("%d",&mmm[i]);
		if(mmm[i]==1){
			scanf("%d%d",&lll[i],&sss[i]);
			liss[lll[i]];
		}else if(mmm[i]==2){
			scanf("%d",&lll[i]);
		}else{
			scanf("%d%d%d",&lll[i],&rrr[i],&sss[i]);
		}
	}
	for(map<int,int>::iterator it=liss.begin();it!=liss.end();it++){
		it->second=lscnt;
		dy[lscnt]=it->first;
		if(lscnt){
			xju[lscnt-1]=dy[lscnt]-dy[lscnt-1];
		}
		lscnt++;
	}
	xju[lscnt-1]=1;
	for(int I=0;I<q;I++){
		int mode=mmm[I];
		if(mode==1){
			int t=lll[I],s=sss[I];
			spit xx=evs.upper_bound(make_pair(t,s));
			pair<INT,INT> x=*xx;
			change(root,0,lscnt-1,liss[t],liss[x.first]-1,s);
			evs.insert(make_pair(t,s));
		}else if(mode==2){
			int t=lll[I];
			spit xx=evs.upper_bound(make_pair(t,INF));
			spit yy=xx;yy--;
			spit zz=yy;zz--;
			pair<INT,INT> x=*xx,z=*zz;
			change(root,0,lscnt-1,liss[t],liss[x.first]-1,z.second);
			evs.erase(yy);
		}else{
			int l=lll[I],r=rrr[I],v=sss[I];
			if(v==0){
				printf("%d\n",l);
				continue;
			}
			spit xxx=evs.lower_bound(make_pair(l,-INF));
			int frm=(*xxx).first;
			pair<INT,INT> fff;
			fff=Chmin(frm,r);
			INT rval=fff.first;
			if(rval+v>0){
				puts("-1");
				continue;
			}
			int L=frm,R=r;
			INT lval=0;
			while(R-L>1){
				INT m=(L+R)>>1;
				pair<INT,INT> fff=Chmin(frm,m);
				INT mnx=fff.first;
				if(mnx+v>0){
					L=m;
					lval=fff.second;
				}else{
					R=m;
					rval=fff.second;
				}
			}
			double vv;
			if(rval-lval==0){
				vv=L;
			}else{
				vv=1.00*(-v-lval)/(rval-lval)+L;
			}
			printf("%.10lf\n",vv);
		}
	}
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 200010;
const int K = sqrt(N) + 1;
const int INF = (int)1e9 + 10;
const long long INF_LL = (long long)2e18;

int q, k;
vector<int> a[N];
vector<int> moment;
int val[N];

struct Bucket {
    int cnt, firstApp, lastS;
    long long minVal, delta;

    Bucket(int cnt = 0, int firstApp = -1, int lastS = -INF, long long minVal = 0, long long delta = 0) :
        cnt(cnt), firstApp(firstApp), lastS(lastS), minVal(minVal), delta(delta) {}

    void reset() {
        cnt = 0;
        firstApp = -1;
        lastS = -INF;
        minVal = 0;
        delta = 0;
    }

    void debug() {
        cerr << cnt << ' ' << firstApp << ' ' << lastS << ' ' << minVal << ' ' << delta << endl;
    }
} b[N / K + 10];

void init() {
    sort(moment.begin(), moment.end());
    moment.resize(unique(moment.begin(), moment.end()) - moment.begin());
    for (int i = 0; i < moment.size(); i++) val[i] = INF;
}

void updateBucket(int pos) {
    int u = pos / k;
    b[u].reset();
    int curS = 0;
    for (int i = k * u; i < min(k * (u + 1), (int)moment.size() - 1); i++) {
        if (val[i] == INF) {
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        } else {
            b[u].cnt++;
            if (b[u].firstApp == -1) b[u].firstApp = i;
            curS = val[i];
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        }
        b[u].minVal = min(b[u].minVal, b[u].delta);
    }
    b[u].lastS = curS;
}

bool go(long long &v, int &curS, int l, int r, double &res) {
    for (int i = l; i < r; i++) {
        if (val[i] != INF) curS = val[i];
        if (v + 1ll * curS * (moment[i + 1] - moment[i]) <= 0ll) {
            res = -(double)v / curS + moment[i];
            return 1;
        }
        v += 1ll * curS * (moment[i + 1] - moment[i]);
    }
    return 0;
}

double getRes(int l, int r, long long v) {
    l = lower_bound(moment.begin(), moment.end(), l) - moment.begin();
    r = lower_bound(moment.begin(), moment.end(), r) - moment.begin();
    if (v == 0) return moment[l];
    if (moment.size() == 1) {
        return -1;
    }
    r--;
    int ll = l / k;
    int rr = r / k;
    if (ll == rr) {
        int curS = 0;
        double res = -1;
        if (go(v, curS, l, r + 1, res)) return res;
        else return -1;
    }
    int curS = 0;
    double res = -1;
    if (go(v, curS, l, min(k * (ll + 1), (int)moment.size() - 1), res)) return res;
    for (int i = ll + 1; i < rr; i++) {
        if (b[i].cnt == 0) {
            int fullTime = moment[k * (i + 1)] - moment[k * i];
            if (v + 1ll * curS * fullTime <= 0) return -(double)v / curS + moment[k * i];
            v += 1ll * curS * fullTime;
            continue;
        }
        int foo = moment[b[i].firstApp] - moment[i * k];
        if (v + 1ll * curS * foo <= 0ll) {
            return -(double)v / curS + moment[i * k];
        }
        v += 1ll * curS * foo;
        if (v + b[i].minVal <= 0) {
            if (go(v, curS, b[i].firstApp, min(k * (i + 1), (int)moment.size() - 1), res)) return res;
        } else {
            v += b[i].delta;
            curS = b[i].lastS;
        }
    }
    if (go(v, curS, k * rr, r + 1, res)) return res;
    return -1;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        int op;
        cin >> op;
        a[i].push_back(op);
        if (op == 1) {
            int t, s;
            cin >> t >> s;
            moment.push_back(t);
            a[i].push_back(t);
            a[i].push_back(s);
        } else if (op == 2) {
            int t;
            cin >> t;
            moment.push_back(t);
            a[i].push_back(t);
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            moment.push_back(l);
            moment.push_back(r);
            a[i].push_back(l);
            a[i].push_back(r);
            a[i].push_back(v);
        }
    }
    init();
    k = sqrt(moment.size()) + 1;

    for (int i = 1; i <= q; i++) {
        if (a[i][0] == 1) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = a[i][2];
            updateBucket(pos);
        } else if (a[i][0] == 2) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = INF;
            updateBucket(pos);
        } else {
            double ans = getRes(a[i][1], a[i][2], a[i][3]);
            if (ans < 0) cout << -1 << '\n';
            else cout << fixed << setprecision(10) << ans << '\n';
        }
        // cerr << "q " << i << ' ' << endl;
        // for (int i = 0; i < (int)moment.size() / k; i++) {
        //     cerr << "number " <<  i << ' ' ;
        //     b[i].debug();
        // }
    }
    return 0;
}

#include <bits/stdc++.h>
#define watch(x) std::cout << "$ LINE @" << __LINE__ << " FUNC @" << __FUNCTION__ << "\n$ " \
                           << (#x) << ": " << x << std::endl

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

template <typename Tp>
inline void read(Tp &x)
{
    static char c;
    static bool neg;
    x = 0, c = getchar(), neg = false;
    for (; !isdigit(c); c = getchar())
    {
        if (c == '-')
        {
            neg = true;
        }
    }
    for (; isdigit(c); c = getchar())
    {
        x = x * 10 + c - '0';
    }
    if (neg)
    {
        x = -x;
    }
}

typedef pair<double, ll> pdl;

const int INF = 1e9 + 5;
const int N = 1e5 + 5;

int q;

namespace Seg
{
#define lson son[0]
#define rson son[1]

    struct Node
    {
        Node *son[2];
        bool flag;
        int set;
        ll sum, lsum;
        inline void pushUp();
        inline void pushDown(int, int);
        inline void ensureLeft();
        inline void ensureRight();
        inline void ensureBoth();
    };

    inline Node *newNode()
    {
        Node *res = new Node();
        res->son[0] = res->son[1] = nullptr;
        res->flag = false;
        res->set = 0;
        res->sum = res->lsum = 0LL;
        return res;
    }
    inline void Node::pushUp()
    {
        ensureBoth();
        sum = lson->sum + rson->sum;
        lsum = std::min(lson->lsum, lson->sum + rson->lsum);
    }
    inline void Node::pushDown(int l, int r)
    {
        if (flag)
        {
            int mid = (l + r) >> 1;
            ensureBoth();
            lson->flag = rson->flag = true;
            lson->set = rson->set = set;
            lson->sum = (ll)(mid - l + 1) * set;
            lson->lsum = set >= 0 ? 0 : lson->sum;
            rson->sum = (ll)(r - mid) * set;
            rson->lsum = set >= 0 ? 0 : rson->sum;
            flag = false;
        }
    }
    inline void Node::ensureLeft()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
    }
    inline void Node::ensureRight()
    {
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    inline void Node::ensureBoth()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    void update(Node *u, int l, int r, int ul, int ur, int x)
    {
        if (ul <= l && r <= ur)
        {
            u->flag = true;
            u->set = x;
            u->sum = (ll)(r - l + 1) * x;
            u->lsum = x >= 0 ? 0 : u->sum;
            return;
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        if (ul <= mid)
        {
            u->ensureLeft();
            update(u->lson, l, mid, ul, ur, x);
        }
        if (mid < ur)
        {
            u->ensureRight();
            update(u->rson, mid + 1, r, ul, ur, x);
        }
        u->pushUp();
    }
    pdl query(Node *u, int l, int r, int ql, int qr, ll x)
    {
        if (ql <= l && r <= qr)
        {
            if (u->lsum + x > 0)
            {
                return (pdl){-1.0, u->sum};
            }
            if (l == r)
            {
                return (pdl){(double)l - (double)x / (double)u->sum, u->sum};
            }
            if (u->flag)
            {
                return (pdl){(double)l - (double)x / (double)(u->sum / (ll)(r - l + 1)), u->sum};
            }
            int mid = (l + r) >> 1;
            u->ensureBoth();
            pdl res = query(u->lson, l, mid, ql, qr, x);
            if (res.first > 0)
            {
                return res;
            }
            else
            {
                pdl pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
                return (pdl){pir.first, res.second + pir.second};
            }
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        pdl res = (pdl){-1.0, 0}, pir;
        if (ql <= mid)
        {
            u->ensureLeft();
            res = query(u->lson, l, mid, ql, qr, x);
        }
        if (mid < qr)
        {
            if (res.first > 0)
            {
                return res;
            }
            u->ensureRight();
            pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
            res = (pdl){pir.first, res.second + pir.second};
        }
        return res;
    }

#undef lson
#undef rson
} // namespace Seg

int main()
{
    read(q);
    map<int, int> timeline;
    int L = 1, R = INF;
    timeline[L - 1] = timeline[R + 1] = 0;
    auto root = Seg::newNode();
    for (int i = 0, op, x, y, z; i < q; ++i)
    {
        read(op);
        if (op == 1)
        {
            read(x), read(y);
            timeline[x] = y;
            Seg::update(root, L, R - 1, x, std::min(next(timeline.find(x))->first, R) - 1, y);
        }
        else if (op == 2)
        {
            read(x);
            auto iter = timeline.find(x);
            Seg::update(root, L, R - 1, x, std::min(next(iter)->first, R) - 1, prev(iter)->second);
            timeline.erase(iter);
        }
        else
        {
            read(x), read(y), read(z);
            if (z == 0)
            {
                printf("%d\n", x);
            }
            else
            {
                x = timeline.lower_bound(x)->first;
                if (x >= y)
                {
                    puts("-1");
                }
                else
                {
                    auto ans = Seg::query(root, L, R - 1, x, y - 1, z);
                    if (ans.first < 0)
                    {
                        puts("-1");
                    }
                    else
                    {
                        printf("%.8f\n", ans.first);
                    }
                }
            }
        }
    }
}

#include <bits/stdc++.h>
using std::cerr;using std::cin;using std::cout;using std::abs;using std::min;using std::max;using std::swap;using std::map;using std::unordered_map;using std::unordered_set;using std::bitset;using std::pair;using std::set;using std::string;using std::vector;using std::sort;using ll=long long;using uint=unsigned int;using pii=pair<int,int>;using pll=pair<ll,ll>;using ull = unsigned long long;using ld=long double;using vci=vector<int>;using vcl=vector<ll>;template<typename T>void _dbg(const char*_s,T _h){cerr<<_s<<" = "<<_h<<"\n";}template<typename T,typename...Ts>void _dbg(const char*_s,T _h,Ts..._t){int _b=0;while(((_b+=*_s=='(')-=*_s==')')!=0||*_s!=',')cerr<<*_s++;cerr<<" = "<<_h<<",";_dbg(_s+1,_t...);}
#define f first
#define s second
#define pb emplace_back
#define sz(a) ((int)a.size())
#define forn(i,n) for(int i=0;i<(n);++i)
struct init{init(){cin.tie(0);std::iostream::sync_with_stdio(0);cout<<std::fixed<<std::setprecision(10);cerr<<std::fixed<<std::setprecision(5);}~init(){
#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__,__VA_ARGS__)
cerr<<"Time elapsed: "<<(double)clock()/CLOCKS_PER_SEC<<"s.\n";
#else
#define dbg(...)
#endif
}}init;template<typename T,typename U>void upx(T&x,U y){if(x<y)x=y;}template<typename T,typename U>void upn(T&x,U y){if(x>y)x=y;}
#define int ll
const int N=1e5+444,K=200,OO=1e9;
int xs[N];
struct query{
    int type,a,b,c;
}qs[N];
struct block{
    int x[K+1]={0},a[K+1]={0},u[K+1]={0};
    int mn=0,delta=0,lasts=0,ub=0,ftx;
    void recalc(){
        mn=ub=0,ftx=x[K];
        int s=0,val=0,pos=x[0];
        forn(i,K+1){
            val+=(x[i]-pos)*s;
            pos=x[i];
            if(u[i]){
                upn(ftx,x[i]);
                lasts=s=a[i];
                ub=1;
            }
            upn(mn,val);
            if(pos>OO)break;
        }
        delta=val;
    }
    int getmn(int starts){
        return min(starts*(ftx-x[0]),starts*(ftx-x[0])+mn);
    }
    int getdelta(int starts){
        return starts*(ftx-x[0])+delta;
    }
    void upd(int i,int v){
        u[i]=1;
        a[i]=v;
        recalc();
    }
    void rem(int i){
        u[i]=0;
        recalc();
    }
    bool go(int i,int val,double&ans,int&ls,int starts){
        int s=starts;
        int pos=x[i];
        for(int j=i;j<=K;++j){
            dbg(j,val,pos,x[j]);
            if(val+(x[j]-pos)*s<=0){
                ans=-((double)val)/s+pos;
                return 1;
            }
            val+=(x[j]-pos)*s;
            if(u[j])s=a[j];
            pos=x[j];
            if(pos>OO)break;
        }
        ans=val;
        ls=s;
        return 0;
    }
}bs[N/K+5];
int b;
int32_t main() {
    int n;
    cin>>n;
    int m=0;
    forn(i,n){
        cin>>qs[i].type;
        if(qs[i].type==1){
            cin>>qs[i].a>>qs[i].b;
            xs[m++]=qs[i].a;
        }
        if(qs[i].type==2)cin>>qs[i].a;
        if(qs[i].type==3){
            cin>>qs[i].a>>qs[i].b>>qs[i].c;
            xs[m++]=qs[i].a;
        }
    }
    xs[m++]=1e9+1;
    sort(xs,xs+m);
    m=std::unique(xs,xs+m)-xs;
    b=(m+K-1)/K;
    forn(i,b){
        for(int j=i*K;j<=(i+1)*K;++j)bs[i].x[j-i*K]=xs[j];
        bs[i].recalc();
    }
    for(int i=K;i>=0;--i){
        if(bs[b-1].x[i]>OO)break;
        bs[b-1].x[i]=OO;
    }
    bs[b-1].recalc();
    forn(i,n){
        if(qs[i].type==1){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            bs[x/K].upd(x%K,qs[i].b);
        }
        if(qs[i].type==2){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            bs[x/K].rem(x%K);
        }
        if(qs[i].type==3){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            int val=qs[i].c;
            if(val==0){
                cout<<qs[i].a<<'\n';
                continue;
            }
            double ans;
            int f=0,s;
            if(!bs[x/K].go(x%K,val,ans,s,0)){
                val=(ll)(ans+0.5);
                dbg(ans,val);
                for(int j=x/K+1;j<b;++j){
                    dbg(j,bs[j].x[0],val,s);
                    if(val+bs[j].getmn(s)<=0){
                        dbg(bs[j].getmn(s));
                        bs[j].go(0,val,ans,s,s);
                        f=1;
                        break;
                    }
                    val+=bs[j].getdelta(s);
                    if(bs[j].ub)s=bs[j].lasts;
                }
            }else f=1;
            if(f&&ans<=(double)qs[i].b+1e-9){
                cout<<ans<<'\n';
            }else{
                cout<<"-1\n";
            }
        }
    }

    return 0;
}

#include <bits/stdc++.h>

using namespace std;

struct STree {
    vector<int64_t> sum;
    vector<int64_t> mn;
    vector<int> cnt;
    int sz;

    void build(int n) {
        sz = 1;
        while (sz < n) {
            sz *= 2;
        }
        sum.assign(sz * 2, 0);
        mn.assign(sz * 2, 0);
        cnt.assign(sz * 2, 0);
    }

    int xl, xr;

    int64_t x;

    int64_t _getSum(int v, int l, int r) {
        if (xl <= l && r <= xr) {
            return sum[v];
        } else if (r < xl || xr < l) {
            return 0;
        } else {
            int m = (l + r) / 2;
            return _getSum(v * 2, l, m) + _getSum(v * 2 + 1, m + 1, r);
        }
    }

    int64_t getSum(int l, int r) {
        xl = l;
        xr = r;
        return _getSum(1, 0, sz - 1);
    }

    void _setX(int v, int l, int r) {
        if (l == r) {
            sum[v] = x;
            mn[v] = x;
            cnt[v] += xr;;
        } else {
            int m = (l + r) / 2;
            if (xl <= m) {
                _setX(v * 2, l, m);
            } else {
                _setX(v * 2 + 1, m + 1, r);
            }
            sum[v] = sum[v * 2] + sum[v * 2 + 1];
            mn[v] = min(mn[v * 2], mn[v * 2 + 1] + sum[v * 2]);
            cnt[v] += xr;
        }
    }

    void setX(int pos, int64_t val, int zp) {
        xl = pos;
        xr = zp;
        x = val;
        _setX(1, 0, sz - 1);
    }

    int _getPos(int v, int l, int r) {
        // cerr << "pos " << v << ' ' << l << ' ' << r << ' ' << x << ' ' << mn[v] << endl;
        if (r < xl || mn[v] > x) {
            return -1;
        } else if (l == r) {
            return l;
        } else {
            int m = (l + r) / 2;
            int res = _getPos(v * 2, l, m);
            if (res == -1) {
                x -= sum[v * 2];
                res = _getPos(v * 2 + 1, m + 1, r);
                x += sum[v * 2];
            }
            return res;
        }
    }

    int getPos(int l, int64_t val) {
        xl = l;
        x = val;
        return _getPos(1, 0, sz - 1);
    }

    int _getMaxZp(int v, int l, int r) {
        if (cnt[v] == 0 || xr < l) {
            return -1;
        } else if (l == r) {
            return l;
        } else {
            int m = (l + r) / 2;
            int res = _getMaxZp(v * 2 + 1, m + 1, r);
            if (res == -1) {
                res = _getMaxZp(v * 2, l, m);
            }
            return res;
        }
    }

    int getMaxZp(int r) {
        xr = r;
        return _getMaxZp(1, 0, sz - 1);
    }

    int _getMinZp(int v, int l, int r) {
        if (cnt[v] == 0 || r < xl) {
            return -1;
        } else if (l == r) {
            return l;
        } else {
            int m = (l + r) / 2;
            int res = _getMinZp(v * 2, l, m);
            if (res == -1) {
                res = _getMinZp(v * 2 + 1, m + 1, r);
            }
            return res;
        }
    }

    int getMinZp(int l) {
        xl = l;
        return _getMinZp(1, 0, sz - 1);
    }

    void debug(int v, int l, int r) {
        cout << v << ' ' << l << ' ' << r << " | " << mn[v] << ' ' << sum[v] << ' ' << cnt[v] << endl;
        if (l != r) {
            int m = (l + r) / 2;
            debug(v * 2, l, m);
            debug(v * 2 + 1, m + 1, r);
        }
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    vector<int> qe(q);
    vector<pair<int, int>> add;
    vector<int> rm;
    vector<pair<pair<int, int>, int>> md;
    set<int> times;
    for (int i = 0; i < q; ++i) {
        cin >> qe[i];
        if (qe[i] == 1) {
            int t, s;
            cin >> t >> s;
            times.insert(t);
            add.push_back({t, s});
        } else if (qe[i] == 2) {
            int t;
            cin >> t;
            rm.push_back(t);
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            times.insert(l);
            times.insert(r);
            md.push_back({{l, r}, v});
        }
    }
    int cur = 0;
    vector<int> uncom;
    map<int, int> compress;
    for (int v : times) {
        compress[v] = cur;
        ++cur;
        uncom.push_back(v);
    }
    STree s;
    s.build(cur);
    vector<int> states(cur, 2e+9);
    int p1 = 0, p2 = 0, p3 = 0;
    cout << fixed << setprecision(10);
    double dans = 0;
    for (int i = 0; i < q; ++i) {
        if (qe[i] == 1) {
            int ct = compress[add[p1].first];
            states[ct] = add[p1].second;
            int nx = s.getMinZp(ct);
            int pr = s.getMaxZp(ct);
            int64_t x = 2e+9 * 1ll * add[p1].second;
            if (nx != -1) {
                x = add[p1].second * 1ll * (uncom[nx] - add[p1].first);
            }
            s.setX(ct, x, 1);
            if (pr != -1) {
                x = states[pr] * 1ll * (add[p1].first - uncom[pr]);
                s.setX(pr, x, 0);
            }
            // s.debug(1, 0, s.sz - 1);
            ++p1;
        } else if (qe[i] == 2) {
            int ct = compress[rm[p2]];
            states[ct] = 2e+9;
            s.setX(ct, 0, -1);
            int nx = s.getMinZp(ct);
            int pr = s.getMaxZp(ct);
            if (pr != -1) {
                int64_t x = (long long)(2e+9) * 1ll * states[pr];
                if (nx != -1) {
                    x = states[pr] * 1ll * (uncom[nx] - uncom[pr]);
                }
                s.setX(pr, x, 0);
            }
            ++p2;
        } else {
            int l, r;
            int64_t v;
            l = md[p3].first.first;
            r = md[p3].first.second;
            v = md[p3].second;
            double ans;
            if (v == 0) {
                ans = l;
                // if (abs(dans - 10985.7257438551) < 1e-7) {
                //     cout << "!!" << endl;
                // }
            } else {
                int ps = s.getPos(compress[l], -v + s.getSum(0, compress[l] - 1));
                if (ps == -1) {
                    // ps = s.getMaxZp(compress[r] - 1);
                    // if (ps < compress[l]) {
                    //     ps = -1;
                    // }
                }
                if (ps == -1 || ps >= compress[r]) {
                    ans = -1;
                    // if (abs(dans - 10985.7257438551) < 1e-7) {
                    //     cout << "!1!" << endl;
                    // }
                } else {
                    int64_t sm = s.getSum(compress[l], ps - 1);
                    v += sm;
                    ans = uncom[ps];
                    if (states[ps] >= 0 || states[ps] * 1ll * (r - uncom[ps]) + v > 0) {
                        // if (abs(dans - 10985.7257438551) < 1e-7) {
                        //     cout << "!2!" << ans -  v * 1.0 / states[ps]<< endl;
                        // }
                        ans = -1;
                    } else {
                        ans -= v * 1.0 / states[ps];
                    }
                }
            }
            cout << ans << '\n';
            dans = ans;
            ++p3;
        }
    }
    return 0;
}

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

mt19937 rng(347189);

struct treap {
    treap *lc, *rc, *prv, *nxt, *st, *ed;
    long long sum, pref, half;
    int v, t, pri;
    treap(int t, int v): lc(nullptr), rc(nullptr), prv(nullptr), nxt(nullptr), st(this), ed(this),
                         pri(rng()), v(v), sum(0), t(t), pref(0), half(0) {}
    void pull() {
        pref = sum = half = 0;
        prv = nxt = nullptr;
        st = ed = this;
        if (lc) {
            lc->ed->nxt = this;
            prv = lc->ed;
            st = lc->st;
            pref = max(pref, lc->pref);
            assert(prv);
            half = sum = lc->sum + (t - prv->t) * 1ll * prv->v;
            pref = max(pref, sum);
        }
        if (rc) {
            rc->st->prv = this;
            nxt = rc->st;
            ed = rc->ed;
            pref = max(pref, sum + (nxt->t - t) * 1ll * v + rc->pref);
            assert(nxt);
            sum += rc->sum + (nxt->t - t) * 1ll * v;
            pref = max(pref, sum);
        }
    }
};

treap *merge(treap *a, treap *b) {
    if (!a || !b) return a ? a : b;
    if (a->pri > b->pri) return a->rc = merge(a->rc, b), a->pull(), a;
    else return b->lc = merge(a, b->lc), b->pull(), b;
}

void split(treap *t, int k, treap *&a, treap *&b) {
    if (!t) return a = b = nullptr, void();
    if (t->t <= k) a = t, split(t->rc, k, a->rc, b), a->pull();
    else b = t, split(t->lc, k, a, b->lc), b->pull();
}

void insert(treap *&tr, int t, int s) {
    treap *a, *b;
    split(tr, t - 1, a, b);
    tr = merge(merge(a, new treap(t, s)), b);
}

void erase(treap *&tr, int t) {
    treap *a, *b, *c, *d;
    split(tr, t - 1, a, b);
    split(b, t, c, d);
    delete c;
    tr = merge(a, d);
}

int dfs(treap *t, long long v) {
    if (t->lc && t->lc->pref >= v) return dfs(t->lc, v);
    if (t->half >= v) return t->t;
    if (t->rc && t->rc->pref + t->half + (t->nxt->t - t->t) * 1ll * t->v >= v) return dfs(t->rc, v - (t->half + (t->nxt->t - t->t) * 1ll * t->v));
    return -1;
}

treap *right(treap *tr) {
    treap *res = tr;
    while (res->rc) res = res->rc;
    return res;
}

treap *find(treap *tr, int t) {
    if (tr->t == t) return tr;
    if (tr->t > t) return find(tr->lc, t);
    else return find(tr->rc, t);
}

int main() {
    int q; scanf("%d", &q);
    treap *bst = nullptr;
    set<int> f;
    for (int i = 0; i < q; ++i) {
        int z; scanf("%d", &z);
        if (z == 1) {
            int t, s; scanf("%d%d", &t, &s);
            insert(bst, t, -s);
            f.insert(t);
        }
        if (z == 2) {
            int t; scanf("%d", &t);
            erase(bst, t);
            f.erase(t);
        }
        if (z == 3) {
            int l, r, v; scanf("%d%d%d", &l, &r, &v);
            if (v == 0) {
                printf("%.20lf\n", 1.0 * l);
                continue;
            }
            auto itl = f.lower_bound(l);
            auto itr = f.upper_bound(r);
            if (itl == f.end() || itr == f.begin()) {
                puts("-1");
                continue;
            }
            itr = prev(itr);
            int tl = *itl, tr = *itr;
            if (tl > tr) {
                puts("-1");
                continue;
            }
            treap *a, *b, *c, *d;
            split(bst, tl - 1, a, b);
            split(b, tr, c, d);
            if (!c) {
                puts("-1");
                bst = merge(a, merge(c, d));
                continue;
            }
            int x = dfs(c, v);
            if (x == -1) {
                treap *y = right(c);
                assert(c->pref < v);
                if (c->sum + y->v * 1ll * (r - y->t) >= v) printf("%.20lf\n", y->t + 1.0 * (v - c->sum) / y->v);
                else puts("-1");
            } else {
                int z = *prev(f.lower_bound(x));
                treap *lz, *rz;
                split(c, z, lz, rz);
                assert(lz->sum <= v);
                double need = 1.0 * (v - lz->sum) / lz->ed->v;
                printf("%.20lf\n", lz->ed->t + need);
                c = merge(lz, rz);
            }
            bst = merge(a, merge(c, d));
        }
    }
}

#include<bits/stdc++.h>
using namespace std;
#define pr pair<LL,LL>
#define mk(a,b) make_pair(a,b)
#define LL long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

const int maxn=3e5+5;
struct NODE{
    LL mn,edsum,edval,bgpos;
    int l,r;//离散化前表示的区间
    NODE(){
        mn=edval=bgpos=edsum=0;
    }
    NODE operator +(const NODE&p)const{
        NODE tp;
    //    printf("r=%d p.l=%d\n",r,p.l);
        assert(r+1==p.l);
        if(p.bgpos==0){
            tp.edsum=edsum+edval*(p.r-p.l+1);
            tp.edval=edval;
            tp.bgpos=bgpos;
            tp.mn=min(mn,tp.edsum);
            tp.l=l,tp.r=p.r;
        }else{
            tp.edsum=edsum+p.edsum+edval*(p.bgpos-r-1);
            tp.edval=p.edval;
            tp.bgpos=bgpos==0?p.bgpos:bgpos;
            tp.mn=min(mn,edsum+p.mn+edval*(p.bgpos-r-1));
            tp.l=l,tp.r=p.r;
        }
        return tp;
    }
    void print(){
        printf("l=%d r=%d mn=%lld edsum=%lld edval=%lld bgpos=%lld\n",l,r,mn,edsum,edval,bgpos);
    }
}T[maxn<<2];
//LL mn[maxn<<2],ed[maxn<<2];
    vector<int>v;
void updata(int rt){
    T[rt]=T[rt<<1]+T[rt<<1|1];
}
void build(int l,int r,int rt){
    if(l==r){
        T[rt]=NODE();
        T[rt].l=v[l-1];
        assert(l<=v.size());
        if(l==v.size())T[rt].r=v[l-1];
        else T[rt].r=(v[l]-1);
    //    printf("pos=%d l=%d r=%lld\n",l,T[rt].l,T[rt].r);
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
 //   printf("l=%d r=%d\n",l,r);
    updata(rt);
}
const int inf=1e9+7;
void modify(int l,int r,int rt,int pos,int val){
    if(l==r){
        if(val==inf){
            NODE tp=NODE();
            tp.l=T[rt].l,tp.r=T[rt].r;
            T[rt]=tp;
            return;
        }else{
            T[rt].edsum=(LL)val*(LL)(T[rt].r-T[rt].l+1);
            T[rt].mn=min(0ll,T[rt].edsum);
            T[rt].bgpos=T[rt].l;
            T[rt].edval=val;
         //   mn[rt]=min(0ll,ed[rt]);
            return;
        }
    }
    int mid=(l+r)>>1;
    if(pos<=mid)modify(lson,pos,val);
    else modify(rson,pos,val);
    updata(rt);
}
NODE query(int l,int r,int rt,int nl,int nr){
 //   printf("l=%d r=%d ed=%lld mn=%lld\n",l,r,ed[rt],mn[rt]);
 //   if(nl>nr)return mk(0,0);
    assert(nl<=nr);
    if(nl<=l&&nr>=r){
        return T[rt];
    }
    int mid=(l+r)>>1;
    if(nl<=mid&&nr>mid){
        return query(lson,nl,nr)+query(rson,nl,nr);
    //    return mk(u.first+v.first,min(u.second,u.first+v.second));
    }else if(nl<=mid)return query(lson,nl,nr);
    else if(nr>mid)return query(rson,nl,nr);
}
void print(int l,int r,int rt){
    printf("l=%d r=%d rt=%d\n",l,r,rt);
    T[rt].print();
    if(l==r)return;
    int mid=(l+r)>>1;
    print(lson);
    print(rson);
}
namespace santongding{
    struct Q{
        int l,r,v,ck;
    }qr[maxn];
    double solve(int l,int r,int val){
    //    puts("@!#");
        if(l==r){
        //    puts("!!!");
            if(val==0)return l;
            else return -1.0;
        }
        assert(l<r);
        r--;
        NODE ans=query(1,v.size(),1,l,r);
        if(ans.mn+val>0)return -1.0;
        int bg=l;
        while(l!=r){
            int mid=(l+r)>>1;
        //    printf("l=%d r=%d\n",l,r);
            NODE tp=query(1,v.size(),1,bg,mid);
            if(tp.mn+val<=0){
                r=mid;
            }else{
                l=mid+1;
            }
        }
    //    printf("bg=%d l=%d\n",bg,l);
      //  printf("%lld %lld \n",ans.first,ans.second);
     //   exit(0);
     //   if(ans.edsum+val>0)return -1.0;
     //   puts("!(@");
        ans=query(1,v.size(),1,bg,l);
        assert(ans.edval<0);
        assert(ans.mn==ans.edsum);
  //      ans.print();
    //    exit(0);
      //  printf("%lld %lld %lld %lld\n",a.first,a.second,b.first,b.second);
        return (double)ans.r+1.0-(double)(ans.edsum+val)/(double)ans.edval;

    }
    int getpos(int pos){
        return lower_bound(v.begin(),v.end(),pos)-v.begin()+1;
    }
    void solve(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&qr[i].ck);
            if(qr[i].ck==1){
                scanf("%d%d",&qr[i].l,&qr[i].v);
                v.push_back(qr[i].l);
            }
            else if(qr[i].ck==2){
                scanf("%d",&qr[i].l);
                v.push_back(qr[i].l);
            }else{
                scanf("%d%d%d",&qr[i].l,&qr[i].r,&qr[i].v);
                v.push_back(qr[i].l);
                v.push_back(qr[i].r);
            }
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
     //   printf("siz=%d\n",v.size());
    //    for(auto x:v)printf("%d ",x);
     //   puts("");
        build(1,v.size(),1);
      //  print(1,v.size(),1);
        for(int i=1;i<=n;i++){
            if(qr[i].ck==1)modify(1,v.size(),1,getpos(qr[i].l),qr[i].v);
            else if(qr[i].ck==2)modify(1,v.size(),1,getpos(qr[i].l),inf);
            else{
            //    print(1,v.size(),1);
           //     exit(0);
                if(qr[i].v==0){
                    printf("%d\n",qr[i].l);
                }else{
                printf("%.8f\n",solve(getpos(qr[i].l),getpos(qr[i].r),qr[i].v));
                }
            }
        }
    }
}
int main(){
//   freopen("in.txt","r",stdin);
    int t=1;
//    scanf("%d",&t);
    while(t--){
        santongding::solve();
    }
}

#include <iostream>
#include <cmath>
#include <map>

using namespace std;

typedef long long int ll;

const int infinite=1000000005;

struct elem {
  ll s,hs,posle,posri;
  ll minimum,hri,marginle;
  elem() {
    s=hs=minimum=hri=marginle=0;
    posle=posri=infinite;
  }
};

const int tope=1<<20;
const int first=1<<19;

elem v[tope];
map<int,int> mapa;

void insert(int posreal,int s,int hs)
{
  //cout<<"insert posreal "<<posreal<<" s "<<s<<" hs "<<hs<<endl;
  int pos=mapa[posreal];
  //cout<<"pos "<<pos<<endl;
  pos+=first;
  {
    elem &e=v[pos];
    e.posle=e.posri=posreal;
    e.s=s;
    e.hs=hs;
  }
  while (pos>1) {
    pos/=2;
    elem &e=v[pos];
    elem &e0=v[2*pos];
    elem &e1=v[2*pos+1];
    e.posle=e0.posle;
    e.posri=e1.posri;
    e.hs=e0.hs or e1.hs;
    e.s=e1.hs?e1.s:e0.s;
    if (e0.hs && e1.hs) {
      e.marginle=e0.marginle;
      e.minimum=min(e0.minimum,e0.hri+e0.s*(e1.marginle+e1.posle-e0.posri)+e1.minimum);
      e.hri=e0.hri+e0.s*(e1.marginle+e1.posle-e0.posri)+e1.hri;
    } else if (e0.hs) {
      e.marginle=e0.marginle;
      e.minimum=min(e0.minimum,e0.hri+e0.s*(e1.posri-e0.posri));
      e.hri=e0.hri+e0.s*(e1.posri-e0.posri);
    } else if (e1.hs) {
      e.marginle=e1.posle-e0.posle+e1.marginle;
      e.minimum=e1.minimum;
      e.hri=e1.hri;
    }
  }
}

double simulate(int pos,ll s,ll hri,int posrealr)
{
  //cout<<"simulate posle "<<v[pos].posle<<" posri "<<v[pos].posri<<" s "<<s<<" hri "<<hri<<" posrealr "<<posrealr<<endl;
  if (posrealr<v[pos].posle) return -1;
  if (first<=pos) return v[pos].posle;
  int pos0=2*pos;
  int pos1=2*pos+1;
  elem &e0=v[pos0];
  elem &e1=v[pos1];
  int posle=e0.posle;
  if (e0.hs) {
    if (hri+s*e0.marginle+e0.minimum<=0) return simulate(pos0,s,hri,posrealr);
    hri+=s*e0.marginle+e0.hri;
    s=e0.s;
    posle=e0.posri;
  }
  if (hri+s*(e1.posle-posle)<=0) {
    if (hri<=-s*(posrealr-posle))
      return posle+double(hri)/(-s);
    return -1;
  }
  hri+=s*(e1.posle-posle);
  return simulate(pos1,s,hri,posrealr);
}

double simulate(int posreall,int posrealr,ll hri)
{
  if (hri<=0) return posreall;
  if (posreall==posrealr) return -1;
  int pos0=mapa[posreall];
  pos0+=first;
  ll s=v[pos0].s;
  while (pos0>1) {
    if (posrealr<v[pos0].posri) return -1;
    if (pos0%2==0) {
      elem &e0=v[pos0];
      int pos1=pos0+1;
      elem &e1=v[pos1];
      if (hri+s*(e1.posle-e0.posri)<=0) {
	if (hri<=-s*(posrealr-e0.posri))
	  return e0.posri+double(hri)/(-s);
	return -1;
      }
      hri+=s*(e1.posle-e0.posri);
      if (e1.hs) {
	if (hri+s*e1.marginle+e1.minimum<=0)
	  return simulate(pos1,s,hri,posrealr);
	hri+=s*e1.marginle+e1.hri;
	s=e1.s;
      } else {
	if (hri+s*(e1.posri-e1.posle)<=0)
	  return simulate(pos1,s,hri,posrealr);
	hri+=s*(e1.posri-e1.posle);
      }
    }
    pos0/=2;
  }
  return -1;
}

const int limit=1000000;
int cases;
int kind[limit];
int le[limit],ri[limit],H[limit],t[limit],s[limit];

int main()
{
  cout.setf(ios::fixed);
  cout.precision(10);
  ios::sync_with_stdio(false);
  cin>>cases;
  for (int cas=1;cas<=cases;cas++) {
    cin>>kind[cas];
    if (kind[cas]==1) {
      cin>>t[cas]>>s[cas];
      mapa[t[cas]];
    } else if (kind[cas]==2) {
      cin>>t[cas];
    } else {
      cin>>le[cas]>>ri[cas]>>H[cas];
      mapa[le[cas]];
      mapa[ri[cas]];
    }
  }
  {
    int n=0;
    for (map<int,int>::iterator it=mapa.begin();it!=mapa.end();it++,n++)
      it->second=n;
    for (map<int,int>::iterator it=mapa.begin();it!=mapa.end();it++)
      insert(it->first,0,0);
  }
  for (int cas=1;cas<=cases;cas++) {
    if (kind[cas]==1) {
      insert(t[cas],s[cas],1);
    } else if (kind[cas]==2) {
      insert(t[cas],0,0);
    } else {
      double sol=simulate(le[cas],ri[cas],H[cas]);
      if (sol<0) cout<<-1<<endl;
      else cout<<sol<<endl;
    }
  }
}

#ifndef LOCAL
#pragma GCC optimize ("O3")
#endif

#include <bits/stdc++.h>

using namespace std;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return {i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (c it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(x...) " [" #x ": " << (x) << "] "

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
template <typename A, typename B>
using unordered_map2 = __gnu_pbds::gp_hash_table<A, B>;
using namespace __gnu_pbds;
template <typename T> using ordered_set =
  __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag,
                   __gnu_pbds::tree_order_statistics_node_update>;
// ordered_set<int> s; s.insert(1); s.insert(2);
// s.order_of_key(1);    // Out: 0.
// *s.find_by_order(1);  // Out: 2.

using ld = long double;
using ll = long long;

constexpr int mod = 1000 * 1000 * 1000 + 7;
constexpr int odw2 = (mod + 1) / 2;

void OdejmijOd(int& a, int b) { a -= b; if (a < 0) a += mod; }
int Odejmij(int a, int b) { OdejmijOd(a, b); return a; }
void DodajDo(int& a, int b) { a += b; if (a >= mod) a -= mod; }
int Dodaj(int a, int b) { DodajDo(a, b); return a; }
int Mnoz(int a, int b) { return (ll) a * b % mod; }
void MnozDo(int& a, int b) { a = Mnoz(a, b); }
int Pot(int a, ll b) { int res = 1; while (b) { if (b % 2 == 1) MnozDo(res, a); a = Mnoz(a, a); b /= 2; } return res; }
int Odw(int a) { return Pot(a, mod - 2); }
void PodzielDo(int& a, int b) { MnozDo(a, Odw(b)); }
int Podziel(int a, int b) { return Mnoz(a, Odw(b)); }
int Moduluj(ll x) { x %= mod; if (x < 0) x += mod; return x; }

template <typename T> T Maxi(T& a, T b) { return a = max(a, b); }
template <typename T> T Mini(T& a, T b) { return a = min(a, b); }

constexpr int Nie = numeric_limits<int>::max();

struct Node {
  int ustaw = Nie;
  int len = 0;
  ll najm = 0, ost = 0;

  int GetL(int w) { return w * 2; }
  int GetR(int w) { return w * 2 + 1; }
};

int n2;
unique_ptr<Node[]> nodes;

Node& Get(int x) {
  return nodes[x];
}

int Left(int p, int k) {
  return (p + k) / 2;
}

int Right(int p, int k) {
  return (p + k) / 2 + 1;
}

void Spusc(int w, Node& n, int p, int k) {
  if (n.ustaw != Nie) {
    if (p < k) {
      Node& l = Get(n.GetL(w));
      Node& r = Get(n.GetR(w));
      r.ustaw = l.ustaw = n.ustaw;
    }
    n.ost = ll(n.len) * n.ustaw;
    n.najm = min(0ll, n.ost);
    n.ustaw = Nie;
  }
}

void Update(int w, Node& n) {
  Node& l = Get(n.GetL(w));
  Node& r = Get(n.GetR(w));
  n.ost = l.ost + r.ost;
  n.najm = min(l.najm, l.ost + r.najm);
}

void Dodaj(int w, int p, int k, int a, int b, int s) {
  Node& n = Get(w);
  Spusc(w, n, p, k);
  if (k < a or b < p) return;
  if (a <= p and k <= b) {
    n.ustaw = s;
    Spusc(w, n, p, k);
    return;
  }
  Dodaj(n.GetL(w), p, Left(p, k), a, b, s);
  Dodaj(n.GetR(w), Right(p, k), k, a, b, s);
  Update(w, n);
}

constexpr int N = 1000 * 1000 * 1000 + 105;
vector<int> num = {0, N};
map<int, int> mapa;

pair<ll, ld> Wynik(int w, int p, int k, int a, int b, ll v) {
  #ifdef LOCAL
  assert(v > 0);
  #endif
  Node& n = Get(w);
  Spusc(w, n, p, k);
  if (b < p or k < a) {
    return {v, 0.0l};
  }
  if (a <= p and k <= b) {
    if (v + n.najm > 0) {
      return {v + n.ost, 0.0l};
    }
    if (p == k) {
      return {-1, (num[p] + ld(-v) / ld(n.ost / n.len))};
    }
  }
  auto res = Wynik(n.GetL(w), p, Left(p, k), a, b, v);
  if (res.first < 0) return res;
  return Wynik(n.GetR(w), Right(p, k), k, a, b, res.first);
}

void Zap1(int t, int s) {
  auto res = mapa.insert(make_pair(t, s));
  assert(res.second);
  auto it = res.first;
  auto nt = next(it);
  Dodaj(1, 0, n2 - 1, t, nt->first - 1, s);
}

void Zap2(int t) {
  auto it = mapa.find(t);
  assert(it != mapa.end());
  auto pr = prev(it);
  auto nt = next(it);
  mapa.erase(it);
  Dodaj(1, 0, n2 - 1, pr->first, nt->first - 1, pr->second);
}

void Zap3(int l, int r, ll v) {
  if (v == 0) {
    cout << num[l] << '\n';
    return;
  }
  l = mapa.lower_bound(l)->first;
  if (l >= r) {
    cout << -1 << '\n';
    return;
  }
  auto res = Wynik(1, 0, n2 - 1, l, r - 1, v);
  debug() << imie(l) imie(r) imie(v) imie(res);
  if (res.first < 0) {
    cout << res.second << '\n';
    return;
  }
  cout << -1 << '\n';
  return;
  auto it = prev(mapa.lower_bound(r + 1));
  int s = 0;
  if (it->first >= l) {
    s = it->second;
  }
  if (s >= 0) {
    cout << -1 << '\n';
    return;
  }
  cout << ((r + 1) + ld(-v) / s) << '\n';
}

int Znajdz(int x) {
  return lower_bound(num.begin(), num.end(), x) - num.begin();
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  //Init();
  //debug() << imie(Max);
  mapa[0] = 0;
  mapa[N] = 0;
//  if (NewNode() != 1) {
//    assert(false);
//    abort();
//  }
  int q;
  cin >> q;
  while (q--) {
    int typ;
    cin >> typ;
    if (typ == 1) {
      int t, s;
      cin >> t >> s;
      num.push_back(t);
      //Zap1(t, s);
    } else if (typ == 2) {
      int t;
      cin >> t;
      num.push_back(t);
      //Zap2(t);
    } else if (typ == 3) {
      int l, r, v;
      cin >> l >> r >> v;
      //Zap3(l, r, v);
      num.push_back(l);
      num.push_back(r);
    } else {
      assert(false);
    }
  }
  sort(num.begin(), num.end());
  num.erase(unique(num.begin(), num.end()), num.end());
  n2 = 1;
  while (n2 <= (int) num.size()) n2 *= 2;
  nodes = unique_ptr<Node[]>(new Node[n2 * 2]);
  for (int i = 1; i < (int) num.size(); i++) {
    nodes[n2 + i - 1].len = num[i] - num[i - 1];
  }
  for (int i = n2 - 1; i >= 1; i--) {
    nodes[i].len = nodes[i * 2].len + nodes[i * 2 + 1].len;
  }

  cin.seekg(0);

  debug() << imie(num);

  cin >> q;
  cout << fixed << setprecision(10);
  while (q--) {
    int typ;
    cin >> typ;
    if (typ == 1) {
      int t, s;
      cin >> t >> s;
      Zap1(Znajdz(t), s);
    } else if (typ == 2) {
      int t;
      cin >> t;
      Zap2(Znajdz(t));
    } else if (typ == 3) {
      int l, r, v;
      cin >> l >> r >> v;
      Zap3(Znajdz(l), Znajdz(r), v);
    } else {
      assert(false);
    }
  }
  return 0;
}

#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <chrono>
#include <random>
#include <iostream>
#define FOR(i, n) for(int i = 0; i < n; i++)
#define D(x) cout << #x << ": " << x << endl;
using namespace std;

typedef pair<int,int> pii;
typedef long long ll;

#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)

#define time__(d) \
    for ( \
        auto blockTime = make_pair(chrono::high_resolution_clock::now(), true); \
        blockTime.second; \
        debug("%s: %ld ms\n", d, chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - blockTime.first).count()), blockTime.second = false \
    )

mt19937 rng (chrono::steady_clock::now().time_since_epoch().count());

const int MAXN = 100100;
const int inf = (int)1e9 + 1000;
const ll infll = (ll)1e18 + 1000;

int getRandom () {
	return uniform_int_distribution<int>(-inf, inf)(rng);
}

struct Node {
	int time, speed, pr;
	int tL, tR, speedR;
	ll sum, minSum;
	int l, r;
};

Node tree[MAXN];
int cnt = 1;

int getNode () {
	return cnt++;
}

void update (int v) {
	if (!v) return;
	int l = tree[v].l, r = tree[v].r;
	tree[v].tL = tree[v].tR = tree[v].time;
	tree[v].speedR = tree[v].speed;
	tree[v].sum = 0;
	tree[v].minSum = 0;
	ll gap1, gap2;
	if (l) {
		tree[v].tL = tree[l].tL;
		gap1 = (ll) (tree[v].time - tree[l].tR) * tree[l].speedR;
		tree[v].sum += tree[l].sum + gap1;
		tree[v].minSum = min (tree[v].minSum, min (tree[l].minSum, tree[v].sum));
	}
	if (r) {
		tree[v].tR = tree[r].tR;
		tree[v].speedR = tree[r].speedR;
		gap2 = (ll) (tree[r].tL - tree[v].time) * tree[v].speed;
		tree[v].sum += gap2 + tree[r].sum;
		if (!l) tree[v].minSum = min (tree[v].minSum, min (gap2, gap2 + tree[r].minSum));
	}
	if (l && r) tree[v].minSum = min (tree[v].minSum, tree[l].sum + gap1 + gap2 + tree[r].minSum);
	tree[v].minSum = min (tree[v].minSum, tree[v].sum);
}

void split (int t, int &L, int &R, int val) {
	if (!t) {
		L = R = 0;
	} else if (val >= tree[t].time) {
		split (tree[t].r, tree[t].r, R, val);
		L = t;
	} else {
		split (tree[t].l, L, tree[t].l, val);
		R = t;
	}
	update (t);
}

void merge (int &t, int l, int r) {
	if (!l || !r) {
		t = l ? l : r;
	} else if (tree[l].pr > tree[r].pr) {
		merge (tree[l].r, tree[l].r, r);
		t = l;
	} else {
		merge (tree[r].l, l, tree[r].l);
		t = r;
	}
	update (t);
}

void insert (int &t, int it) {
	if (!t) {
		t = it;
	} else if (tree[it].pr > tree[t].pr) {
		split (t, tree[it].l, tree[it].r, tree[it].time);
		t = it;
	} else {
		insert (tree[it].time >= tree[t].time ? tree[t].r : tree[t].l, it);
	}
	update (t);
}

void erase (int &t, int val) {
	if (!t) return;
	else if (tree[t].time == val) {
		merge (t, tree[t].l, tree[t].r);
	} else {
		erase (val > tree[t].time ? tree[t].r : tree[t].l, val);
	}
	update (t);
}

double query (int t, ll v) {
	if (tree[t].minSum + v > 0) return -1;
	int l = tree[t].l, r = tree[t].r;
	if (l) {
		if (v + tree[l].minSum <= 0) return query (l, v);
		ll gap1 = (ll) tree[l].speedR * (tree[t].time - tree[l].tR);
		if (v + tree[l].sum + gap1 <= 0) return (double) (v + tree[l].sum) / -tree[l].speedR + tree[l].tR;
		v += tree[l].sum + gap1;
	}
	if (r) {
		ll gap2 = (ll) tree[t].speed * (tree[r].tL - tree[t].time);
		if (v + gap2 <= 0) return (double) (v) / -tree[t].speed + tree[t].time;
		v += gap2;
		return query (r, v);
	}
	return -1; // should never happen
}

double query (int &t, int a, int b, int v) {
	int l, r;
	if (v == 0) return a;
	split (t, l, r, a - 1);
	double ret;
	ret = query (r, v);
	merge (t, l, r);
	return ret - 1e-9 < b ? ret : -1;
}

int q;

void load() {
	scanf("%d", &q);
}

void solve() {
	int t = 0;
	auto INSERT = [&](int time, int speed) -> void {
		int it = getNode();
		tree[it].time = time;
		tree[it].speed = speed;
		tree[it].pr = getRandom ();
		insert (t, it);
	};
	INSERT (0, 0);
	INSERT (inf, 0);
	while (q--) {
		int a, b, c, d;
		scanf("%d", &a);
		if (a == 1) {
			scanf("%d%d", &b, &c);
			INSERT (b, c);
		} else if (a == 2) {
			scanf("%d", &b);
			erase (t, b);
		} else {
			scanf("%d%d%d", &b, &c, &d);
			printf("%.10lf\n", query (t, b, c, d));
		}
	}
}

int main() {
	load();
	solve();
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define disp(x) cout << #x << "=" << x << "; "
#define dprintf(...) fprintf(stderr, __VA_ARGS__)

template <class T> bool chkmin(T& a, T b) { return a > b ? a = b, 1 : 0; }
template <class T> bool chkmax(T& a, T b) { return a < b ? a = b, 1 : 0; }

const int maxN = 2e5 + 5;
const int maxB = 505;
const double eps = 1e-10;

inline int dcmp(const double& a) {
	if(fabs(a) < eps) return 0;
	return a > 0 ? 1 : -1;
}

typedef long long LL;

struct Query {
	int ty, t, s, l, r, v;
}que[maxN];

bool act[maxN];
int spd[maxN];
int T, Q;
int blsz;
LL mindec[maxB], findec[maxB];
int finspd[maxB], firchg[maxB];
int Hash[maxN];

#define idx(x) (lower_bound(Hash + 1, Hash + T + 1, x) - Hash)

void rebuild(int k) {
	//printf("in rebuild"), disp(k), puts("");

	int l = (k - 1) * blsz + 1;
	int r = k * blsz;

	LL sum = 0, mn = 0;
	firchg[k] = 0;
	int curs = 0;
	for(int i = l; i <= r; ++i) {
		sum += (LL) curs * (Hash[i] - Hash[i - 1]);
		chkmin(mn, sum);
		if(act[i]) {
			curs = spd[i];
			if(firchg[k] == 0) firchg[k] = i;
		}
	}
	findec[k] = sum;
	mindec[k] = mn;
	finspd[k] = curs;
}

void modify(int t, int s) {
	int idxt = idx(t);
	act[idxt] = 1;
	spd[idxt] = s;
	rebuild((idxt - 1) / blsz + 1);
}

void erase(int t) {
	int idxt = idx(t);
	act[idxt]= 0;
	rebuild((idxt - 1) / blsz + 1);
}

double Proc(int l, int r, LL& sum, int& curs) {
	//printf("in Proc"), disp(l), disp(r), disp(sum), disp(curs), puts("");
	for(int i = l; i <= r; ++i) {
		//disp(i), disp(curs), puts("");
		LL tmp = sum + (LL) curs * (Hash[i] - Hash[i - 1]);
		if(tmp <= 0) return Hash[i - 1] + ((double) -sum / (double) curs);
		sum = tmp;
		if(act[i]) curs = spd[i];
	}
	return -1;
}

double getans(int l, int r, int v) {
	//printf("----------in getans");disp(l), disp(r), disp(v), puts("");

	if(v == 0) return l;
	l = idx(l), r = idx(r);
	int lbl = (l - 1) / blsz + 1;
	int rbl = (r - 1) / blsz + 1;
	int curs = 0;
	LL sum = v;
	if(lbl == rbl) {
		return Proc(l, r, sum, curs);
	} else {
		double ret = Proc(l, lbl * blsz, sum, curs);

		if(dcmp(ret + 1) != 0) return ret;

		for(int i = lbl + 1; i < rbl; ++i) {
			LL tmp = 0;
			if(firchg[i])
				tmp = sum + (LL)curs * (Hash[firchg[i]] - Hash[(i-1)*blsz]);
			else tmp = sum + (LL) curs * (Hash[i*blsz]-Hash[(i-1)*blsz]);
			if(tmp <= 0)
				return Hash[(i-1)*blsz] + ((double) -sum / (double) curs);
			sum = tmp;
			//disp(i), disp(sum), puts("");
			if(sum + mindec[i] <= 0) {
				curs = spd[firchg[i]];
				return Proc(firchg[i] + 1, i * blsz, sum, curs);
			}

			if(firchg[i]) {
				sum += findec[i];
				curs = finspd[i];
			}
			//disp(i), disp(sum), disp(curs), puts("");
		}

		return Proc((rbl - 1) * blsz + 1, r, sum, curs);
	}
	return -1;
}

int main() {
#ifdef Leeson
	freopen("tmp.in", "r", stdin);
	freopen("tmp.out", "w", stdout);
#endif

	scanf("%d", &Q);
	for(int i = 1; i <= Q; ++i) {
		scanf("%d", &que[i].ty);
		if(que[i].ty == 1) {
			scanf("%d%d", &que[i].t, &que[i].s);
			Hash[++T] = que[i].t;
		} else if(que[i].ty == 2) {
			scanf("%d", &que[i].t);
			Hash[++T] = que[i].t;
		} else {
			scanf("%d%d%d", &que[i].l, &que[i].r, &que[i].v);
			Hash[++T] = que[i].l;
			Hash[++T] = que[i].r;
		}
	}

	sort(Hash + 1, Hash + T + 1);
	T = unique(Hash + 1, Hash + T + 1) - Hash - 1;
	blsz = sqrt(T);

	//for(int i = 1; i <= T; ++i) disp(Hash[i]), puts("");
	//disp(T), disp(blsz), puts(""), puts("");

	for(int i = 1; i <= Q; ++i) {

		//printf("while i = %d ----------------\n", i);

		if(que[i].ty == 1) {
			modify(que[i].t, que[i].s);
		} else if(que[i].ty == 2) {
			erase(que[i].t);
		} else {
			double ret = getans(que[i].l, que[i].r, que[i].v);
			if(dcmp(ret+1) <= 0) puts("-1");
			else printf("%.7f\n", ret);
		}

		//for(int t = 1; t <= T; ++t) {
		//	printf("% 3d", Hash[t]);
		//} puts("");
		//for(int t = 1; t <= T; ++t) {
		//	printf("% 3d", (int) act[t] * spd[t]);
		//} puts("");

		//for(int i = 1; i <= (T / blsz) + 1; ++i)
		//	disp(i), disp(mindec[i]), disp(findec[i]), disp(finspd[i]), puts("");

	}

	return 0;
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#define int long long
#define pii pair<int, int>
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define endl "\n"
//#pragma GCC optimize ("O3")

using namespace std;

const int N = 1e6 + 10;
const int inf = 2e18;
const int mod = 1e9 + 7;
const int eps = 1e-9;
const char spc = 29;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

struct node {
	int key = 0;
	int prir = rnd();
	int speed = 0;
	int mxt = -inf;
	int mnt = inf;
	int mxtspeed = 0;
	int res = 0;
	int mn = 0;
	int l = -1, r = -1;
};

node t[N];
int top = 0;
int rt = -1;
set<int> st;
vector<pair<pii, pii>> qv;

void upd(int nd)
{
	if (nd == -1)
		return;

	node l;
	node r;

	if (t[nd].l != -1)
		l = t[t[nd].l];

	if (t[nd].r != -1)
		r = t[t[nd].r];

	t[nd].mxt = max(t[nd].key, r.mxt);
	t[nd].mnt = min(t[nd].key, l.mnt);

	assert(t[nd].mxt >= l.mxt);
	assert(t[nd].mnt <= r.mnt);

	if (r.mxt > t[nd].key)
		t[nd].mxtspeed = r.mxtspeed;
	else
		t[nd].mxtspeed = t[nd].speed;

	t[nd].mn = 0;
	t[nd].res = l.res;
	t[nd].mn = min(t[nd].mn, l.mn);
	t[nd].mn = min(t[nd].mn, t[nd].res);

	if (l.mxt != -inf)
		t[nd].res += abs(t[nd].key - l.mxt) * l.mxtspeed;

	t[nd].mn = min(t[nd].mn, t[nd].res);

	if (r.mnt != inf)
		t[nd].res += abs(r.mnt - t[nd].key) * t[nd].speed;

	t[nd].mn = min(t[nd].mn, t[nd].res);
	t[nd].mn = min(t[nd].mn, t[nd].res + r.mn);
	t[nd].res += r.res;
	t[nd].mn = min(t[nd].mn, t[nd].res);
}

int merge(int l, int r)
{
	if (l == -1) return r;
	if (r == -1) return l;

	if (t[l].prir > t[r].prir)
	{
		t[l].r = merge(t[l].r, r);
		upd(l);
		return l;
	}
	else
	{
		t[r].l = merge(l, t[r].l);
		upd(r);
		return r;
	}
}

pii split(int nd, int key)
{
	if (nd == -1)
		return make_pair(-1, -1);

	if (t[nd].key <= key)
	{
		pii p = split(t[nd].r, key);

		t[nd].r = p.x;
		upd(nd);

		return make_pair(nd, p.y);
	}
	else
	{
		pii p = split(t[nd].l, key);

		t[nd].l = p.y;
		upd(nd);

		return make_pair(p.x, nd);
	}
}

void init(node &nd, int key, int speed)
{
	nd.key = key;
	nd.speed = speed;
	nd.mxt = key;
	nd.mnt = key;
	nd.mxtspeed = speed;
	nd.l = -1;
	nd.r = -1;
	nd.res = 0;
	nd.mn = 0;
}

void add(int pos, int val)
{
	init(t[top], pos, val);

	pii p = split(rt, pos);

	rt = merge(p.x , merge(top, p.y));

	++top;
}

void del(int pos)
{
	pii p1 = split(rt, pos);
	pii p2 = split(p1.x, pos - 1);

	rt = merge(p2.x, p1.y);
}

double rec(int nd, int have)
{
	if (nd == -1)
		return -1;

	if (t[nd].mn + have > 0)
		return -1;

	double res = rec(t[nd].l, have);

	if (res > -0.5)
		return res;

	if (t[nd].l != -1)
		have += t[t[nd].l].res;

	if (have <= 0)
	{
		if (t[nd].l != -1)
			return t[t[nd].l].mxt;

		return t[nd].key;
	}

	if (t[nd].l != -1)
	{
		if (have + abs(t[nd].key - t[t[nd].l].mxt) * t[t[nd].l].mxtspeed <= 0)
			return (double)t[t[nd].l].mxt + abs((double)have / (double)t[t[nd].l].mxtspeed);

		have += abs(t[nd].key - t[t[nd].l].mxt) * t[t[nd].l].mxtspeed;
	}

	if (t[nd].r != -1)
	{
		if (have + abs(t[t[nd].r].mnt - t[nd].key) * t[nd].speed <= 0)
			return (double)t[nd].key + abs((double)have / (double)t[nd].speed);

		have += abs(t[t[nd].r].mnt - t[nd].key) * t[nd].speed;
	}

	res = rec(t[nd].r, have);

	if (res > -0.5)
		return res;

	assert(1 != 1);
}

double get(int l, int r, int have)
{
	pii p1 = split(rt, l - 1);
	pii p2 = split(p1.y, r);
	int seg = p2.x;

	double res = rec(seg, have);

	if (res > -0.5)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return res;
	}

	rt = merge(p1.x, merge(p2.x, p2.y));
	return -1;
}

int q;

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cout.precision(7);

	cin >> q;

	while (q--)
	{
		int tp;

		cin >> tp;

		if (tp == 1)
		{
			int tm, speed;

			cin >> tm >> speed;

			add(tm, speed);
			st.insert(tm);
		}
		else if (tp == 2)
		{
			int tm;

			cin >> tm;

			del(tm);
			st.erase(tm);
		}
		else
		{
			int l, r, have;

			cin >> l >> r >> have;

			if (st.find(l) == st.end())
				add(l, 0);

			if (st.find(r) == st.end())
				add(r, 0);

			cout << get(l, r, have) << endl;

			if (st.find(l) == st.end())
				del(l);

			if (st.find(r) == st.end())
				del(r);
		}
	}
}

#include <bits/stdc++.h>

typedef long long LL;
const int N = 800005;

int q;

int opt[N], x[N], y[N];
LL z[N];
int val[N], tot;

std::set<int> set;

int prev(int x) {
	std::set<int>::iterator it = set.find(x);
	return it == set.begin() ? 0 : *--it;
}
int next(int x) {
	std::set<int>::iterator it = set.find(x);
	return ++it == set.end() ? tot : *it;
}

int weight[N];
LL tag[N], min[N], max[N];

void setadd(int o, LL v) { tag[o] += v, min[o] += v, max[o] += v; }
void pushdown(int o) { setadd(o << 1, tag[o]), setadd(o << 1 | 1, tag[o]), tag[o] = 0; }
void pushup(int o) {
	min[o] = std::min(min[o << 1], min[o << 1 | 1]);
	max[o] = std::max(max[o << 1], max[o << 1 | 1]);
}

void modify(int L, int R, LL v, int o = 1, int l = 1, int r = tot) {
	if (L <= l && R >= r) return setadd(o, v);
	int mid = l + r >> 1; pushdown(o);
	if (L <= mid) modify(L, R, v, o << 1, l, mid);
	if (R > mid) modify(L, R, v, o << 1 | 1, mid + 1, r);
	pushup(o);
}
LL query(int pos, int o = 1, int l = 1, int r = tot) {
	if (l == r) return min[o];
	int mid = l + r >> 1; pushdown(o);
	if (pos <= mid)
		return query(pos, o << 1, l, mid);
	else
		return query(pos, o << 1 | 1, mid + 1, r);
}

int find(int L, LL val, bool &m, bool &M, int o = 1, int l = 1, int r = tot) {
	if (L <= l && (!(m || min[o] <= val) || !(M || max[o] >= val)))
		return m |= min[o] <= val, M |= max[o] >= val, -1;
	if (l == r) return l;
	int mid = l + r >> 1; pushdown(o);
	int ret = -1;
	if (L <= mid)
		ret = find(L, val, m, M, o << 1, l, mid);
	if (ret != -1) return ret;
	return find(L, val, m, M, o << 1 | 1, mid + 1, r);
}

int main() {
	std::ios::sync_with_stdio(0), std::cin.tie(0);
	std::cin >> q;
	for (int i = 1; i <= q; ++i) {
		std::cin >> opt[i];
		if (opt[i] == 1)
			std::cin >> x[i] >> y[i], val[++tot] = x[i];
		else if (opt[i] == 2) std::cin >> x[i];
		else {
			std::cin >> x[i] >> y[i] >> z[i];
			val[++tot] = x[i], val[++tot] = y[i];
		}
	}
	val[++tot] = 1e9, val[++tot] = 0;
	std::sort(val + 1, val + tot + 1);
	tot = std::unique(val + 1, val + tot + 1) - val - 1;
	for (int i = 1; i <= q; ++i) {
		x[i] = std::lower_bound(val + 1, val + tot + 1, x[i]) - val;
		if (opt[i] == 3)
			y[i] = std::lower_bound(val + 1, val + tot + 1, y[i]) - val;
	}
	for (int i = 1; i <= q; ++i) {
		if (opt[i] == 1) {
			set.insert(x[i]), weight[x[i]] = y[i];
			int pre = prev(x[i]), nxt = next(x[i]);
			if (nxt > x[i]) modify(x[i], nxt - 1, (LL) (val[x[i]] - val[pre]) * weight[pre]);
			modify(nxt, tot, (LL) (val[nxt] - val[x[i]]) * (weight[x[i]] - weight[pre]));
		} else if (opt[i] == 2) {
			int pre = prev(x[i]), nxt = next(x[i]);
			set.erase(x[i]);
			if (nxt > x[i]) modify(x[i], nxt - 1, (LL) -(val[x[i]] - val[pre]) * weight[pre]);
			modify(nxt, tot, (LL) -(val[nxt] - val[x[i]]) * (weight[x[i]] - weight[pre]));
		} else {
			if (z[i] == 0) {std::cout << val[x[i]] << '\n'; continue; }
			std::set<int>::iterator it = set.lower_bound(x[i]);
			if (it == set.end() || *it > y[i]) {std::cout << "-1\n"; continue; }
			x[i] = *it, z[i] = query(x[i]) - z[i];
			bool m = 0, M = 0;
			int q = find(x[i], z[i], m, M);
			if (q == -1) {std::cout << "-1\n"; continue; }
			int lst = prev(q); z[i] -= query(lst);
			if (weight[lst] > 0) {
				if (z[i] > (LL) (val[y[i]] - val[lst]) * weight[lst]) {std::cout << "-1\n"; continue; }
			} else {
				if (z[i] < (LL) (val[y[i]] - val[lst]) * weight[lst]) {std::cout << "-1\n"; continue; }
			}
			std::cout << std::fixed << std::setprecision(10) << val[lst] + (double)z[i] / weight[lst] << '\n';
		}
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

int q;

struct item {
	int key, prior;
	long long tot;
	long long rate;
	long long low;
	long long sum;
	item * l, * r;
	item () {}
	item (int key, int prior): key (key), prior (prior), tot(0), rate(0), low(0), sum(0), l (NULL), r (NULL) {}
};
typedef item * pitem;

long long sum(pitem t) {
	return t? t->sum : 0ll;
}
long long low(pitem t) {
	return t? t->low : (long long)1e9;
}
void upd_cnt (pitem t) {
	if (t) {
		t->sum = t->tot + sum(t->l) + sum(t->r);
		t->low = min(low(t->l), sum(t->l) + t->tot);
		t->low = min(t->low, sum(t->l) + t->tot + low(t->r));
	}
}

void split (pitem t, int key, pitem & l, pitem & r) {
	if (! t)
		l = r = NULL;
	else if (key <=t-> key)
		split (t-> l, key, l, t-> l), r = t;
	else
		split (t-> r, key, t-> r, r), l = t;

	upd_cnt(t);
}

void merge (pitem & t, pitem l, pitem r) {
	if (! l ||! r)
		t = l? l: r;
	else if (l-> prior> r-> prior)
		merge (l-> r, l-> r, r), t = l;
	else
		merge (r-> l, l, r-> l), t = r;

	upd_cnt(t);
}

pitem root;

pitem find_small(pitem v) {
	if (!v) {
		return NULL;
	}

	if (v->l != NULL) {
		return find_small(v->l);
	}

	return v;
}
pitem find_large(pitem v, long long t) {
	if (!v) {
		return NULL;
	}

	if (v->r != NULL) {
		pitem res = find_large(v->r, t);
		upd_cnt(v);
		return res;
	}

	v->tot = 1ll * (t - v->key) * v->rate;
	upd_cnt(v);
	return v;
}

pitem find_large(pitem v) {
	if (!v) {
		return NULL;
	}

	if (v->r != NULL) {
		pitem res = find_large(v->r);
		return res;
	}

	return v;
}
void output (pitem t) {
	if (! t) return;
	output (t-> l);
	printf ("key=%d tot=%lld", t-> key, t->tot);
	output (t-> r);
}
int main() {
	cin >> q;

	for (int i = 0; i < q; i++) {
		int ope;
		scanf("%d", &ope);

		if (ope == 1) {
			int s, t;
			scanf("%d %d", &t, &s);

			pitem l, r;
			split(root, t, l, r);

			pitem v = new item(t, rand());
			v->rate = s;

			if (r == NULL) {
				v->tot = 1ll * ((long long)2e9) * s;
			} else {
				v->tot = 1ll * (find_small(r)->key - t) * s;
			}

			v->low = v->tot;
			v->sum = v->tot;

			if (l != NULL) {
				find_large(l, t);
			}

			merge(root, l, v);
			merge(root, root, r);
		} else if (ope == 2) {
			int t;
			scanf("%d", &t);

			pitem l, mid, r;
			split(root, t, l, mid);
			split(mid, t + 1, mid, r);

			if (r == NULL) {
				find_large(l, (long long)2e9);
			} else {
				find_large(l, find_small(r)->key);
			}

			merge(root, l, r);
		} else {
			int l, r, v;
			scanf("%d %d %d", &l, &r, &v);

			if (v == 0) {
				printf("%d\n", l);
				continue;
			}

			pitem L, mid, R;
			split(root, l, L, mid);
			split(mid, r, mid, R);

			if (mid != NULL) {
				int lb = l - 1, ub = r;

				while (ub - lb > 1) {
					int Mid = (ub + lb) >> 1;

					pitem temp;
					split(mid, Mid + 1, temp, mid);

					bool good;

					if (1ll * v + low(temp) > 0) {
						good = false;
					} else {
						good = true;
					}
					merge(mid, temp, mid);

					if (good) ub = Mid;
					else lb = Mid;
				}

				if (ub == r) {
					puts("-1");
				} else {
					double res = 0.;
					double cur = v;

					pitem temp;
					split(mid, ub + 1, temp, mid);

					pitem highest = find_large(temp);
					pitem LEFT;

					split(temp, highest->key, LEFT, temp);

					cur += sum(LEFT);

					if (1ll * v + (sum(LEFT) + 1ll * (r - temp->key) * temp->rate) > 0) {
						puts("-1");
					} else {
						res = 1. * temp->key + -1. * cur / temp->rate;
						printf("%.10lf\n", res);
					}

					merge(temp, LEFT, temp);
					merge(mid, temp, mid);
				}
			} else {
				puts("-1");
			}

			merge(root, L, mid);
			merge(root, root, R);
		}
	}
}

#include <bits/stdc++.h>
#define int long long
#define iter map <int, int>::iterator
using namespace std;
const int sz=1e5+10, inf=2e9;
int dot[sz*4], add[sz*4], val[sz];
void push(int nu)
{
    add[nu*2]+=add[nu];
    add[nu*2+1]+=add[nu];
    add[nu]=0;
}
void recalc(int nu)
{
    dot[nu]=min(dot[nu*2]+add[nu*2], dot[nu*2+1]+add[nu*2+1]);
}
int lg, rg, va;
void cha(int nu, int l, int r)
{
    if(l>=lg and r<=rg)
    {
        add[nu]+=va;
    }
    else if(!(l>rg or r<lg))
    {
        push(nu);
        int mid=(l+r)>>1;
        cha(nu*2, l, mid);
        cha(nu*2+1, mid+1, r);
        recalc(nu);
    }
}
int p;
int que(int nu, int l, int r)
{
    if(l==r) return dot[nu]+add[nu];
    else
    {
        push(nu);
        int mid=(l+r)>>1, re;
        if(p<=mid) re=que(nu*2, l, mid);
        else re=que(nu*2+1, mid+1, r);
        recalc(nu);
        return re;
    }
}
int que2(int nu, int l, int r)
{
    if(l>=lg and r<=rg)
    {
        if(dot[nu]+add[nu]<=va)
        {
            if(l==r) return l;
            else
            {
                push(nu);
                int mid=(l+r)>>1, re;
                if(dot[nu*2]+add[nu*2]<=va) re=que2(nu*2, l, mid);
                else re=que2(nu*2+1, mid+1, r);
                recalc(nu);
                return re;
            }
        }
        else return -1;
    }
    else if(l>rg or r<lg) return -1;
    else
    {
        push(nu);
        int mid=(l+r)>>1, re;
        re=que2(nu*2, l, mid);
        if(re==-1) re=que2(nu*2+1, mid+1, r);
        recalc(nu);
        return re;
    }
}
main()
{
    //freopen("input.txt", "r", stdin);
    int q;
    cin>>q;
    map <int, int> ma;
    int zap[q][4];
    for(int a=0; a<q; a++)
    {
        scanf("%lld", &zap[a][0]);
        if(zap[a][0]==1)
        {
            scanf("%lld%lld", &zap[a][1], &zap[a][2]);
            ma[zap[a][1]]=0;
        }
        else if(zap[a][0]==2) scanf("%lld", &zap[a][1]);
        else scanf("%lld%lld%lld", &zap[a][1], &zap[a][2], &zap[a][3]);
    }
    ma[0]=0, ma[inf]=0;
    int n=0;
    for(auto it=ma.begin(); it!=ma.end(); it++)
    {
        val[n]=(*it).first;
        (*it).second=n, n++;
    }
    map <int, int> se;
    se[0]=0, se[inf]=0;
    for(int a=0; a<q; a++)
    {
        int ty=zap[a][0];
        if(ty==1)
        {
            int t=zap[a][1], s=zap[a][2];
            iter it=se.lower_bound(t);
            int nt=(*it).first;
            it--;
            int pt=(*it).first, ps=(*it).second;

            lg=ma[t], rg=ma[nt]-1, va=(t-pt)*ps;
            cha(1, 0, n-1);

            lg=ma[nt], rg=n-1, va=(nt-t)*(s-ps);
            cha(1, 0, n-1);

            se[t]=s;
        }
        else if(ty==2)
        {
            int t=zap[a][1];
            iter it=se.find(t);
            int s=(*it).second;
            it++;
            int nt=(*it).first;
            it--, it--;
            int pt=(*it).first, ps=(*it).second;

            lg=ma[t], rg=ma[nt]-1, va=-(t-pt)*ps;
            cha(1, 0, n-1);

            lg=ma[nt], rg=n-1, va=-(nt-t)*(s-ps);
            cha(1, 0, n-1);

            se.erase(t);
        }
        else
        {
            int l=zap[a][1], r=zap[a][2], v=zap[a][3];
            if(v)
            {
                iter itl=se.lower_bound(l), itr=se.upper_bound(r);
                if(itl!=itr)
                {
                    int lp=(*itl).first, rp=(*itr).first;

                    p=ma[lp];
                    int x=que(1, 0, n-1);

                    lg=ma[lp], rg=ma[rp]-1, va=x-v;
                    int re=que2(1, 0, n-1);

                    if(re==-1) re=rg;
                    else re--;

                    iter it=se.upper_bound(val[re]);
                    it--;
                    int t=(*it).first, s=(*it).second;

                    p=re;
                    int pva=que(1, 0, n-1);

                    if(pva+(r-t)*s<=x-v)
                    {
                        double an=t+(pva-(x-v))/(-1.0*s);
                        printf("%.10f\n", an);
                    }
                    else printf("-1\n");
                }
                else printf("-1\n");
            }
            else printf("%lld\n", l);
        }
    }
}

/*input
5
1 1 1
1 3 -1
1 5 1
1 7 -1
3 1 100 8

*/

#include <iostream>
#include <cassert>
#include <tuple>
#include <vector>
#include <algorithm>
#include <iomanip>

using namespace std;
const int INF = 1e9 + 8;
const int MAXN = 100007;

// #define LOCAL
#define endl '\n'

#define deb err_stream()
struct err_stream
{
	template<typename T>
	err_stream& operator<< (T x)
	{
		#ifdef LOCAL
		cout << x;
		cout << flush;
		#endif
		return *this;
	}
};

using Query = tuple<int, int, int, int>;
int Q;
vector<Query> queries;
vector<int> vec;

struct Node
{
	int l, r, p0;
	int64_t v0, v1, mn, en;
	bool lf;

	Node(int _l = -1, int _r = -1, int _p0 = -1, int64_t _v0 = 0, int64_t _v1 = 0, int64_t _mn = 0, int64_t _en = 0, bool _lf = true):
		l(_l), r(_r), p0(_p0), v0(_v0), v1(_v1), mn(_mn), en(_en), lf(_lf) {}

	void set_event(int64_t x)
	{
		assert(lf);
		deb << "set " << l << ' ' << r << ": " << x << " " << mn << endl;
		p0 = l, v0 = v1 = x, mn = min(0ll, en = x * (r - l));
	}

	void rem_event()
	{
		assert(lf);
		deb << "rem " << l << ' ' << r << endl;
		p0 = -1, v0 = v1 = 0, mn = en = 0;
	}

	int64_t get_mn(int64_t v)
	{
		return min(0ll, (~p0 ? v * (p0 - l) + mn : v * (r - l)));
	}

	int64_t get_en(int64_t v)
	{
		return (~p0 ? v * (p0 - l) + en : v * (r - l));
	}

	friend Node operator+ (Node x, Node y)
	{
		assert(x.r == y.l);
		return Node(
			x.l,
			y.r,
			(~x.p0 ? x.p0 : y.p0),
			(~x.p0 ? x.v0 : y.v0),
			(~y.p0 ? y.v1 : x.v1),
			min(x.mn, x.en + y.get_mn(x.v1)),
			x.en + y.get_en(x.v1),
			false
		);
	}
} it[MAXN << 2];

void set_event(int t, int s, int rt = 1)
{
	auto &nd = it[rt];
	if (nd.lf) return nd.set_event(s);

	int m = it[rt << 1].r;
	if (t < m) set_event(t, s, rt << 1);
	else set_event(t, s, rt << 1 | 1);
	it[rt] = it[rt << 1] + it[rt << 1 | 1];
}

void rem_event(int t, int rt = 1)
{
	auto &nd = it[rt];
	if (nd.lf) return nd.rem_event();

	int m = it[rt << 1].r;
	if (t < m) rem_event(t, rt << 1);
	else rem_event(t, rt << 1 | 1);
	it[rt] = it[rt << 1] + it[rt << 1 | 1];
}

bool trav(int l, int r, int64_t &x, int64_t &v, int rt, long double &ans)
{
	auto &nd = it[rt];
	deb << l << ' ' << r << ": " << rt << ' ' << nd.l << ' ' << nd.r << ' ' << x << ' ' << v << ": " << nd.get_mn(v) << ", " << nd.p0 << endl;

	if (r <= nd.l || nd.r <= l) return 0;
	if (l <= nd.l && nd.r <= r && x + nd.get_mn(v) > 0) return x += nd.get_en(v), v = (~nd.p0 ? nd.v1 : v), 0;
	if (nd.lf) {
		if (nd.l < l) return 0;
		v = (~nd.p0 ? nd.v0 : v);
		deb << "T " << x + (min(r, nd.r) - nd.l) * v << endl;
		if (x + (min(r, nd.r) - nd.l) * v <= 0) return ans = (long double) (nd.l * v - x) / v, 1;
		return x += (min(r, nd.r) - nd.l) * v, 0;
	}

	if (trav(l, r, x, v, rt << 1, ans)) return 1;
	if (trav(l, r, x, v, rt << 1 | 1, ans)) return 1;
	return 0;
}

long double get(int l, int r, int64_t x)
{
	if (x == 0) return l;
	int64_t v = 0;
	long double ans;
	if (trav(l, r, x, v, 1, ans)) return ans;
	deb << "get " << l << ' ' << r << ": " << x << ' ' << v << endl;
	return -1;
}

void build(int rt = 1, int lo = 0, int hi = (int) vec.size() - 2)
{
	if (lo == hi) {
		it[rt] = Node(vec[lo], vec[lo + 1]);
		return;
	}

	int mid = (lo + hi) >> 1;
	build(rt << 1, lo, mid);
	build(rt << 1 | 1, mid + 1, hi);
	it[rt] = it[rt << 1] + it[rt << 1 | 1];
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> Q;
	queries.resize(Q);
	vec.reserve(Q + 2);

	for (auto &q : queries) {
		int k, t, s, l, r, v;
		cin >> k;
		if (k == 1) {
			cin >> t >> s;
			vec.push_back(t);
			q = make_tuple(k, t, s, 0);
		} else if (k == 2) {
			cin >> t;
			q = make_tuple(k, t, 0, 0);
		} else {
			cin >> l >> r >> v;
			q = make_tuple(k, l, r, v);
		}
	}

	for (int i = 0; i <= 10; ++i) vec.push_back(i);
	vec.push_back(INF);
	vec.push_back(INF + 1);
	sort(vec.begin(), vec.end());
	vec.erase(unique(vec.begin(), vec.end()), vec.end());

	build();
	cout << fixed << setprecision(10);
	for (auto &q : queries) {
		if (get<0>(q) == 1) {
			set_event(get<1>(q), get<2>(q));
		} else if (get<0>(q) == 2) {
			rem_event(get<1>(q));
		} else {
			long double ans = get(get<1>(q), get<2>(q), get<3>(q));
			if (ans < 0) cout << -1 << '\n';
			else cout << ans << '\n';
		}
	}
}

#undef NDEBUG
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

struct IdGen {
	map<int, int> mp;
	vector<int> lazy;

	void insert(int x) {
		assert(mp.empty());
		lazy.push_back(x);
	}
	void process() {
		assert(mp.empty());
		sort(lazy.begin(), lazy.end());
		lazy.erase(unique(lazy.begin(), lazy.end()), lazy.end());
		for (int i = 0; i < (int) lazy.size(); ++i)
			mp[lazy[i]] = i;
		lazy.clear();
	}
	int getId(int x) const {
		assert(lazy.empty());
		return mp.at(x);
	}
	int size() const {
		assert(lazy.empty());
		return mp.size();
	}
} idGen;

template<class V> struct SegTree {
	int n;
	vector<V> st;
	vector<int> leaves;

	SegTree(const int n) :
			n(n) {
		leaves.resize(n);
		init(1, 0, n - 1);
	}

	void init(const int si, const int lo, const int hi) { // init st[] and leaves[]
		if (lo == hi) {
			if (si >= (int) st.size())
				st.resize(si + 1);
			st[si] = V(); // optional if V(V(), V()) = V() ---- | ---- cin >> ??
			leaves[lo] = si;
		} else {
			const int mid = (lo + hi) >> 1;
			init(si << 1, lo, mid);
			init(si << 1 | 1, mid + 1, hi);
			st[si] = V(st[si << 1], st[si << 1 | 1]); // optional if T(T(), T()) = T()
		}
	}

	V query(const int l, const int r) {
		return (l <= r && l < n && r >= 0) ? query(l, r, 1, 0, n - 1) : V();
	}
	V query(const int l, const int r, const int si, const int lo, const int hi) {
		if (l <= lo && hi <= r)
			return st[si];

		const int mid = (lo + hi) >> 1;
		if (r <= mid)
			return query(l, r, si << 1, lo, mid);
		if (mid < l)
			return query(l, r, si << 1 | 1, mid + 1, hi);
		return V(query(l, r, si << 1, lo, mid), query(l, r, si << 1 | 1, mid + 1, hi));
	}

	void update(const int i, V v) {
		// cerr << "update " << i << ' ' << v.empty << ' ' << v.t1 << ' ' << v.s2 << endl;
		int si = leaves[i];
		st[si] = v;
		for (si >>= 1; si; si >>= 1)
			st[si] = V(st[si << 1], st[si << 1 | 1]);
	}

};

struct StVal { // define
	bool empty = true;
	ll t1 = 0, t2 = 0, s2 = 0;
	ll mn = 0, diff = 0;

	StVal() {
	}
	StVal(const ll t, const ll s) :
			empty(false), t1(t), t2(t), s2(s) {
	}

	StVal(const bool empty) :
			empty(empty) {
		assert(empty == true);
	}

	StVal(const StVal &v1, const StVal &v2) {
		if (v1.empty || v2.empty) {
			*this = v1.empty ? v2 : v1;
			return;
		}
		const ll midDiff = v1.s2 * (v2.t1 - v1.t2);
		diff = v1.diff + midDiff + v2.diff;
		mn = min(v1.mn, v1.diff + midDiff + v2.mn);
		t1 = v1.t1;
		t2 = v2.t2;
		s2 = v2.s2;
		empty = false;
	}
};

typedef SegTree<StVal> MyST;

struct Query {
	ll type, t, s, l, r, v;
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cout << fixed << setprecision(10);

	vector<Query> queries;

	{
		int Q;
		cin >> Q;
		queries.resize(Q);
	}

	for (Query &query : queries) {
		cin >> query.type;
		if (query.type == 1)
			cin >> query.t >> query.s;
		else if (query.type == 2)
			cin >> query.t;
		else if (query.type == 3)
			cin >> query.l >> query.r >> query.v;
		else
			assert(0);
	}

	for (const Query &query : queries)
		if (query.type == 1) {
			idGen.insert(query.t);
		}

	const int LastStEntry = (int) 1e9 + 9;

	idGen.insert(0);
	idGen.insert(LastStEntry);
	idGen.process();

	MyST st(idGen.size());
	st.update(idGen.getId(0), StVal(0, 0));
	st.update(idGen.getId(LastStEntry), StVal(LastStEntry, 0));

	for (const Query &query : queries) {
		if (query.type == 1) {
			st.update(idGen.getId(query.t), StVal(query.t, query.s));
		} else if (query.type == 2)
			st.update(idGen.getId(query.t), StVal(true));
		else {
			assert(query.type == 3);
			ll l = query.l;
			const ll r = query.r;
			const ll v = query.v;
			if (v == 0) {
				cout << l << '\n';
				continue;
			}
			const int lIdx = idGen.mp.lower_bound(l)->second;
			int lo = lIdx;
			int hi = st.n;
			while (lo < hi) {
				const int mid = (lo + hi) / 2;
				if (st.query(lIdx, mid).mn + v <= 0) {
					hi = mid;
				} else
					lo = mid + 1;
			}
			if (lo == st.n) {
				cout << -1 << '\n';
				// cerr << "case 1 " << endl;
				continue;
			}
			const StVal stVal = st.query(lIdx, lo - 1);
			if (stVal.empty) {
				cout << -1 << '\n';
				// cerr << "case 2 " << endl;
				continue;
			}
			const ll f_t2 = v + stVal.diff;
			assert(f_t2 > 0);
			if (stVal.s2 >= 0) {
				cout << -1 << '\n';
				// cerr << "case 3 " << endl;
				continue;
			}
			const long double x = -(long double) (f_t2) / stVal.s2;
			const long double ans = stVal.t2 + x;
			if (ans > r) {
				cout << -1 << '\n';
				// cerr << "case 4 " << ' ' << ans << endl;
				continue;
			}
			cout << ans << '\n';

		}
	}
	return 0;
}

#include <stdio.h>
#include <map>

#define DEBUG 0
#define minn(a,b) (a<=b?a:b)
#define maxx(a,b) (a>=b?a:b)
const int INF=0x7fffffff;

struct seg{
    int a,b;            // [a,b)
    long long add;      // amount of flow added
    long long min;      // minimum reached, if starting at 0
    long long prop;     // does nothing when it's equal to INF
    seg *s1,*s2;
};

seg *root=new seg{0,0x7ffffffe,0,0,0,nullptr,nullptr};

void segprop(seg *s)
{
    if (s->b-s->a==1) return;
    if (s->prop==INF) return;
    if (s->s1==nullptr) {
        int mid=s->a+(s->b-s->a)/2;
        s->s1=new seg{s->a,mid,0,0,INF,nullptr,nullptr};
        s->s2=new seg{mid,s->b,0,0,INF,nullptr,nullptr};
    }
    s->s1->add=(s->prop)*(s->s1->b-s->s1->a);
    s->s1->min=minn(0,s->s1->add);
    s->s2->add=(s->prop)*(s->s2->b-s->s2->a);
    s->s2->min=minn(0,s->s2->add);
    s->s1->prop=s->s2->prop=s->prop;
    s->prop=INF;
}

void paint(seg *s,int a,int b,int v)
{
    segprop(s);
    //if (DEBUG) printf("paint seg [%d %d)\n",s->a,s->b);
    // paint [a,b) with v
    if (s->b<=a || b<=s->a) return;
    if (a<=s->a && s->b<=b) {
        //if (DEBUG) printf("paint seg [%d %d) with %d\n",s->a,s->b,v);
        s->add=v*1LL*(s->b-s->a);           // stupid
        s->min=minn(0,s->add);
        s->prop=v;
        return;
    }
    // do subranges
    paint(s->s1,a,b,v);
    paint(s->s2,a,b,v);
    s->add=s->s1->add+s->s2->add;
    long long t1=s->s1->min;                // stupid
    long long t2=s->s1->add+s->s2->min;     // stupid
    s->min=minn(t1,t2);
    s->prop=INF;
}

long long remain;
double ans;
// state = 0, continue reading ranges
// state = 1, done and found
// state = 2, nothing found (because doubles can't handle 10^9 + 10^-9)
int state;
void getans(seg *s,int a,int b)
{
    //if (DEBUG) printf("getans [%d %d)\n",s->a,s->b);
    segprop(s);
    if (s->b<=a || b<=s->a) return;
    if (a<=s->a && s->b<=b) {
        //if (DEBUG) printf("getans [%d %d) init %I64d\n",s->a,s->b,remain);
        //if (DEBUG) printf("node has %I64d %I64d %I64d\n",s->add,s->min,s->prop);
        if (remain+s->min<=0) {
            if (s->b-s->a==1) {
                //if (DEBUG) printf("done %d init %I64d\n",s->a,remain);
                ans=s->a-remain/1.0/s->prop;
                state=1;
                remain=0;
            }
            else {
                getans(s->s1,a,b);
                if (!state) getans(s->s2,a,b);
            }
        }
        else {
            remain+=s->add;
        }
        return;
    }
    getans(s->s1,a,b);
    if (!state) getans(s->s2,a,b);
}

void printseg(seg *s)
{
    if (s==nullptr) return;
    if (s->a>20) return;
    segprop(s);
    printseg(s->s1);
    printseg(s->s2);
    printf("[%d %d) has %I64d %I64d %I64d\n",s->a,s->b,s->add,s->min,s->prop);
}

std::map<int,int> flow;
std::map<int,int>::iterator it;

int q;
int q1,q2,q3;

int main()
{
    #ifdef NOT_DMOJ
    freopen("data.txt","r",stdin);
    #endif // NOT_DMOJ
    scanf("%d",&q);
    flow[0]=0;
    flow[0x7ffffffd]=0;
    while (q--) {
        scanf("%d",&q1);
        if (q1==1) {
            scanf("%d%d",&q1,&q2);
            it=flow.lower_bound(q1);
            if (DEBUG) printf("paint %d %d %d\n\n",q1,it->first,q2);
            paint(root,q1,it->first,q2);
            flow[q1]=q2;
        }
        else if (q1==2) {
            scanf("%d",&q1);
            flow.erase(q1);
            it=flow.lower_bound(q1);
            q2=it->first;
            --it;
            if (DEBUG) printf("paint %d %d %d\n\n",it->first,q2,it->second);
            paint(root,it->first,q2,it->second);
        }
        else {
            scanf("%d%d%d",&q1,&q2,&q3);
            if (q3==0) {
                // so very bad
                printf("%d\n",q1);
                continue;
            }
            // so very bad #2
            q1=flow.lower_bound(q1)->first;
            if (q1>=q2) {
                printf("-1\n");
                continue;
            }
            remain=q3;
            state=0;
            getans(root,q1,q2);
            if (remain>0 || state==2) printf("-1\n");
            else printf("%.9f\n",ans);
        }
    }
    //printseg(root);
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <random>
#include <climits>
#include <iomanip>
#include <queue>
#include <bitset>
#include <cctype>

using namespace std;

#define forn(i,n) for (int i = 0;i < int(n);i++)
#define ford(i,n) for (int i = n-1;i >=0;i--)
#define fore(i,l,r) for (int i = int(l);i < int(r);i++)
#define forv(a) for(int i = 0;i < (a).size();i++) cin >> a[i]
#define correct(x,n) (((x) >= 0) && ((x) < n))
#define sort_all(a) sort((a).begin(),(a).end())
#define mp(a,b) make_pair((a),(b))
#define all(a) (a).begin(),(a).end()
#define pb(a) push_back(a)
#define rnd() (rand() + (RAND_MAX+1)*rand())
#define fi first
#define se second
#define V(A) vector<A>
//#define DEBUG_

//#define x first
//#define y second

typedef long long li;
typedef vector<int> vi;
typedef vector<li> vli;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<vi> vvi;
typedef vector<vli> vvli;
typedef long double ld;
typedef pair<li, li> Point;

const ld EPS = 1e-9;

class Node
{
public:
	li key,pr,s;
	li mn, mx, smx,d,dmn;//Min t,max t, s of max t,d,and minimum of d in subtree
	Node* l, *r;
	Node() {}

	Node(li key, li s) : key(key), s(s), mn(key), pr(rnd()), mx(key), smx(s),d(0),dmn(0),l(nullptr),r(nullptr) {}
};

typedef Node* DTree;

li getMin(DTree t)
{
	if (!t)
		return 1500000000;
	return t->mn;
}

li getMax(DTree t)
{
	if (!t)
		return 0;
	return t->mx;
}

li getSMax(DTree t)
{
	if (!t)
		return 0;
	return t->smx;
}

li getD(DTree t)
{
	if (!t)
		return 0;
	return t->d;
}

li getDMin(DTree t)
{
	if (!t)
		return 0;
	return t->dmn;
}

void update(DTree t)
{
	if (!t)
		return;

	t->mn = min(t->key, getMin(t->l));
	t->mx = max(t->key, getMax(t->r));

	if (t->key > getMax(t->r))
		t->smx = t->s;
	else
		t->smx = getSMax(t->r);

	li d = 0, dmn = 0;
	dmn = min(dmn, getDMin(t->l));
	d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	dmn = min(dmn, d);
	d += (t->r ? t->s*(getMin(t->r) - t->key) : 0);
	dmn = min(dmn, d + getDMin(t->r));
	d += getD(t->r);
	dmn = min(dmn, d);
	t->d = d;
	t->dmn = dmn;
}

void split(DTree t, DTree &l, DTree &r,li key)
{
	if (!t)
	{
		l = r = nullptr;
		return;
	}
	if (key < t->key)
		split(t->l, l, t->l, key), r = t;
	else
		split(t->r, t->r, r, key), l = t;
	update(t);
}

void merge(DTree &t, DTree l, DTree r)
{
	if (!l || !r)
	{
		t = (l ? l : r);
		return;
	}
	if (l->pr > r->pr)
		merge(l->r, l->r, r), t = l;
	else
		merge(r->l, l, r->l), t = r;
	update(t);
}

void insert(DTree &t,li key,li s)
{
	DTree tl, tm = new Node(key, s), tr;
	split(t, tl, tr, key);
	merge(t, tl, tm);
	merge(t, t, tr);
}

void erase(DTree &t, li key)
{
	DTree tl, tm, tr;
	split(t, tl, tm, key-1);
	split(tm, tm, tr, key);
	merge(t, tl, tr);
}

double getAns(DTree t,li r,li v)
{
	if (!t)
		return -1;

	if (t->dmn + v > 0)
		return (t->smx >= 0 || t->mx * t->smx - (t->d + v) < r * t->smx ? -1 : t->mx - (ld)(t->d + v) / t->smx);

	li dl = getDMin(t->l);
	li d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	li dr = d + (t->r ? t->s*(getMin(t->r) - t->key) : 0);

	if (dl + v <= 0)
		return getAns(t->l, r, v);

	if (d + v <= 0)
		return getMax(t->l) - (ld)(v + getD(t->l)) / getSMax(t->l);

	if (dr + v <= 0)
		return t->key - (ld)(v + d) / t->s;

	return getAns(t->r, r, v + dr);
}

double getAns(DTree t, li l, li r, li v)
{
	if (!v)
		return l;
	DTree tl, tm,tr;
	split(t, tl, tm, l - 1);
	split(tm, tm, tr, r);
	double ans = getAns(tm, r, v);
	merge(t, tl, tm);
	merge(t, t, tr);
	return ans;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	DTree t = nullptr;

	int n;
	cin >> n;
	forn(i, n)
	{
		int q;
		cin >> q;
		if (q == 1)
		{
			li key, s;
			cin >> key >> s;
			insert(t, key, s);
		}
		if (q == 2)
		{
			li key;
			cin >> key;
			erase(t, key);
		}
		if (q == 3)
		{
			li l, r, v;
			cin >> l >> r >> v;
			cout << setprecision(20) << getAns(t, l, r, v) << '\n';
		}
	}
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define N 100005
#define L (d << 1)
#define R (L | 1)
#define M (l + r >> 1)
#define LL long long
#define fi(a, b, c) for(int a = (b); a < (c); a++)
#define FI(a, b, c) for(int a = (b); a <= (c); a++)
#define FD(a, b, c) for(int a = (b); a >= (c); a--)
using namespace std;

int q, type[N], l[N], r[N], v[N], le, slp[N], c[N];
int lazy[1 << 18], cnt[1 << 18];
bool haslazy[1 << 18], isok;
LL s[1 << 18], t[1 << 18], sums, mins;

void push(int d, int l, int r) {
	if (haslazy[d]) {
		s[d] = (LL) (c[r + 1] - c[l]) * lazy[d];
		t[d] = min(0LL, s[d]);
		if(l < r) {
			haslazy[L] = haslazy[R] = 1;
			lazy[L] = lazy[R] = lazy[d];
		}
		haslazy[d] = lazy[d] = 0;
	}
}

int find_last(int d, int l, int r, int id) {
	if (!cnt[d] || id < l) return -1;
	if (l == r) return l;
	if (id > M) {
		int rres = find_last(R, M + 1, r, id);
		if (rres != -1) return rres;
	}
	return find_last(L, l, M, id);
}

int find_next(int d, int l, int r, int id) {
	if (!cnt[d] || id > r) return -1;
	if (l == r) return l;
	if (id <= M) {
		int lres = find_next(L, l, M, id);
		if (lres != -1) return lres;
	}
	return find_next(R, M + 1, r, id);
}

void update_cnt(int d, int l, int r, int id, int val) {
	cnt[d] += val;
	if (l == r) return;
	if (id <= M) update_cnt(L, l, M, id, val);
	else update_cnt(R, M + 1, r, id, val);
}

void update(int d, int l, int r, int a, int b, int val) {
	if (a <= l && b >= r) {
		haslazy[d] = 1;
		lazy[d] = val;
		return;
	}

	push(d, l, r);
	if (a <= M) update(L, l, M, a, b, val);
	if (b > M) update(R, M + 1, r, a, b, val);
	push(L, l, M);
	push(R, M + 1, r);
	s[d] = s[L] + s[R];
	t[d] = min(t[L], s[L] + t[R]);
}

void get(int d, int l, int r, int a, int b, int val) {
	if (isok) return;
	push(d, l, r);
	if (a <= l && b >= r) {
		mins = min(mins, sums + t[d]);
		sums += s[d];
		if (mins <= val) isok = 1;
		return;
	}
	if (a <= M) get(L, l, M, a, b, val);
	if (b > M) get(R, M + 1, r, a, b, val);
}

bool query(int a, int b, int val) {
	sums = mins = isok = 0;

	get(1, 0, le - 1, a, b, val);

	return isok;
}

LL getsum(int d, int l, int r, int a, int b) {
	if (a <= l && b >= r) return s[d];
	LL sum = 0;
	if (a <= M) sum += getsum(L, l, M, a, b);
	if (b > M) sum += getsum(R, M + 1, r, a, b);
	return sum;
}

int main(){
	scanf("%d", &q);
	fi(i, 0, q) {
		scanf("%d %d", &type[i], &l[i]);
		if (type[i] == 1 || type[i] == 3) scanf("%d", &r[i]);
		if (type[i] == 3) scanf("%d", &v[i]);

		if (type[i] <= 2) c[le++] = l[i];
	}

	sort(c, c + le);
	le = unique(c, c + le) - c;
	c[le] = 1.1e9;

//	fi(i, 0, le) printf("d %d %d\n", i, c[i]);

	fi(i, 0, q) {
		int ld = lower_bound(c, c + le, l[i]) - c;
		if (type[i] == 1) {
			slp[ld] = r[i];
			int nxt = find_next(1, 0, le - 1, ld + 1);
			if (nxt == -1) nxt = le;
			update(1, 0, le - 1, ld, nxt - 1, r[i]);
			update_cnt(1, 0, le - 1, ld, 1);
		} else if (type[i] == 2) {
			int lst = find_last(1, 0, le - 1, ld - 1);
			int nxt = find_next(1, 0, le - 1, ld + 1);
			if (nxt == -1) nxt = le;
			int val = lst == -1 ? 0 : slp[lst];
			update(1, 0, le - 1, ld, nxt - 1, val);
			update_cnt(1, 0, le - 1, ld, -1);
		} else {
			if (v[i] == 0) {
				printf("%d\n", l[i]);
				continue;
			}
			int nxt = find_next(1, 0, le - 1, ld);
			int rd = lower_bound(c, c + le, r[i]) - c;
			if (nxt == -1 || nxt >= rd) {
				puts("-1");
				continue;
			}
		//	printf("rd %d\n", rd);//

			bool ok = 0;
			int from = nxt;
			while(nxt < rd) {
				int mid = nxt + rd >> 1;
				if (query(from, mid, -v[i])) {
					rd = mid;
					ok = 1;
				} else nxt = mid + 1;
			}

			if (ok) {
				LL sum = from == rd ? 0 : getsum(1, 0, le - 1, from, rd - 1);
				int lst = find_last(1, 0, le - 1, rd);
		//		printf("ok %d %I64d %d\n", rd, sum, lst);
				double ans = ((double) v[i] + sum) / -slp[lst] + c[rd];
				if (ans - 1e-9 < r[i]) printf("%.6lf\n", ans);
				else puts("-1");
			} else puts("-1");
		}
	}
}

#include <bits/stdc++.h>

#define x first
#define y second
#define pii pair<ll, ll>
#define ll long long
#define ld long double

using namespace std;

ld EPS = 1e-8;

const ll NMAX = 111111;
const ll inf = 2e9;
const ll M = 1e9 + 7;

struct vertex
{
	ll y;
	ll t, s;
	vertex * l, *r;
	ll tl, tr;
	ll res, mn;
	ll sr;
} g[NMAX];

vertex * ls = g + 1;

vertex * nver(ll t, ll s)
{
	ls -> y = rand() | (rand() << 15);
	ls -> t = t;
	ls -> s = s;
	ls -> l = g;
	ls -> r = g;
	ls -> tl = t;
	ls -> tr = t;
	ls -> sr = s;
	ls -> res = 0;
	ls -> mn = 0;
	return ls++;
}

void update(vertex * v)
{
	if (v == g)
		return;
	v -> res = 0;
	v -> mn = 0;
	ll cur = 0;
	if (v -> l != g)
	{
		v -> res += v -> l -> res;
		v -> res += (v -> t - v -> l -> tr) * v -> l -> sr;
		cur += v -> res;
		v -> tl = v -> l -> tl;
		v -> mn = min(v -> mn, min(v -> l -> mn, cur));
	}
	else
	{
		v -> tl = v -> t;
	}
	if (v -> r != g)
	{
		cur += (v -> r -> tl - v -> t) * v -> s;
		v -> mn = min(v -> mn, v -> r -> mn + cur);
		v -> res += v -> r -> res;
		v -> res += (v -> r -> tl - v -> t) * v -> s;
		v -> tr = v -> r -> tr;
		v -> sr = v -> r -> sr;
	}
	else
	{
		v -> tr = v -> t;
		v -> sr = v -> s;
	}
	return;
}

vertex * merge(vertex * l, vertex * r)
{
	if (l == g)
		return r;
	if (r == g)
		return l;
	if (l -> y < r -> y)
	{
		r -> l = merge(l, r -> l);
		update(r);
		return r;
	}
	l -> r = merge(l -> r, r);
	update(l);
	return l;
}

pair<vertex *, vertex *> split(vertex * t, ll x)
{
	if (t == g)
		return {g, g};
	if (t -> t < x)
	{
		auto w = split(t -> r, x);
		t -> r = w.first;
		update(t);
		return {t, w.second};
	}
	else
	{
		auto w = split(t -> l, x);
		t -> l = w.second;
		update(t);
		return {w.first, t};
	}
}

ld ans(vertex * t, ll v, ll tr)
{
	ll mn = 0;
	ll cur = 0;
	if (t -> l != g)
	{
		cur += (t -> t - t -> l -> tr) * t -> l -> sr + t -> l -> res;
		mn = min(mn, min(t -> l -> mn, cur));
		if (v + mn <= 0)
			return ans(t -> l, v, t -> t);
	}
	if (t -> s < 0)
	{
		ll k = tr;
		if (t -> r != g)
			k = t -> r -> tl;
		if ((v + cur) <= -t -> s * (k - t -> t))
			return t -> t - (ld)(v + cur) / t -> s;
	}
	if (t -> r == g)
	{
		// cout << t -> s << ':';
		// cout << v << ' ';
		return -1;
	}
	return ans(t -> r, v + cur + (t -> s) * (t -> r -> tl - t -> t), tr);
}

void debug(vertex * v)
{
	if (v == g)
		return;
	debug(v -> l);
	cout << v -> y << ' ' << v -> s << ' ' << v -> res << ' ' << v -> mn << endl;
	debug(v -> r);
	return;
}

signed main() {
	cin.sync_with_stdio(0);
	cout.sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout.precision(40);
	ll q;
	cin >> q;
	vertex * t = g;
	for (ll i = 1; i <= q; i++)
	{
		ll w;
		cin >> w;
		if (w == 1)
		{
			ll tm, s;
			cin >> tm >> s;
			auto w = split(t, tm);
			t = merge(w.first, merge(nver(tm, s), w.second));
		}
		else if (w == 2)
		{
			ll tm;
			cin >> tm;
			auto w = split(t, tm);
			auto e = split(w.second, tm + 1);
			t = merge(w.first, e.second);
		}
		else
		{
			ll l, r, v;
			cin >> l >> r >> v;
			// cout << endl;
			// debug(t);
			if (v == 0)
			{
				cout << l << endl;
				continue;
			}
			auto w = split(t, l);
			auto e = split(w.second, r);
			if (e.first == g)
			{
				cout << -1 << endl;
			}
			else
				cout << ans(e.first, v, r) << endl;
			t = merge(w.first, merge(e.first, e.second));
		}
	}
	return 0;
}

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

struct node {
    pair<int, int> f, s;
    node *le, *ri;
    ll mn, res;
    int tl, tr;
    node() {
        mn = 228;
    }
    node(int l, int r) {
        tl = l; tr = r;
        mn = 228;
        if (l == r) return;
        le = new node(l, (l+r)/2);
        ri = new node((l+r)/2+1, r);
    }
    node (node* a, node* b) {
        le = a; ri = b;
        tl = le->tl; tr = ri->tr;
        if (le->mn == 228) {
            res = ri->res;
            mn = ri->mn;
            f = ri->f;
            s = ri->s;
            return;
        }
        if (ri->mn == 228) {
            res = le->res;
            mn = le->mn;
            f = le->f;
            s = le->s;
            return;
        }
        f = le->f; s = ri->s;
        ll del = 1ll*le->s.second*(ri->f.first-le->s.first);
        res = le->res+del+ri->res;
        mn = min(le->mn, le->res+del);
        mn = min(mn, ri->mn+le->res+del);
    }
    void combine() {
        node tmp(le, ri);
        *this = tmp;
    }
    void update(int id, int time, int speed) {
        if (tl == tr) {
            mn = res = 0;
            f.first = s.first = time;
            f.second = s.second = speed;
            return;
        }
        if (id <= (tl+tr)/2)
            le->update(id, time, speed);
        else
            ri->update(id, time, speed);
        combine();
    };
    void del(int id) {
        if (tl == tr) {
            mn = 228;
            return;
        }
        if (id <= (tl+tr)/2)
            le->del(id);
        else
            ri->del(id);
        combine();
    }
    node* get_seg(int l, int r) {
        if (tr < l || r < tl) {
            return new node();
        }
        if (l <= tl && tr <= r) {
            return this;
        }
        return new node(le->get_seg(l, r), ri->get_seg(l, r));
    };
    long double simulate(int r, ll v) {
        if (mn == 228) { return -1; }
        if (v+mn > 0 && v+res+1ll*s.second*(r-s.first) > 0) {
            return -1;
        }
        if (f == s) {
            return s.first - (long double)v/s.second;
        }
        if (le->mn == 228) {
            return ri->simulate(r, v);
        }
        long double to = le->simulate(le->s.first, v);
        if (to != -1) {
            return to;
        }
        v += le->res;
        ll del = 1ll*le->s.second * ((ri->mn == 228? r : ri->f.first)-le->s.first);
        if (v+del <= 0) {
            return le->s.first - (long double)v/le->s.second;
        }
        v += del;
        return ri->simulate(r, v);
    };
    long double query(int l, int r, int rr, ll v) {
        node* t = get_seg(l, r);
        return t->simulate(rr, v);
    };
};
struct query {
    int time, speed, start;
    int l, r, type;
    query() {}
};

vector<int> pos;
vector<query> q;

int main() {
    int qq;
    cout.precision(7);
    cin >> qq;
    q.resize(qq);

    for (int i = 0; i < qq; ++i) {
        cin >> q[i].type;
        if (q[i].type == 1) {
            cin >> q[i].time >> q[i].speed;
            pos.push_back(q[i].time);
        }
        if (q[i].type == 2) {
            cin >> q[i].time;
        }
        if (q[i].type == 3) {
            cin >> q[i].l >> q[i].r >> q[i].start;
        }
    }
    sort(pos.begin(), pos.end());
    pos.erase(unique(pos.begin(), pos.end()), pos.end());
    if (pos.size() == 0) {
        pos.push_back(0);
    }
    node* t = new node(0, pos.size()-1);
    for (int i = 0; i < qq; ++i) {
        if (q[i].type == 1) {
            int id = lower_bound(pos.begin(), pos.end(), q[i].time) - pos.begin();
            t->update(id, q[i].time, q[i].speed);
        }
        if (q[i].type == 2) {
            int id = lower_bound(pos.begin(), pos.end(), q[i].time) - pos.begin();
            t->del(id);
        }
        if (q[i].type == 3) {
            int l = lower_bound(pos.begin(), pos.end(), q[i].l) - pos.begin();
            int r = --upper_bound(pos.begin(), pos.end(), q[i].r) - pos.begin();
            if (q[i].start == 0) {
                cout << fixed << q[i].l << endl;
            } else {
                cout << fixed << t->query(l, r, q[i].r, q[i].start) << endl;
            }
        }
    }

    return 0;
}

#pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2,fma,sse4.1,sse4.2,sse4a,xsave")

#define _CRT_SECURE_NO_WARNINGS
# include <iostream>
# include <cmath>
# include <algorithm>
# include <stdio.h>
# include <cstdint>
# include <cstring>
# include <string>
# include <cstdlib>
# include <vector>
# include <bitset>
# include <map>
# include <queue>
# include <ctime>
# include <stack>
# include <set>
# include <list>
# include <random>
# include <deque>
# include <functional>
# include <iomanip>
# include <sstream>
# include <fstream>
# include <complex>
# include <numeric>
# include <immintrin.h>
# include <cassert>
# include <array>
# include <tuple>
# include <unordered_map>
# include <unordered_set>

//#ifdef LOCAL
//# include <opencv2/core/core.hpp>
//# include <opencv2/highgui/highgui.hpp>
//# include <opencv2/imgproc/imgproc.hpp>
//#endif

using namespace std;

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL_((0,__VA_ARGS__, 6,5,4,3,2,1))
#define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
#define VA_NUM_ARGS_IMPL(_0,_1,_2,_3,_4,_5,_6,N,...) N
#define macro_dispatcher(macro, ...) macro_dispatcher_(macro, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(macro, nargs) macro_dispatcher__(macro, nargs)
#define macro_dispatcher__(macro, nargs) macro_dispatcher___(macro, nargs)
#define macro_dispatcher___(macro, nargs) macro ## nargs
#define DBN1(a)           cerr<<#a<<"="<<(a)<<"\n"
#define DBN2(a,b)         cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"\n"
#define DBN3(a,b,c)       cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"\n"
#define DBN4(a,b,c,d)     cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"\n"
#define DBN5(a,b,c,d,e)   cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"\n"
#define DBN6(a,b,c,d,e,f) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<", "<<#f<<"="<<(f)<<"\n"
#define DBN(...) macro_dispatcher(DBN, __VA_ARGS__)(__VA_ARGS__)
#define DA(a,n) cerr<<#a<<"=["; printarray(a,n); cerr<<"]\n"
#define DAR(a,n,s) cerr<<#a<<"["<<s<<"-"<<n-1<<"]=["; printarray(a,n,s); cerr<<"]\n"

#ifdef _MSC_VER
#define PREFETCH(ptr, rw, level) ((void)0)
#else
#define PREFETCH(ptr, rw, level) __builtin_prefetch(ptr, rw, level)
#endif

#if defined _MSC_VER
#define ASSUME(condition) ((void)0)
#define __restrict
#elif defined __clang__
#define ASSUME(condition)       __builtin_assume(condition)
#elif defined __GNUC__
[[noreturn]] __attribute__((always_inline)) inline void undefinedBehaviour() {}
#define ASSUME(condition)       ((condition) ? true : (undefinedBehaviour(), false))
#endif

#ifdef LOCAL
#define CURTIME() cerr << clock() * 1.0 / CLOCKS_PER_SEC << endl
#else
#define CURTIME()
#endif

typedef long long ll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef int itn;

template<class T1, class T2, class T3>
struct triple{ T1 a; T2 b; T3 c; triple() : a(T1()), b(T2()), c(T3()) {}; triple(T1 _a, T2 _b, T3 _c) :a(_a), b(_b), c(_c){} };
template<class T1, class T2, class T3>
bool operator<(const triple<T1,T2,T3>&t1,const triple<T1,T2,T3>&t2){if(t1.a!=t2.a)return t1.a<t2.a;else if(t1.b!=t2.b)return t1.b<t2.b;else return t1.c<t2.c;}
template<class T1, class T2, class T3>
bool operator>(const triple<T1,T2,T3>&t1,const triple<T1,T2,T3>&t2){if(t1.a!=t2.a)return t1.a>t2.a;else if(t1.b!=t2.b)return t1.b>t2.b;else return t1.c>t2.c;}
#define tri triple<int,int,int>
#define trll triple<ll,ll,ll>

#define FI(n) for(int i=0;i<(n);++i)
#define FJ(n) for(int j=0;j<(n);++j)
#define FK(n) for(int k=0;k<(n);++k)
#define FL(n) for(int l=0;l<(n);++l)
#define FQ(n) for(int q=0;q<(n);++q)
#define FOR(i,a,b) for(int i = (a), __e = (int) (b); i < __e; ++i)
#define all(a) std::begin(a), std::end(a)
#define reunique(v) v.resize(std::unique(v.begin(), v.end()) - v.begin())

#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(1.0 * (x))
#define pow(x, n) pow(1.0 * (x), n)

#define COMPARE(obj) [&](const std::decay_t<decltype(obj)>& a, const std::decay_t<decltype(obj)>& b)
#define COMPARE_BY(obj, field) [&](const std::decay_t<decltype(obj)>& a, const std::decay_t<decltype(obj)>& b) { return a.field < b.field; }

#define checkbit(n, b) (((n) >> (b)) & 1)
#define setbit(n, b) ((n) | (static_cast<std::decay<decltype(n)>::type>(1) << (b)))
#define removebit(n, b) ((n) & ~(static_cast<std::decay<decltype(n)>::type>(1) << (b)))
#define flipbit(n, b) ((n) ^ (static_cast<std::decay<decltype(n)>::type>(1) << (b)))
inline int countBits(uint v){v=v-((v>>1)&0x55555555);v=(v&0x33333333)+((v>>2)&0x33333333);return((v+(v>>4)&0xF0F0F0F)*0x1010101)>>24;}
inline int countBits(ull v){uint t=v>>32;uint p=(v & ((1ULL << 32) - 1)); return countBits(t) + countBits(p); }
inline int countBits(ll v){return countBits((ull)v); }
inline int countBits(int v){return countBits((uint)v); }
unsigned int reverseBits(uint x){ x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); return((x >> 16) | (x << 16)); }
template<class T> inline int sign(T x){ return x > 0 ? 1 : x < 0 ? -1 : 0; }
inline bool isPowerOfTwo(int x){ return (x != 0 && (x&(x - 1)) == 0); }
constexpr ll power(ll x, int p) { return p == 0 ? 1 : (x * power(x, p - 1)); }
template<class T>
inline bool inRange(const T& val, const T& min, const T& max) { return min <= val && val <= max; }
//template<class T1, class T2, class T3> T1 inline clamp(T1 x, const T2& a, const T3& b) { if (x < a) return a; else if (x > b) return b; else return x; }
unsigned long long rdtsc() { unsigned long long ret = 0;
#ifdef __clang__
    return __builtin_readcyclecounter();
#endif
#ifndef _MSC_VER
    asm volatile("rdtsc" : "=A" (ret) : :);
#endif
    return ret; }
// Fast IO ********************************************************************************************************
const int __BS = 4096;
static char __bur[__BS + 16], *__er = __bur + __BS, *__ir = __er;
template<class T = int> T readInt() {
    auto c = [&]() { if (__ir == __er) std::fill(__bur, __bur + __BS, 0), cin.read(__bur, __BS), __ir = __bur; };
    c(); while (*__ir && (*__ir < '0' || *__ir > '9') && *__ir != '-') ++__ir; c();
    bool m = false; if (*__ir == '-') ++__ir, c(), m = true;
    T r = 0; while (*__ir >= '0' && *__ir <= '9') r = r * 10 + *__ir - '0', ++__ir, c();
    ++__ir; return m ? -r : r;
}
string readString() {
    auto c = [&]() { if (__ir == __er) std::fill(__bur, __bur + __BS, 0), cin.read(__bur, __BS), __ir = __bur; };
    string r; c(); while (*__ir && isspace(*__ir)) ++__ir, c();
    while (!isspace(*__ir)) r.push_back(*__ir), ++__ir, c();
    ++__ir; return r;
}
char readChar() {
    auto c = [&]() { if (__ir == __er) std::fill(__bur, __bur + __BS, 0), cin.read(__bur, __BS), __ir = __bur; };
    c(); while (*__ir && isspace(*__ir)) ++__ir, c(); return *__ir++;
}
static char __buw[__BS + 20], *__iw = __buw, *__ew = __buw + __BS;
template<class T>
void writeInt(T x, char endc = '\n') {
    if (x < 0) *__iw++ = '-', x = -x; if (x == 0) *__iw++ = '0';
    char* s = __iw;
    while (x) { T t = x / 10; char c = x - 10 * t + '0'; *__iw++ = c; x = t; }
    char* f = __iw - 1; while (s < f) swap(*s, *f), ++s, --f;
    if (__iw > __ew) cout.write(__buw, __iw - __buw), __iw = __buw;
    if (endc) { *__iw++ = endc; }
}
template<class T>
void writeStr(const T& str) {
    int i = 0; while (str[i]) { *__iw++ = str[i++]; if (__iw > __ew) cout.write(__buw, __iw - __buw), __iw = __buw; }
}
struct __FL__ { ~__FL__() { if (__iw != __buw) cout.write(__buw, __iw - __buw); } };
static __FL__ __flushVar__;

//STL output *****************************************************************************************************
#define TT1 template<class T>
#define TT1T2 template<class T1, class T2>
#define TT1T2T3 template<class T1, class T2, class T3>
TT1T2 ostream& operator << (ostream& os, const pair<T1, T2>& p);
TT1 ostream& operator << (ostream& os, const vector<T>& v);
TT1T2 ostream& operator << (ostream& os, const set<T1, T2>&v);
TT1T2 ostream& operator << (ostream& os, const multiset<T1, T2>&v);
TT1T2 ostream& operator << (ostream& os, priority_queue<T1, T2> v);
TT1T2T3 ostream& operator << (ostream& os, const map<T1, T2, T3>& v);
TT1T2T3 ostream& operator << (ostream& os, const multimap<T1, T2, T3>& v);
TT1T2T3 ostream& operator << (ostream& os, const triple<T1, T2, T3>& t);
template<class T, size_t N> ostream& operator << (ostream& os, const array<T, N>& v);
TT1T2 ostream& operator << (ostream& os, const pair<T1, T2>& p){ return os <<"("<<p.first<<", "<< p.second<<")"; }
TT1 ostream& operator << (ostream& os, const vector<T>& v){       bool f=1;os<<"[";for(auto& i : v) { if (!f)os << ", ";os<<i;f=0;}return os << "]"; }
template<class T, size_t N> ostream& operator << (ostream& os, const array<T, N>& v) {     bool f=1;os<<"[";for(auto& i : v) { if (!f)os << ", ";os<<i;f=0;}return os << "]"; }
TT1T2 ostream& operator << (ostream& os, const set<T1, T2>&v){    bool f=1;os<<"[";for(auto& i : v) { if (!f)os << ", ";os<<i;f=0;}return os << "]"; }
TT1T2 ostream& operator << (ostream& os, const multiset<T1,T2>&v){bool f=1;os<<"[";for(auto& i : v) { if (!f)os << ", ";os<<i;f=0;}return os << "]"; }
TT1T2T3 ostream& operator << (ostream& os, const map<T1,T2,T3>& v){ bool f = 1; os << "["; for (auto& ii : v) { if (!f)os << ", "; os << "(" << ii.first << " -> " << ii.second << ") "; f = 0; }return os << "]"; }
TT1T2 ostream& operator << (ostream& os, const multimap<T1, T2>& v){ bool f = 1; os << "["; for (auto& ii : v) { if (!f)os << ", "; os << "(" << ii.first << " -> " << ii.second << ") "; f = 0; }return os << "]"; }
TT1T2 ostream& operator << (ostream& os, priority_queue<T1, T2> v) { bool f = 1; os << "["; while (!v.empty()) { auto x = v.top(); v.pop(); if (!f) os << ", "; f = 0; os << x; } return os << "]"; }
TT1T2T3 ostream& operator << (ostream& os, const triple<T1, T2, T3>& t){ return os << "(" << t.a << ", " << t.b << ", " << t.c << ")"; }
TT1T2 void printarray(const T1& a, T2 sz, T2 beg = 0){ for (T2 i = beg; i<sz; i++) cout << a[i] << " "; cout << endl; }

//STL input *****************************************************************************************************
TT1T2T3 inline istream& operator >> (istream& os, triple<T1, T2, T3>& t);
TT1T2 inline istream& operator >> (istream& os, pair<T1, T2>& p) { return os >> p.first >> p.second; }
TT1 inline istream& operator >> (istream& os, vector<T>& v) {
    if (v.size()) for (T& t : v) os >> t; else {
        string s; T obj; while (s.empty()) {getline(os, s); if (!os) return os;}
        stringstream ss(s); while (ss >> obj) v.push_back(obj);
    }
    return os;
}
TT1T2T3 inline istream& operator >> (istream& os, triple<T1, T2, T3>& t) { return os >> t.a >> t.b >> t.c; }

//Pair magic *****************************************************************************************************
#define PT1T2 pair<T1, T2>
TT1T2 inline PT1T2 operator+(const PT1T2 &p1 , const PT1T2 &p2) { return PT1T2(p1.first + p2.first, p1.second + p2.second); }
TT1T2 inline PT1T2& operator+=(PT1T2 &p1 , const PT1T2 &p2) { p1.first += p2.first, p1.second += p2.second; return p1; }
TT1T2 inline PT1T2 operator-(const PT1T2 &p1 , const PT1T2 &p2) { return PT1T2(p1.first - p2.first, p1.second - p2.second); }
TT1T2 inline PT1T2& operator-=(PT1T2 &p1 , const PT1T2 &p2) { p1.first -= p2.first, p1.second -= p2.second; return p1; }

#undef TT1
#undef TT1T2
#undef TT1T2T3

#define FREIN(FILE) freopen(FILE, "rt", stdin)
#define FREOUT(FILE) freopen(FILE, "wt", stdout)
#ifdef LOCAL
#define BEGIN_PROFILE(idx, name) int profileIdx = idx; profileName[profileIdx] = name; totalTime[profileIdx] -= rdtsc() / 1e3;
#define END_PROFILE totalTime[profileIdx] += rdtsc() / 1e3; totalCount[profileIdx]++;
#else
#define BEGIN_PROFILE(idx, name)
#define END_PROFILE
#endif

const int USUAL_MOD = 1000000007;
template<class T> inline void normmod(T &x, T m = USUAL_MOD) { x %= m; if (x < 0) x += m; }
template<class T1, class T2> inline T2 summodfast(T1 x, T1 y, T2 m = USUAL_MOD) { T2 res = x + y; if (res >= m) res -= m; return res; }
template<class T1, class T2, class T3 = int> inline void addmodfast(T1 &x, T2 y, T3 m = USUAL_MOD) { x += y; if (x >= m) x -= m; }
template<class T1, class T2, class T3 = int> inline void submodfast(T1 &x, T2 y, T3 m = USUAL_MOD) { x -= y; if (x < 0) x += m; }
inline ll mulmod(ll x, ll n, ll m){ x %= m; n %= m; ll r = x * n - ll(ld(x)*ld(n) / ld(m)) * m; while (r < 0) r += m; while (r >= m) r -= m; return r; }
inline ll powmod(ll x, ll n, ll m){ ll r = 1; normmod(x, m); while (n){ if (n & 1) r *= x; x *= x; r %= m; x %= m; n /= 2; }return r; }
inline ll powmulmod(ll x, ll n, ll m) { ll res = 1; normmod(x, m); while (n){ if (n & 1)res = mulmod(res, x, m); x = mulmod(x, x, m); n /= 2; } return res; }
template<class T> inline T gcd(T a, T b) { while (b) { T t = a % b; a = b; b = t; } return a; }
template<class T>
T fast_gcd(T u, T v) {
    int shl = 0; while ( u && v && u != v) { T eu = u & 1; u >>= eu ^ 1; T ev = v & 1; v >>= ev ^ 1;
        shl += (~(eu | ev) & 1); T d = u & v & 1 ? (u + v) >> 1 : 0; T dif = (u - v) >> (sizeof(T) * 8 - 1); u -= d & ~dif; v -= d & dif;
    } return std::max(u, v) << shl;
}

inline ll lcm(ll a, ll b){ return a / gcd(a, b) * b; }
template<class T> inline T gcd(T a, T b, T c){ return gcd(gcd(a, b), c); }
ll gcdex(ll a, ll b, ll& x, ll& y) {
    if (!a) { x = 0; y = 1; return b; }
    ll y1; ll d = gcdex(b % a, a, y, y1); x = y1 - (b / a) * y;
    return d;
}

bool isPrime(long long n) {
    if (n <= (1 << 14)) { int x = (int) n; if (x <= 4 || x % 2 == 0 || x % 3 == 0) return x == 2 || x == 3;
        for (int i = 5; i * i <= x; i += 6) if (x % i == 0 || x % (i + 2) == 0) return 0; return 1; }
    long long s = n - 1; int t = 0; while (s % 2 == 0) { s /= 2; ++t; }
    for (int a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) { if (!(a %= n)) return true;
        long long f = powmulmod(a, s, n); if (f == 1 || f == n - 1) continue;
        for (int i = 1; i < t; ++i) if ((f = mulmod(f, f, n)) == n - 1) goto nextp;
        return false; nextp:;
    } return true;
}

// Useful constants

//int some_primes[7] = {24443, 100271, 1000003, 1000333, 5000321, 98765431,
#define T9          1000000000
#define T18         1000000000000000000LL
#define INF         1011111111
#define LLINF       1000111000111000111LL
#define mod         1000000007
#define fftmod      998244353
#define EPS         1e-10
#define PI          3.14159265358979323846264
#define link        himomisubmitted
#define rank        thatsnoteasytask
//*************************************************************************************

int32_t solve();
int32_t main(int argc, char** argv) {
    ios_base::sync_with_stdio(0);cin.tie(0);
#ifdef LOCAL
    FREIN("input.txt");
    //    FREOUT("out.txt");
#endif
    return solve();
}

struct Node {
    Node *lp;
    Node *rp;
    ll sum = 0;
    ll minVal = 0;
    int s = 0;
    int free = 0;
    void update(int tl, int tr) {
//        DBN(tl, tr);
        assert(lp || rp);
        if (!lp) {
            this->sum = rp->sum;
            this->minVal = rp->minVal;
            this->s = rp->s;
            this->free = rp->free;
            free += tl;
            return;
        }
        if (!rp) {
            this->sum = lp->sum;
            this->minVal = lp->minVal;
            this->s = lp->s;
            this->free = lp->free;
            sum += lp->s * 1LL * tr;
            minVal = min(minVal, sum);
            return;
        }
        sum = lp->sum + rp->free * 1LL * lp->s + rp->sum;
        minVal = min(lp->minVal, lp->sum + rp->free * 1LL * lp->s + rp->minVal);
        s = rp->s;
        free = lp->free;
    }
};

Node nodes[101010 * 32];
Node* lastn = nodes;
Node* root;

void update(Node*& cur, int l, int r, int pos, int val) {
//    DBN(l, r, pos);
    if (!cur) {
        cur = lastn++;
    }
    if (l == r) {
        cur->s = val;
        cur->free = 0;
        cur->minVal = min(0, cur->s);
        cur->sum = val;
    } else {
        int m = (l + r) / 2;
        if (pos <= m) {
            update(cur->lp, l, m, pos, val);
        } else {
            update(cur->rp, m + 1, r, pos, val);
        }
//        DBN("upd", l, r, m);
        cur->update(m - l + 1, r - m);
    }
}
void del(Node*& cur, int l, int r, int pos) {
//    assert(cur);
    if (l == r) {
        cur = nullptr;
    } else {
        int m = (l + r) / 2;
        if (pos <= m) {
            del(cur->lp, l, m, pos);
        } else {
            del(cur->rp, m + 1, r, pos);
        }
        if (!cur->lp && !cur->rp) {
            cur = nullptr;
            return;
        }
        cur->update(m - l + 1, r - m);
    }
}
double ans = 1e20;
void getAns(Node* cur, int l, int r, int x, int y, ll& v, int& s) {
    if (y < l) return;
    if (x > r) return;
//    if (v <= 0) {
//        DBN(l, r, x, y, v, s);
//    }
//    assert(v > 0);
    if (!cur || l == r) {
//        assert(l <= x && y <= r);
        if (cur) s = cur->s;
        ll tot = s * (y - x + 1LL);
        if (tot + v > 0) {
            v += tot;
            return;
        }
        ans = x + v * 1.0 / -s;
        v = 0;
        return;
    }
    int m = (l + r) / 2;
    if (x <= l && r <= y) {
//        DBN(l, r, v, s);
        ll minVal = cur->minVal + cur->free * 1LL * s;
//        assert(cur->minVal <= cur->sum);
        if (minVal + v > 0) {
            v += cur->sum  + cur->free * 1LL * s;
//            assert(v > 0);
            s = cur->s;
            return;
        } else {
            getAns(cur->lp, l, m, x, m, v, s);
            if (!v) return;
            getAns(cur->rp, m + 1, r, m + 1, y, v, s);
            return;
        }
    }
    if (x <= m) {
        getAns(cur->lp, l, m, x, min(y, m), v, s);
        if (!v) return;
    }
    getAns(cur->rp, m + 1, r, max(x, m + 1), y, v, s);
}

int solve() {
    int q = readInt();
    while (q--) {
        int t = readInt();
        if (t == 1) {
            int w = readInt();
            int s = readInt();
//            DBN(t, w, s);
            update(root, 0, INF, w, s);
        } else if (t == 2) {
            int w = readInt();
//            DBN(t, w);
            del(root, 0, INF, w);
        } else {
            int l, r;
            ll v;
            l = readInt();
            r = readInt();
            v = readInt();
//            DBN(t, l, r, v);
            ans = 1e20;
            if (!v) {
                ans = l;
            }
            if (l < r && v) {
                int s = 0;
                getAns(root, 0, INF, l, r - 1, v, s);
            }
            if (v) {
                cout << -1 << '\n';
            } else {
                cout << fixed;
                cout.precision(8);
                cout << ans << '\n';
            }
        }
    }

    return 0;
}

/*----------------by syr----------------*/
/*
  -----  -----  -----
  |   |  |---|    _/
  |   |  | \_    /
  -----  |   \  -----

  |---\  \   /  |\  /|
  |   |   \_/   | \/ |
  |   |   / \   |    |
  |---/  /   \  |    |
*/
#include<bits/stdc++.h>

using namespace std;

#define PH push
#define MP make_pair
#define PB push_back
#define fst first
#define snd second
#define FOR(i,x,y) for(int i=(x);i<(y);++i)
#define REP(i,x,y) for(int i=(x);i<=(y);++i)
#define x0 x0123456789
#define y0 y0123456789
#define x1 x1234567890
#define y1 y1234567890
#define x2 x2345678901
#define y2 y2345678901
typedef double db;
typedef long long ll;
typedef long double ldb;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int inf=1e9+7;
const ll INF=1e18+7;
const int block=355;
const int maxn=1e5+5;

ll getHead(int id);
int getId(ll x);

class Block{
private:
	ll mxsum;
	ll sum[355];
public:
	vector<pll> vec;
	friend db query(ll l,ll r,ll v);
	friend void printAll();
	Block(){
		vec.clear();
		memset(sum,0,sizeof(sum));
		mxsum=0;
		return;
	}
	void calcTail(){
		int pos=vec.size()-1;
		if(pos) sum[pos]=sum[pos-1];
		else sum[pos]=0;
		sum[pos]+=vec[pos].snd*(getHead(getId(vec[pos].fst)+1)-vec[pos].fst);
		mxsum=-INF;
		FOR(i,0,vec.size()) mxsum=max(mxsum,sum[i]);
		return;
	}
	void insert(ll t,ll s){
		int pos=lower_bound(vec.begin(),vec.end(),MP(t,-INF))-vec.begin();
		vec.insert(vec.begin()+pos,MP(t,s));
		FOR(i,max(pos-1,0),vec.size()){
			if(i) sum[i]=sum[i-1];
			else sum[i]=0;
			if(i!=vec.size()-1) sum[i]+=vec[i].snd*(vec[i+1].fst-vec[i].fst);
			else{
//				printf("NextHead: %lld\n",getHead(getId(vec[0].fst)+1));
				sum[i]+=vec[i].snd*(getHead(getId(vec[0].fst)+1)-vec[i].fst);
			}
		}
		mxsum=-INF;
		FOR(i,0,vec.size()) mxsum=max(mxsum,sum[i]);
		return;
	}
	void erase(ll t){
		int pos=lower_bound(vec.begin(),vec.end(),MP(t,-INF))-vec.begin();
		vec.erase(vec.begin()+pos);
		FOR(i,max(pos-1,0),vec.size()){
			if(i) sum[i]=sum[i-1];
			else sum[i]=0;
			if(i!=vec.size()-1) sum[i]+=vec[i].snd*(vec[i+1].fst-vec[i].fst);
			else sum[i]+=vec[i].snd*(getHead(getId(vec[0].fst)+1)-vec[i].fst);
		}
		mxsum=-INF;
		FOR(i,0,vec.size()) mxsum=max(mxsum,sum[i]);
		return;
	}
	db query(ll l,ll r,ll v){
		int pl=lower_bound(vec.begin(),vec.end(),MP(l,-INF))-vec.begin();
		int pr=upper_bound(vec.begin(),vec.end(),MP(r,-INF))-vec.begin();
//		printf("l=%lld r=%lld v=%lld\n",l,r,v);
//		puts("vec:");
//		FOR(i,0,vec.size()) printf("%lld %lld\n",vec[i].fst,vec[i].snd);
		ll s=0;
		FOR(i,pl,pr){
			ll res=vec[i].snd;
			if(i!=vec.size()-1) res*=vec[i+1].fst-vec[i].fst;
			else res*=getHead(getId(vec[0].fst)+1)-vec[i].fst;
//			printf("s=%lld res=%lld %lld %lld\n",s,res,vec[i].fst,vec[i].snd);
			if(s+res>=v) return vec[i].fst+(1.0*(v-s)/vec[i].snd);
			s+=res;
		}
		return -1;
	}
	ll calcSum(ll l,ll r){
		ll ret=0;
		int pl=lower_bound(vec.begin(),vec.end(),MP(l,-INF))-vec.begin();
		int pr=upper_bound(vec.begin(),vec.end(),MP(r,-INF))-vec.begin();
		FOR(i,pl,pr){
			if(i!=vec.size()-1) ret+=vec[i].snd*(vec[i+1].fst-vec[i].fst);
			else ret+=vec[i].snd*(getHead(getId(vec[0].fst)+1)-vec[i].fst);
//			printf("calcSum: ret=%lld\n",ret);
		}
		return ret;
	}
}blk[355];

int q;
int tp[maxn],x[maxn],y[maxn],z[maxn];
vector<int> evn;

ll getHead(int id){
	FOR(i,id,355) if(blk[i].vec.size()) return blk[i].vec[0].fst;
	return inf;
}

int getId(ll x){
	int pos=lower_bound(evn.begin(),evn.end(),x)-evn.begin();
	return pos/block;
}

void printAll(){
	FOR(i,0,5){
		printf("i=%d\n",i);
		FOR(j,0,blk[i].vec.size()) printf("%lld %lld %lld\n",blk[i].vec[j].fst,blk[i].vec[j].snd,blk[i].sum[j]);
	}
	puts("");
	return;
}

db query(ll l,ll r,ll v){
	if(!v) return l;
	int nl=lower_bound(evn.begin(),evn.end(),l)-evn.begin();
	int nr=upper_bound(evn.begin(),evn.end(),r)-evn.begin()-1;
	int bl=nl/block,br=nr/block;
	if(bl==br){
		db ret=blk[bl].query(l,r,v);
		if(ret<=r) return ret;
		return -1;
	}else{
//		printAll();
		db ret=blk[bl].query(l,inf,v);
		ll cur=blk[bl].calcSum(l,inf);
		if(ret!=-1) return ret;
		FOR(i,bl+1,br){
			if(cur+blk[i].mxsum>=v){
				db res=blk[i].query(0,inf,v-cur);
				if(res<=r) return res;
				return -1;
			}
			if(blk[i].vec.size()) cur+=blk[i].sum[blk[i].vec.size()-1];
//			printf("cur=%lld\n",cur);
		}
//		printf("cur=%lld\n",cur);
		ret=blk[br].query(0,r,v-cur);
		if(ret<=r) return ret;
		return -1;
	}
}

int main(){
	scanf("%d",&q);
	FOR(i,0,q){
		scanf("%d",tp+i);
		if(tp[i]==1){
			scanf("%d %d",x+i,y+i);
			evn.PB(x[i]);
		}
		else if(tp[i]==2){
			scanf("%d",x+i);
		}
		else{
//			printf("i=%d\n",i);
			scanf("%d %d %d",x+i,y+i,z+i);
		}
	}
	sort(evn.begin(),evn.end());
	evn.erase(unique(evn.begin(),evn.end()),evn.end());
	FOR(i,0,q){
//		printf("%d %d\n",i,tp[i]);
//		printf("id=%d\n",getId(x[i]));
		if(tp[i]==1){
			int b=getId(x[i]);
			blk[b].insert(x[i],-y[i]);
			for(int j=b-1;j>=0;--j){
				if(blk[j].vec.size()){
					blk[j].calcTail();
					break;
				}
			}
		}
		else if(tp[i]==2){
			int b=getId(x[i]);
			blk[b].erase(x[i]);
			for(int j=b-1;j>=0;--j){
				if(blk[j].vec.size()){
					blk[j].calcTail();
					break;
				}
			}
		}
		else printf("%.10f\n",query(x[i],y[i],z[i]));
//		puts("ok");
//		printAll();
	}
	return 0;
}

#include <bits/stdc++.h>
using std::cerr;using std::cin;using std::cout;using std::abs;using std::min;using std::max;using std::swap;using std::map;using std::unordered_map;using std::unordered_set;using std::bitset;using std::pair;using std::set;using std::string;using std::vector;using std::sort;using ll=long long;using uint=unsigned int;using pii=pair<int,int>;using pll=pair<ll,ll>;using ull = unsigned long long;using ld=long double;using vci=vector<int>;using vcl=vector<ll>;template<typename T>void _dbg(const char*_s,T _h){cerr<<_s<<" = "<<_h<<"\n";}template<typename T,typename...Ts>void _dbg(const char*_s,T _h,Ts..._t){int _b=0;while(((_b+=*_s=='(')-=*_s==')')!=0||*_s!=',')cerr<<*_s++;cerr<<" = "<<_h<<",";_dbg(_s+1,_t...);}
#define f first
#define s second
#define pb emplace_back
#define sz(a) ((int)a.size())
#define forn(i,n) for(int i=0;i<(n);++i)
struct init{init(){cin.tie(0);std::iostream::sync_with_stdio(0);cout<<std::fixed<<std::setprecision(10);cerr<<std::fixed<<std::setprecision(5);}~init(){
#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__,__VA_ARGS__)
cerr<<"Time elapsed: "<<(double)clock()/CLOCKS_PER_SEC<<"s.\n";
#else
#define dbg(...)
#endif
}}init;template<typename T,typename U>void upx(T&x,U y){if(x<y)x=y;}template<typename T,typename U>void upn(T&x,U y){if(x>y)x=y;}
#define int ll
const int N=1e5+444,K=250,OO=1e9;
int xs[N];
struct query{
    int type,a,b,c;
}qs[N];
struct block{
    int x[K+1]={0},a[K+1]={0},u[K+1]={0};
    int mn=0,delta=0,lasts=0,ub=0,ftx;
    void recalc(){
        mn=ub=0,ftx=x[K];
        int s=0,val=0,pos=x[0];
        forn(i,K+1){
            val+=(x[i]-pos)*s;
            pos=x[i];
            if(u[i]){
                upn(ftx,x[i]);
                lasts=s=a[i];
                ub=1;
            }
            upn(mn,val);
            if(pos>OO)break;
        }
        delta=val;
    }
    int getmn(int starts){
        return min(starts*(ftx-x[0]),starts*(ftx-x[0])+mn);
    }
    int getdelta(int starts){
        return starts*(ftx-x[0])+delta;
    }
    void upd(int i,int v){
        u[i]=1;
        a[i]=v;
        recalc();
    }
    void rem(int i){
        u[i]=0;
        recalc();
    }
    bool go(int i,int val,double&ans,int&ls,int starts){
        int s=starts;
        int pos=x[i];
        for(int j=i;j<=K;++j){
            dbg(j,val,pos,x[j]);
            if(val+(x[j]-pos)*s<=0){
                ans=-((double)val)/s+pos;
                return 1;
            }
            val+=(x[j]-pos)*s;
            if(u[j])s=a[j];
            pos=x[j];
            if(pos>OO)break;
        }
        ans=val;
        ls=s;
        return 0;
    }
}bs[N/K+5];
int b;
int32_t main() {
    int n;
    cin>>n;
    int m=0;
    forn(i,n){
        cin>>qs[i].type;
        if(qs[i].type==1){
            cin>>qs[i].a>>qs[i].b;
            xs[m++]=qs[i].a;
        }
        if(qs[i].type==2)cin>>qs[i].a;
        if(qs[i].type==3){
            cin>>qs[i].a>>qs[i].b>>qs[i].c;
            xs[m++]=qs[i].a;
        }
    }
    xs[m++]=1e9+1;
    sort(xs,xs+m);
    m=std::unique(xs,xs+m)-xs;
    b=(m+K-1)/K;
    forn(i,b){
        for(int j=i*K;j<=(i+1)*K;++j)bs[i].x[j-i*K]=xs[j];
        bs[i].recalc();
    }
    for(int i=K;i>=0;--i){
        if(bs[b-1].x[i]>OO)break;
        bs[b-1].x[i]=OO;
    }
    bs[b-1].recalc();
    forn(i,n){
        if(qs[i].type==1){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            bs[x/K].upd(x%K,qs[i].b);
        }
        if(qs[i].type==2){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            bs[x/K].rem(x%K);
        }
        if(qs[i].type==3){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            int val=qs[i].c;
            if(val==0){
                cout<<qs[i].a<<'\n';
                continue;
            }
            double ans;
            int f=0,s;
            if(!bs[x/K].go(x%K,val,ans,s,0)){
                val=(ll)(ans+0.5);
                dbg(ans,val);
                for(int j=x/K+1;j<b;++j){
                    dbg(j,bs[j].x[0],val,s);
                    if(val+bs[j].getmn(s)<=0){
                        dbg(bs[j].getmn(s));
                        bs[j].go(0,val,ans,s,s);
                        f=1;
                        break;
                    }
                    val+=bs[j].getdelta(s);
                    if(bs[j].ub)s=bs[j].lasts;
                }
            }else f=1;
            if(f&&ans<=(double)qs[i].b+1e-9){
                cout<<ans<<'\n';
            }else{
                cout<<"-1\n";
            }
        }
    }

    return 0;
}

#include <cstdio>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN=110000;
struct Treap
{
	struct Node
	{
		int ls, rs, wgt;
		int time, tL, tR;
		int speed, speedR;
		ll res, mn;
	} tr[MAXN];
	int cnt, root;
	int newNode(int p, int k)
	{
		int x=++cnt;
		tr[x].ls=tr[x].rs=0; tr[x].wgt=rand();
		tr[x].time=tr[x].tL=tr[x].tR=p;
		tr[x].speed=tr[x].speedR=k;
		tr[x].res=tr[x].mn=0;
		return x;
	}
	void pushup(int x)
	{
		int lc=tr[x].ls, rc=tr[x].rs;
		if (lc&&rc)
		{
			tr[x].tL=tr[lc].tL;
			tr[x].tR=tr[rc].tR;
			tr[x].speedR=tr[rc].speedR;
			tr[x].res=tr[x].mn=0;
			tr[x].mn=min(tr[x].mn, tr[lc].mn);
			tr[x].res+=tr[lc].res+1ll*tr[lc].speedR*(tr[x].time-tr[lc].tR);
			tr[x].mn=min(tr[x].mn, tr[x].res);
			tr[x].res+=1ll*tr[x].speed*(tr[rc].tL-tr[x].time);
			tr[x].mn=min(tr[x].mn, tr[x].res+tr[rc].mn);
			tr[x].res+=tr[rc].res;
		}
		else if (lc)
		{
			tr[x].tL=tr[lc].tL;
			tr[x].tR=tr[x].time;
			tr[x].speedR=tr[x].speed;
			tr[x].res=tr[x].mn=0;
			tr[x].mn=min(tr[x].mn, tr[lc].mn);
			tr[x].res+=tr[lc].res+1ll*tr[lc].speedR*(tr[x].time-tr[lc].tR);
			tr[x].mn=min(tr[x].mn, tr[x].res);
		}
		else if (rc)
		{
			tr[x].tL=tr[x].time;
			tr[x].tR=tr[rc].tR;
			tr[x].speedR=tr[rc].speedR;
			tr[x].res=tr[x].mn=0;
			tr[x].res+=1ll*tr[x].speed*(tr[rc].tL-tr[x].time);
			tr[x].mn=min(tr[x].mn, tr[x].res+tr[rc].mn);
			tr[x].res+=tr[rc].res;
		}
		else
		{
			tr[x].tL=tr[x].tR=tr[x].time;
			tr[x].speedR=tr[x].speed;
			tr[x].res=tr[x].mn=0;
		}
	}
	void split(int o, int& x, int& y, int p)
	{
		if (!o) { x=y=0; return; }
		if (tr[o].time<p)
			x=o, split(tr[o].rs, tr[x].rs, y, p);
		else y=o, split(tr[o].ls, x, tr[y].ls, p);
		pushup(o);
	}
	void merge(int x, int y, int& o)
	{
		if (!x||!y) { o=x+y; return; }
		if (tr[x].wgt<tr[y].wgt)
			o=x, merge(tr[x].rs, y, tr[o].rs);
		else o=y, merge(x, tr[y].ls, tr[o].ls);
		pushup(o);
	}
	void insert(int p, int k)
	{
		int a, b, c;
		split(root, a, b, p);
		merge(a, newNode(p, k), c);
		merge(c, b, root);
	}
	void erase(int p)
	{
		int a, b, c, d;
		split(root, a, b, p);
		split(b, c, d, p+1);
		merge(a, d, root);
	}
	void print(int x)
	{
		if (!x) return;
		print(tr[x].ls);
		printf("%d %d %d %d %d %lld %lld\n", x, tr[x].ls, tr[x].rs, tr[x].time, tr[x].speed, tr[x].res, tr[x].mn);
		print(tr[x].rs);
	}
	double query(int l, int r, ll v)
	{
		if (v==0) return l;
		int a, b, c, d, e, x, y;
		split(root, a, b, l);
		split(b, c, d, r);
		merge(c, y=newNode(r, 0), e);
		x=e;
//		acd
//		aed
//		printf("#%lld %lld#\n", tr[e].res, tr[e].mn);
//		puts("##############");
//		print(x);
//		puts("##############");
		while (1)
		{
			ll t1=tr[x].ls?tr[tr[x].ls].res+1ll*tr[tr[x].ls].speedR*(tr[x].time-tr[tr[x].ls].tR):0;
			ll t2=tr[x].rs?1ll*tr[x].speed*(tr[tr[x].rs].tL-tr[x].time):0;
			if (tr[x].ls&&v+min(tr[tr[x].ls].mn, t1)<=0) x=tr[x].ls;
			else if (tr[x].rs&&v+t1+t2>0) v+=t1+t2, x=tr[x].rs;
			else { v+=t1; break;}
		}
		double res=x!=y?tr[x].time-1.0*v/tr[x].speed:-1;
//		printf("%d %lld\n", x, v);
		split(e, b, c, r);
		merge(a, b, c);
		merge(c, d, root);
		return res;
	}
} treap;
int main()
{
//	freopen("C.in", "r", stdin);
//	freopen("C.out", "w", stdout);
	srand(1);
	int q;
	scanf("%d", &q);
	while (q--)
	{
		int opt;
		scanf("%d", &opt);
		if (opt==1)
		{
			int p, k;
			scanf("%d%d", &p, &k);
			treap.insert(p, k);
		}
		else if (opt==2)
		{
			int p;
			scanf("%d", &p);
			treap.erase(p);
		}
		else
		{
			int l, r, v;
			scanf("%d%d%d", &l, &r, &v);
			printf("%.7lf\n", treap.query(l, r, v));
		}
//		treap.print(treap.root);
//		putchar('\n');
	}
	return 0;
}

#include<cstdio>
#include<algorithm>
using namespace std;
int gi(){
	int x=0,w=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')w=0,ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
#define ll long long
const int N=1e5+5;

int ls[N],rs[N],tim[N],spd[N],tL[N],tR[N],spdR[N],rd[N],tot,rt;
ll res[N],mn[N];

void up(int x){
	tL[x]=tR[x]=tim[x];spdR[x]=spd[x];mn[x]=res[x]=0;
	if(ls[x]){
		tL[x]=tL[ls[x]];
		mn[x]=min(mn[x],mn[ls[x]]);
		res[x]+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
		mn[x]=min(mn[x],res[x]);
	}
	if(rs[x]){
		tR[x]=tR[rs[x]];spdR[x]=spdR[rs[x]];
		res[x]+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
		mn[x]=min(mn[x],res[x]+mn[rs[x]]);
		res[x]+=res[rs[x]];
		mn[x]=min(mn[x],res[x]);
	}
}
void split(int x,int k,int &a,int &b){
	if(!x){a=b=0;return;}
	if(tim[x]<=k)a=x,split(rs[x],k,rs[a],b),up(a);
	else b=x,split(ls[x],k,a,ls[b]),up(b);
}
int merge(int x,int y){
	if(!x||!y)return x|y;
	if(rd[x]<rd[y])return rs[x]=merge(rs[x],y),up(x),x;
	else return ls[y]=merge(x,ls[y]),up(y),y;
}

double query(int x,int r,ll v){
	if(ls[x]){
		if(v+mn[ls[x]]<=0)return query(ls[x],tim[x],v);
		v+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
		if(v<=0)return tim[x]-1.0*v/spdR[ls[x]];
	}
	if(rs[x]){
		v+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
		if(v<=0)return tL[rs[x]]-1.0*v/spd[x];
		if(v+mn[rs[x]]<=0)return query(rs[x],r,v);
		v+=res[rs[x]];
	}
	v+=1ll*spdR[x]*(r-tR[x]);return r-1.0*v/spdR[x];
}

int main(){
	int q=gi();while(q--){
		int op=gi();
		if(op==1){
			tim[++tot]=gi();spd[tot]=gi();rd[tot]=rand()*rand();
			int x,y;split(rt,tim[tot],x,y);
			up(tot);rt=merge(x,merge(tot,y));
		}else if(op==2){
			int t=gi(),x,y,z;
			split(rt,t,x,z);split(x,t-1,x,y);
			rt=merge(x,z);
		}else{
			int l=gi(),r=gi(),v=gi(),x,y,z;
			if(!v){printf("%d\n",l);continue;}
			split(rt,r,x,z);split(x,l-1,x,y);
			if(!y||v+min(mn[y],res[y]+1ll*spdR[y]*(r-tR[y]))>0)puts("-1");
			else
				printf("%.6lf\n",query(y,r,v));
			rt=merge(x,merge(y,z));
		}
	}
	return 0;
}

#include <string.h>
#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <set>

#include <map>
#include <vector>
#include <string>
#include <stdlib.h>

#define ll long long
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
#define fr(i,a,b) for(int i = a; i < b; ++i)
#define frr(i,a,b) for(int i = a; i > b; --i)
#define pb push_back
#define sf scanf

#define pf printf
#define mp make_pair

using namespace std;
const ll mod = 1000000007;
const int MAXN = 10000005;
const double eps = 1e-6;
int n,m,z;
ll a[1000000];
int cmd[500010], v[500010],l[500010],r[500010],t[500010], s[1000010],val[1000010];

map<int,int> time_idx, pre_time,ft;
int idx;

void add_t(int t) {
	if(time_idx.find(t)==time_idx.end()) {
		pre_time[idx]=t;
		time_idx[t]=idx++;
	}
}

void push_down(int node) {
}

struct Info{

	ll s0;
	ll st;
	ll min_v;
	ll sp;
	ll start_time;
	ll end_time;
	int flag;
	Info(){flag = 0;}

}info[1000010];

Info merge(const Info &lt, const Info &rt) {
	//printf("lt flag %d rt flag %d\n",lt.flag, rt.flag);
	Info cur;
	if(lt.flag&&rt.flag) {
		int ed = lt.end_time;
		int sd = rt.start_time;
		ll ssp = lt.st + (sd-ed)*lt.sp;
		//printf("ssp = %lld ed = %d sd  = %d st = %lld sp = %lld\n",ssp,ed,sd, lt.st,lt.sp);
		cur.s0 = lt.s0;
		cur.st = ssp+rt.st;
		cur.min_v = min(lt.min_v,min(ssp,rt.min_v+ssp));
		cur.sp = rt.sp;
		cur.start_time = lt.start_time;
		cur.end_time = rt.end_time;
		cur.flag = 1;
	}
	else if(lt.flag) {
		cur = lt;
	}
	else if(rt.flag) {
		cur = rt;
	}
	return cur;
}

void push_up(int node, int l, int r) {
	Info lt = info[node<<1], rt = info[node<<1|1];
	info[node]=merge(lt,rt);
}

void add(int node, int l, int r, int t_idx, int v, int flag) {
	//printf("l = %d r = %d idx = %d v = %d\n",l,r,t_idx,v);
	if(l==r&&l==t_idx) {
		val[r] = v;
		info[node].s0 = 0;
		info[node].st = 0;
		info[node].min_v = 0;
		info[node].sp=v;
		info[node].start_time=pre_time[l];
		info[node].end_time=pre_time[r];

		if(flag>0) {
			info[node].flag=1;
		}
		else {
			info[node].flag=0;
		}
		//printf("node = %d v = %d flag = %d\n",node,v, flag);
		return;
	}

	int mid = (l+r)>>1;
	if(mid>=t_idx) {
		add(node<<1,l,mid,t_idx,v,flag);
	}
	else {
		add(node<<1|1,mid+1,r,t_idx,v,flag);
	}
	push_up(node,l,r);
	Info cur = info[node];
	//printf("l = %d r = %d s0 = %lld st = %lld start = %lld end = %lld min = %lld flag %d\n",l,r,cur.s0,cur.st,cur.start_time,cur.end_time,cur.min_v, cur.flag);
}

Info query(int node, int l, int r, int ql, int qr) {
	//printf("query l = %d r = %d ql = %d qr = %d\n",l,r, ql, qr);
	if(ql<=l&&qr>=r) {
		return info[node];
	}
	if(ql>r||qr<l) {
		return Info();
	}

	int mid = (l+r)>>1;
	if(qr<=mid) {
		return query(node<<1,l,mid,ql,qr);
	}
	else if(ql>mid) {
		return query(node<<1|1,mid+1,r,ql,qr);
	}

	Info sum1 = query(node<<1,l,mid,ql,qr);
	Info sum2 = query(node<<1|1,mid+1,r,ql,qr);
	return merge(sum1,sum2);
}

double cal(double start,double end, int v) {

	auto it1 = ft.lower_bound(start);
	auto it2 = ft.upper_bound(end);
	if(it2!=ft.begin()) {
		it2--;
		if(it1->second > it2->second) return 0;
		//printf("cal start = %lf end = %lf v= %d\n",start,end,v);
		Info sum;
		if(it1->second!=it2->second) {
			sum = query(1,0,idx-1,it1->second,it2->second);
			//printf("sum %lld\n",sum.sp);
		}
		else {
			sum.st = 0;
			sum.sp = val[it2->second];
			sum.end_time = it2->first;
			sum.start_time = it2->first;
			sum.min_v = 0;
		}
		double left_t = end-sum.end_time;
		double res = sum.st+sum.sp*left_t;
		//printf("st = %lld sp = %lld res = %.10lf\n",sum.st,sum.sp,res);
		double min_v = min((double)sum.min_v, res);
		//printf("total sum = %lf left = %lf min = %lf last = %lld end = %lf last end = %lld\n",res, left_t, min_v,sum.sp, end, sum.end_time);
		return min_v;
	}
	else {
		return 0;
	}
}

void query(int start,int end, int v) {
	if(v==0) {
		printf("%d\n",start);
		return;
	}
	auto it1 = ft.lower_bound(start);
	auto it2 = ft.lower_bound(end);
	if(it1 == it2) {
		printf("-1\n");
		return;
		if(it1==ft.begin()) {
			printf("-1\n");
			return;
		}
		else {
			it1--;
			ll s = val[it1->second];
			ll sum = s*(end-start);
			double x = (double)v/s;
			if(start+x>end+eps) {
				printf("-1\n");
			}
			else {
				printf("%.6lf\n",start+x);
			}
			return;
		}
	}

	//printf("query start = %d end = %d v = %d\n",start,end,v);
	double l = start, r = end+eps;
	for(int i = 0; i < 48&&fabs(l-r)>eps; ++i) {
		double mid =(l+r)/2.0;
		double sum = cal(start,mid,v);
		if(sum+v>eps){
			l = mid;
		}
		else {
			r = mid;
		}
	}
	//printf("l = %lf r = %lf\n",l,r);
	double t = cal(start,r,v);
	//printf("l = %lf r = %lf sum = %.10lf, %d\n",l,r,t, (t+v)>eps);
	t+=v;
	//printf("l = %lf t = %.10lf check %d\n",r,t, (t-eps)>=0);
	if(t>eps) printf("-1\n");
	else printf("%.6lf\n",r);
}

void sol(){
	fr(i,0,n) {
		//printf("i = %d\n",i);
		if(cmd[i]==1) {
			add(1,0,idx-1,time_idx[t[i]],s[i],1);
			ft[t[i]]=time_idx[t[i]];
		}
		else if(cmd[i]==2) {
			add(1,0,idx-1,time_idx[t[i]],0,0);
			ft.erase(ft.find(t[i]));
		}
		else {
			query(l[i],r[i],v[i]);
		}
	}
}

int main(){

	idx = 0;
	sf("%d",&n);
	vector<int> xxx;
	fr(i,0,n) {
		sf("%d",&cmd[i]);
		if(cmd[i]==1) {
			sf("%d%d",&t[i],&s[i]);
			xxx.pb(t[i]);
		}
		else if(cmd[i]==2) {
			sf("%d",&t[i]);
		}
		else if(cmd[i]==3) {
			sf("%d%d%d",&l[i],&r[i],&v[i]);
		}
	}
	sort(xxx.begin(), xxx.end());
	int pos = unique(xxx.begin(), xxx.end())-xxx.begin();
	for(int i = 0; i < pos; ++i) {
		add_t(xxx[i]);
	}
	sol();
}

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

class node {
 public:
  node* l;
  node* r;
  node* p;
  int time, ltime, rtime, speed, rspeed;
  long long sum, lsum;

  node(int time, int speed): time(time), speed(speed) {
    l = r = p = NULL;
    ltime = rtime = time;
    rspeed = speed;
    sum = lsum = 0;
  }

  void pull() {
    ltime = rtime = time;
    rspeed = speed;
    sum = lsum = 0;
    if (l != NULL) {
      l->p = this;
      ltime = l->ltime;
      lsum = min(lsum, sum + l->lsum);
      sum += l->sum + (long long) l->rspeed * (time - l->rtime);
      lsum = min(lsum, sum);
    }
    if (r != NULL) {
      r->p = this;
      rtime = r->rtime;
      rspeed = r->rspeed;
      sum += (long long) speed * (r->ltime - time);
      lsum = min(lsum, sum + r->lsum);
      sum += r->sum;
    }
  }
};

void rotate(node* v) {
  node* u = v->p;
  v->p = u->p;
  if (v->p != NULL) {
    if (v->p->l == u) {
      v->p->l = v;
    }
    if (v->p->r == u) {
      v->p->r = v;
    }
  }
  if (v == u->l) {
    u->l = v->r;
    v->r = u;
  } else {
    u->r = v->l;
    v->l = u;
  }
  u->pull();
  v->pull();
}

void splay(node* v, node* aim = NULL) {
  while (v->p != aim) {
    node* u = v->p;
    if (u->p != aim) {
      if ((u->l == v) ^ (u->p->l == u)) {
        rotate(v);
      } else {
        rotate(u);
      }
    }
    rotate(v);
  }
}

node* insert(node* v, node* u) {
  while (true) {
    if (u->time > v->time) {
      if (v->r == NULL) {
        v->r = u;
        u->p = v;
        break;
      } else {
        v = v->r;
      }
    } else {
      if (v->l == NULL) {
        v->l = u;
        u->p = v;
        break;
      } else {
        v = v->l;
      }
    }
  }
  splay(u);
  return u;
}

node* find(node* v, int time) {
  while (true) {
    if (time == v->time) {
      break;
    } else if (time > v->time) {
      v = v->r;
    } else {
      v = v->l;
    }
  }
  splay(v);
  return v;
}

node* find_less(node* v, int time) {
  node* res = NULL;
  node* from = NULL;
  while (v != NULL) {
    from = v;
    if (v->time < time) {
      res = v;
      v = v->r;
    } else {
      v = v->l;
    }
  }
  splay(from);
  splay(res);
  return res;
}

node* find_greater(node* v, int time) {
  node* res = NULL;
  node* from = NULL;
  while (v != NULL) {
    from = v;
    if (v->time > time) {
      res = v;
      v = v->l;
    } else {
      v = v->r;
    }
  }
  splay(from);
  splay(res);
  return res;
}

node* get_rightmost(node* v) {
  while (v->r != NULL) {
    v = v->r;
  }
  splay(v);
  return v;
}

node* merge(node* v, node* u) {
  v = get_rightmost(v);
  splay(u);
  v->r = u;
  v->pull();
  return v;
}

node* erase(node* v) {
  splay(v);
  v->l->p = v->r->p = NULL;
  return merge(v->l, v->r);
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
  node* lmost = new node(0, 0);
  node* rmost = new node(inf, 0);
  lmost->r = rmost;
  lmost->pull();
  node* root = lmost;
  int tt;
  cin >> tt;
  while (tt--) {
    int type;
    cin >> type;
    if (type == 1) {
      int time, speed;
      cin >> time >> speed;
      root = insert(root, new node(time, speed));
    } else if (type == 2) {
      int time;
      cin >> time;
      root = erase(find(root, time));
    } else {
      int l, r;
      long long x;
      cin >> l >> r >> x;
      if (!x) {
        cout << l << "\n";
        continue;
      }
      root = find_less(root, l);
      node* left = root;
      root = find_greater(root, r);
      node* right = root;
      splay(left, right);
      node* v = left->r;
      if (v == NULL) {
        cout << -1 << "\n";
      } else {
        if (x + v->lsum <= 0) {
          while (true) {
            if (v->l != NULL) {
              if (x + v->l->lsum <= 0) {
                v = v->l;
              } else {
                x += v->l->sum;
                if (x + (long long) v->l->rspeed * (v->time - v->l->rtime) <= 0) {
                  cout << v->l->rtime - (double) x / v->l->rspeed << "\n";
                  break;
                } else {
                  x += (long long) v->l->rspeed * (v->time - v->l->rtime);
                  if (x + (long long) v->speed * (v->r->ltime - v->time) <= 0) {
                    cout << v->time - (double) x / v->speed << "\n";
                    break;
                  } else {
                    x += (long long) v->speed * (v->r->ltime - v->time);
                    v = v->r;
                  }
                }
              }
            } else {
              if (x + (long long) v->speed * (v->r->ltime - v->time) <= 0) {
                cout << v->time - (double) x / v->speed << "\n";
                break;
              } else {
                x += (long long) v->speed * (v->r->ltime - v->time);
                v = v->r;
              }
            }
          }
          splay(v);
          root = v;
        } else if (x + v->sum + (long long) v->rspeed * (r - v->rtime) <= 0) {
          cout << v->rtime - (double) (x + v->sum) / v->rspeed << "\n";
        } else {
          cout << -1 << "\n";
        }
      }
    }
  }
  return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define loop int a[n]; for(i=0;i<n;i++)
#define lloop ll a[n]; for(i=0;i<n;i++)
#define tcase int T; cin>>T; for(int t=1;t<=T;t++)
#define pcase cout<<"Case #"<<t<<": "
#define max(a,b) (a>b?a:b)
#define check(a,b) for(int z=0;z<b;z++) cout<<a[z].fi<<' '<<a[z].se<<endl;
#define pb push_back
#define min(a,b) (a<b?a:b)
#define g(a) (a*(a-1))/2
#define fi first
#define se second
#define M 1000000007
#define pi 3.1415926536
using namespace std;

int a[100005][4];
set<int> st;
vector<pair<int,int> > v[500];
vector<int> sp;
int d[100005];
ll an[500];
ll mi[500];
int N;
map<int,int> mp;
void calc(int bl) {
  an[bl]=0;
  mi[bl]=0;
  for(int i=0;i+1<int(v[bl].size());i++) {
    an[bl]=an[bl]+(ll)(v[bl][i+1].fi-v[bl][i].fi)*(v[bl][i].se);
    mi[bl]=min(an[bl],mi[bl]);
  }
}
double query(ll l,ll r,ll vt,double s) {
  int pl=(lower_bound(sp.begin(),sp.end(),l)-sp.begin());
  int pr=(upper_bound(sp.begin(),sp.end(),r)-sp.begin()-1);
  while(pl<=pr&&pl%N!=0) {
    if(d[pl]!=M) {
      vt+=(sp[pl]-l)*s;
      if(vt<=0) {
        vt-=(sp[pl]-l)*s;
        return l-vt/s;
      }
      l=sp[pl];
      s=d[pl];
    }
    pl++;
  }
  while(pl+N<=pr) {
    if(v[pl/N].empty()==false) {
      if(vt+(v[pl/N][0].fi-l)*s+mi[pl/N]<=0) {
        break;
      }
      else {
        vt+=(v[pl/N][0].fi-l)*s+an[pl/N];
        l=v[pl/N].rbegin()->fi;
        s=v[pl/N].rbegin()->se;
      }
    }
    pl+=N;
  }
  while(pl<=pr) {
    if(d[pl]!=M) {
      vt+=(sp[pl]-l)*s;
      if(vt<=0) {
        vt-=(sp[pl]-l)*s;
        return l-vt/s;
      }
      l=sp[pl];
      s=d[pl];
    }
    pl++;
  }
  if(vt+(r-l)*s<=0)
    return l-vt/s;
  return -1;
}
int main() {
  ios::sync_with_stdio(false);
  // freopen("input.txt","r",stdin);
  // freopen("output.txt","w",stdout);
  int q;
  cin>>q;
  for(int i=0;i<q;i++) {
    cin>>a[i][0]>>a[i][1];
    if(a[i][0]!=2)
      cin>>a[i][2];
    if(a[i][0]==3)
      cin>>a[i][3];
    if(a[i][0]==1)
      st.insert(a[i][1]);
  }
  int i=0;
  for(set<int>:: iterator it=st.begin();it!=st.end();it++) {
    mp[*it]=i;
    sp.pb(*it);
    d[i]=M;
    i++;
  }
  sp.pb(M);
  mp[M]=i;
  d[i]=M;
  N=sqrt(i)+1;
  cout<<fixed;
  cout<<setprecision(10);
  for(int i=0;i<q;i++) {
    if(a[i][0]==1) {
      int bl=mp[a[i][1]]/N;
      v[bl].pb(pair<int,int>(0,0));
      int j=0;
      for(j=int(v[bl].size())-1;j>0&&v[bl][j-1].fi>a[i][1];j--) {
        v[bl][j]=v[bl][j-1];
      }
      d[mp[a[i][1]]]=a[i][2];
      v[bl][j]=pair<int,int>(a[i][1],a[i][2]);
      calc(bl);
    }
    else if(a[i][0]==2) {
      int bl=mp[a[i][1]]/N;
      d[mp[a[i][1]]]=M;
      v[bl].erase(lower_bound(v[bl].begin(),v[bl].end(),pair<int,int>(a[i][1],-M)));
      calc(bl);
    }
    else {
      if(a[i][3]==0)
        cout<<a[i][1]<<endl;
      else {
        double ck=query(a[i][1],a[i][2],a[i][3],0);
        if(ck-(ll)ck<1e-7)
          cout<<(ll)ck<<endl;
        else
          cout<<ck<<endl;
      }
    }
  }
}

#include<bits/stdc++.h>
#define IL inline
#define _ 100005
#define ll long long
#define ld long double
using namespace std ;

IL int gi(){
    int data = 0 , m = 1; char ch = 0;
    while(ch!='-' && (ch<'0'||ch>'9')) ch = getchar();
    if(ch == '-'){m = 0 ; ch = getchar() ; }
    while(ch >= '0' && ch <= '9'){data = (data<<1) + (data<<3) + (ch^48) ; ch = getchar(); }
    return (m) ? data : -data ;
}

ld Ans ;  int n , Q , X[_ << 2] , Key[_ << 2] , root , xox ; bool flag ;
ld last_speed ;

struct Qry{int op , l , r ; ld v ; } q[_] ;
IL void Init() {
	for(int i = 1; i <= Q; i ++) {
		q[i].op = gi() ; q[i].l = gi() ;
		if(q[i].op != 2) q[i].r = gi() ; if(q[i].op == 3) q[i].v = gi() ;
	}
	xox = 0 ; for(int i = 1; i <= Q; i ++) X[++ xox] = q[i].l ;
	for(int i = 1; i <= Q; i ++) if(q[i].op == 3) X[++ xox] = q[i].r ;
	sort(X + 1 , X + xox + 1) ;
	xox = unique(X + 1 , X + xox + 1) - X - 1 ; return ;
}

struct Node{
	int ls , rs ; ld Ltim , Rtim , tim , v , rv ; ld res , mn ;
	IL Node() {Ltim = Rtim = v = res = tim = rv = mn = 0 ;  }
	IL Node(int r1,int r2,ld a,ld b,ld c,ld d,ld e,ld ee,ld eee){
		ls = r1 ; rs = r2 ; Ltim = a ; Rtim = b ; tim = c ; v = d ; rv = e ; res = ee ; mn = eee ;
	}
} ;
Node t[_ << 2] ;
IL void PushUp(int o) {
	int lc = t[o].ls , rc = t[o].rs ;
	t[o].res = 0 ; t[o].mn = 0 ; t[o].rv = t[o].v ; t[o].Ltim = t[o].Rtim = t[o].tim ;
	if(lc) {
		t[o].mn = min(t[o].mn , t[lc].mn) , t[o].res = t[lc].res + (t[o].tim - t[lc].Rtim) * t[lc].rv ;
		t[o].mn = min(t[o].mn , t[o].res) ;
		t[o].Ltim = t[lc].Ltim ;
	}
	if(rc) {
		t[o].res = t[o].res + (t[rc].Ltim - t[o].tim) * t[o].v ;
		t[o].mn = min(t[o].mn , t[o].res) ; t[o].mn = min(t[o].mn , t[o].res + t[rc].mn) ;
		t[o].res = t[o].res + t[rc].res ;
		t[o].rv = t[rc].rv ; t[o].Rtim = t[rc].Rtim ;
	}return ;
}

struct Droot{int r1 , r2 ; } tmp , tmp2 ;
int Merge(int o , int os) {
	if(!o || !os) return o + os ;
	int r ;
	if(Key[o] <= Key[os]) r = o , t[o].rs = Merge(t[o].rs , os) ;
	else if(Key[o] > Key[os]) r = os , t[os].ls = Merge(o , t[os].ls) ;
	PushUp(r) ; return r ;
}

Droot Split(int o , int Lim) {
	if(!o) return (Droot){0 , 0} ;
	Droot r ;
	if(t[o].tim > Lim) r = Split(t[o].ls , Lim) , t[o].ls = r.r2 , r.r2 = o ;
	else r = Split(t[o].rs , Lim) , t[o].rs = r.r1 , r.r1 = o ;
	PushUp(o) ; return r ;
}

void Query(int o , ld &vl) {
	if(vl < 1e-7) {Ans = t[o].Ltim ; flag = true ; return ; }
	if(flag || !o || t[o].mn + vl > 0) return ;
	int lc = t[o].ls , rc = t[o].rs ; ld ret = 0 , delta = 0 ;
	if(lc && !flag) {
		if(t[lc].mn + vl <= 0) {Query(lc , vl) ; return ; }
		ret = ret + t[lc].res ;
		delta = (t[o].tim - t[lc].Rtim) * t[lc].rv ;
		if(vl + ret + delta <= 0) {Ans = t[lc].Rtim + abs(vl + ret) / abs(t[lc].rv) ; flag = true ; return ; }
		ret += delta ;
	}
	if(rc && !flag) {
		delta = (t[rc].Ltim - t[o].tim) * t[o].v ;
		if(vl + ret + delta <= 0) {Ans = t[o].tim + abs(vl + ret) / abs(t[o].v) ; flag = true ; return ; }
		ret += delta ; vl += ret ; Query(rc , vl) ;
	}
	return ;
}

double query(int x,int r,ll v){
	int ls = t[x].ls , rs = t[x].rs ;
	if(ls){
		if(v+t[ls].mn<=0)return query(ls,t[x].tim,v);
		v+=t[ls].res+1ll*t[ls].rv*(t[x].tim-t[ls].Rtim);
		if(v<=0)return t[x].tim-1.0*v/t[ls].rv ;
	}
	if(rs){
		v+=1ll*t[x].v*(t[rs].Ltim-t[x].tim);
		if(v<=0)return t[rs].Ltim-1.0*v/t[x].v;
		if(v+t[rs].mn<=0)return query(rs,r,v);
		v+=t[rs].res;
	}
	v+=1ll*t[x].rv*(r-t[x].Rtim); return r-1.0*v/t[x].rv;
}

void Check(int o) {
    printf("Node%d: ls=%d , rs=%d Ltim=%.0Lf , Rtim=%.0Lf\n" , o , t[o].ls , t[o].rs , t[o].Ltim , t[o].Rtim) ;
	if(t[o].ls) Check(t[o].ls) ;
	if(t[o].rs) Check(t[o].rs) ;
}

map<int , ld > g ;
int main() {
	Q = gi() ; Init() ;
	for(int i = 1; i <= xox; i ++) Key[i] = 1 + rand() % 198919890 ;
	int tm , l , r ; ld s , v ;
	root = 0 ;
	for(int i = 1; i <= Q; i ++) {
		if(q[i].op == 1) {
			tm = lower_bound(X + 1 , X + xox + 1 , q[i].l) - X ; s = q[i].r ;
			tmp = Split(root , q[i].l) ;
			t[tm] = Node(0 , 0 , X[tm] , X[tm] , X[tm] , s , s , 0.0 , 0.0) ;
			root = Merge(Merge(tmp.r1 , tm) , tmp.r2) ;
			g[tm] = s ;
		}
		else if(q[i].op == 2) {
			tm = lower_bound(X + 1 , X + xox + 1 , q[i].l) - X ; s = g[tm] ;
			tmp = Split(root , q[i].l - 1) ;
			tmp2 = Split(tmp.r2 , q[i].l) ;
			root = Merge(tmp.r1 , tmp2.r2) ;
		}
		else if(q[i].op == 3) {
			l = q[i].l ; r = q[i].r ;
			v = q[i].v ;
			flag = false ; Ans = -1 ;
			tmp = Split(root , l - 1) ;
			tmp2 = Split(tmp.r2 , r) ;
			//Check(tmp2.r1) ;

			Query(tmp2.r1 , v) ;
			if(tmp2.r1 && !flag) {
				v = q[i].v + t[tmp2.r1].res ;
				last_speed = t[tmp2.r1].rv ;
				if(last_speed < 0) {
					Ans = t[tmp2.r1].Rtim + v / abs(last_speed) ; flag = true ;
				}
				if(Ans > (ld)r) flag = false ;
			}
			//cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl ;
			if(q[i].v < 1e-7) {
				Ans = l ;
			}
			if(!flag) puts("-1") ;
			else printf("%.8lf\n" , (double)Ans) ;

/*
			int y = tmp2.r1 ;
			if(!v)printf("%d\n",l);
			else {
				if(!y||v+min(t[y].mn,t[y].res+1ll*t[y].rv*(r-t[y].Rtim))>0)puts("-1");
				else printf("%.6lf\n",query(y,r,v));
			}
*/
			root = Merge(Merge(tmp.r1 , tmp2.r1) , tmp2.r2) ;
		}
	}
	return 0 ;
}

#include<cstdio>
#include<algorithm>
#include<set>
#define N_ 200100
#define SZ 262144
#define pli pair<long long,double>
#define pii pair<int,int>
using namespace std;
int X[N_ * 2], CX, INF = 2e9;
int n;
set<pii>Set;
struct point {
	int ck, a, b, c;
}w[N_];
struct Tree {
	long long S[SZ + SZ], M[SZ + SZ], K[SZ + SZ];
	void init() {
		for (int i = 0; i < SZ + SZ; i++)K[i] = INF;
	}
	void Put2(int nd, int b, int e, long long x) {
		S[nd] = x * (X[e + 1] - X[b]);
		M[nd] = min(0ll, S[nd]);
		K[nd] = x;
	}
	void Spread(int nd, int b, int e) {
		if (K[nd] == INF)return;
		int m = (b + e) >> 1;
		Put2(nd * 2, b, m, K[nd]);
		Put2(nd * 2 + 1, m + 1, e, K[nd]);
		K[nd] = INF;
	}
	void UDT(int nd) {
		S[nd] = S[nd * 2] + S[nd * 2 + 1];
		M[nd] = min(M[nd * 2], S[nd * 2] + M[nd * 2 + 1]);
	}
	void Put(int nd, int b, int e, int s, int l, long long x) {
		if (s > l)return;
		if (b == s&&e == l) {
			Put2(nd, b, e, x);
			return;
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (s <= m)Put(nd * 2, b, m, s, min(m, l), x);
		if (l > m)Put(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x);
		UDT(nd);
	}
	double Go(int nd, int b, int e, long long x) {
		if (b == e) {
			auto it = Set.lower_bound({ e + 1,-INF });
			it--;
			return X[b] + ((double)-x / it->second);
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (M[nd * 2] + x <= 0) {
			return Go(nd * 2, b, m, x);
		}
		else {
			return Go(nd * 2 + 1, m + 1, e, x + S[nd * 2]);
		}
	}
	pli Calc(int nd, int b, int e, int s, int l, long long x) {
		int m = (b + e) >> 1;
		if (b == s && e == l) {
			if (M[nd] + x <= 0) {
				return { S[nd], Go(nd, b, e, x) };
			}
			return { S[nd], -1.0 };
		}
		Spread(nd, b, e);
		long long ss = 0;
		if (s <= m) {
			pli t = Calc(nd * 2, b, m, s, min(m, l), x);
			if (t.second > -0.5)return t;
			ss = t.first;
		}
		if (l > m) {
			pli t = Calc(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x + ss);
			if (t.second > -0.5)return t;
			ss += t.first;
		}
		return { ss,-1.0 };

	}
}T;
void Ins(int t, int c) {
	int x = lower_bound(X, X + CX, t) - X;
	Set.insert({ x,c });
	auto it = Set.find({ x,c });
	auto et = it; et++;
	T.Put(1, 0, CX - 1, x, et->first - 1, c);
}
void Del(int t) {

	int x = lower_bound(X, X + CX, t) - X;
	auto it = Set.lower_bound({ x,-INF });
	auto bt = it; bt--;
	auto et = it; et++;
	Set.erase(it);
	T.Put(1, 0, CX - 1, bt->first, et->first - 1, bt->second);

}
int main() {
	int i, ck, a = 0, b = 0, c = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++) {
		scanf("%d", &ck);
		if (ck == 1) {
			scanf("%d%d", &a, &b);
			X[CX++] = a;
		}
		if (ck == 2) {
			scanf("%d", &a);
		}
		if (ck == 3) {
			scanf("%d%d%d", &a, &b, &c);
			X[CX++] = a;
			X[CX++] = b;
		}
		w[i] = { ck,a,b,c };
	}
	X[CX++] = 0;
	X[CX++] = 2e9;
	sort(X, X + CX);
	CX = unique(X, X + CX) - X;
	CX--;
	T.init();
	Set.insert({ 0,0 });
	Set.insert({ CX,0 });
	for (i = 1; i <= n; i++) {
		if (w[i].ck == 1) {
			Ins(w[i].a, w[i].b);
		}
		if (w[i].ck == 2) {
			Del(w[i].a);
		}
		if (w[i].ck == 3) {
			int b = lower_bound(X, X + CX, w[i].a) - X;
			int e = lower_bound(X, X + CX, w[i].b) - X;
			if (w[i].c == 0) {
				printf("%d\n", w[i].a);
				continue;
			}
			if (b == e) {
				printf("-1\n");
				continue;
			}
			auto it = Set.lower_bound({ b,-INF });
			pii tp = *it;
			if (tp.first != b) {
				Ins(w[i].a, 0);
			}
			pli tt = T.Calc(1, 0, CX - 1, b, e - 1, w[i].c);
			if (tp.first != b) {
				Del(w[i].a);
			}
			if (tt.second < 0) {
				printf("-1\n");
			}
			else {
				printf("%.10f\n", tt.second);
			}
		}
	}
}

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author marX
 */

#include <iostream>
#include <fstream>

#include <bits/stdc++.h>

using namespace std;

const long long oo = 2000000000000000000LL + 1;

struct node {
    node *l, *r;
    long long sum;
    long long min_sum;

    node() : l(0), r(0), sum(0), min_sum(0) {}
};

long long get_sum(node *u) {
    return u ? u->sum : 0;
}

long long get_min_sum(node *u) {
    return u ? u->min_sum : 0;
}

void update(node* u, int b, int e, int x, long long v) {
    if (b + 1 == e) {
        u->sum = v;
        u->min_sum = min(0LL, v);
    } else {
        int m = (b + e) / 2;
        if (x < m) {
            if (u->l == nullptr) u->l = new node();
            update(u->l, b, m, x, v);
        } else {
            if (u->r == nullptr) u->r = new node();
            update(u->r, m, e, x, v);
        }
        u->sum = get_sum(u->l) + get_sum(u->r);
        u->min_sum = min(get_min_sum(u->l), get_sum(u->l) + get_min_sum(u->r));
    }
}

int find(node *u, int b, int e, int x, int y, long long &v) {
    if (x <= b && e <= y) {
        if (u->min_sum + v > 0) {
            v += u->sum;
            return -1;
        } else {
            if (b + 1 == e) {
                return b;
            } else {
                int m = (b + e) / 2;
                if (get_min_sum(u->l) + v <= 0)
                    return find(u->l, b, m, x, y, v);
                else {
                    v += get_sum(u->l);
                    return find(u->r, m, e, x, y, v);
                }
            }
        }
    } else {
        int m = (b + e) / 2;

        if (x < m && u->l) {
            auto r = find(u->l, b, m, x, y, v);
            if (r >= 0) return r;
        }

        if (m < y && u->r) {
            auto r = find(u->r, m, e, x, y, v);
            if (r >= 0) return r;
        }

        return -1;
    }
}

class ESashaAndAPatientFriend {
public:
    void solve(std::istream& in, std::ostream& out) {
        const int R = 1000000002;
        out.precision(10);

        auto root = new node();

        int q; in >> q;

        set<long long> active;
        map<long long, long long> speed;

        auto add = [&](long long p, long long s) {
            auto it = active.lower_bound(p);

            if (it != active.end()) {
                update(root, 1, R, p, s * (*it - p));
            } else if (s < 0) {
                update(root, 1, R, p, -oo);
            }

            if (it != active.begin()) {
                auto prev = it; --prev;
                update(root, 1, R, *prev, speed[*prev] * (p - *prev));
            }

            active.insert(p);
            speed[p] = s;
        };

        auto remove = [&](long long p) {
            update(root, 1, R, p, 0);

            auto it = active.lower_bound(p);
            assert(*it == p);

            if (it != active.begin()) {
                auto prev = it; --prev;
                long long r_prev = *prev;

                auto nxt = it; ++nxt;

                if (nxt != active.end()) {
                    long long r_nxt = *nxt;
                    assert(r_nxt > r_prev);
                    update(root, 1, R, *prev, speed[*prev] * (r_nxt - r_prev));
                } else {
                    if (speed[*prev] < 0) {
                        update(root, 1, R, *prev, -oo);
                    } else {
                        update(root, 1, R, *prev, 0);
                    }
                }
            }

            speed.erase(p);
            active.erase(p);
        };

        while (q-->0) {
            int t; in >> t;

            if (t == 1) {
                long long p, s;
                in >> p >> s;
                add(p, s);
            } else if (t == 2) {
                long long p; in >> p;
                remove(p);
            } else {
                long long l, r, v;
                in >> l >> r >> v;

                // TODO
                if (v == 0) {
                    out << l << '\n';
                    continue;
                }

                bool added = false;
                auto it = active.lower_bound(r);
                if (it == active.end() || *it != r) {
                    added = true;
                    add(r, 0);
                }

                auto x = find(root, 1, R, l, r, v);

                if (x == -1) {
                    out << -1 << '\n';
                } else {
                    auto s = speed[x];
                    long double ans = -1. * v / s + x;
                    out << fixed << ans << '\n';
                    // calculate
                }

                if (added) {
                    remove(r);
                }
            }
        }
    }
};

int main() {
	ESashaAndAPatientFriend solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int myrand() {return abs((int) mt());}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

template<typename num_t>
struct node_t {
    node_t *l, *r;
    int h, size, rev;
    num_t key, lz;
    num_t s, ss, mn;
    node_t<num_t> *first_node, *last_node;
    node_t(num_t key, num_t s, node_t* l = 0, node_t* r = 0, int h = rand()) : key(key), s(s), ss(0), mn(0), l(0), r(0), h(h) {
        size = (l ? l->size : 0) + 1 + (r ? r->size : 0);
        rev = lz = 0;
        first_node = last_node = this;
    }
};

template<typename num_t>
int size(node_t<num_t>* x) {
    return x ? x->size : 0;
}
template<typename num_t>
void pull(node_t<num_t>* x) {
    x->size = size(x->l) + 1 + size(x->r);
    x->first_node = x->last_node = x;
    x->ss = 0;
    x->mn = 1e18;
    if (x->l) {
        x->first_node = x->l->first_node;
        x->ss += x->l->ss;
        x->ss += x->l->last_node->s * (x->key - x->l->last_node->key);
        chkmin(x->mn, x->l->mn);
    }
    chkmin(x->mn, x->ss);
    if (x->r) {
        x->last_node = x->r->last_node;
        x->ss += x->s * (x->r->first_node->key - x->key);
        chkmin(x->mn, x->ss + x->r->mn);
        x->ss += x->r->ss;
    }
}
template<typename num_t>
void push(node_t<num_t>* x) {
    node_t<num_t>* u = x->l;
    node_t<num_t>* v = x->r;
    if (x->rev) {
        if (u) swap(u->l, u->r), u->rev ^= 1;
        if (v) swap(v->l, v->r), v->rev ^= 1;
        x->rev = 0;
    }
    if (x->lz) {
        if (u) u->key += x->lz, u->lz += x->lz;
        if (v) v->key += x->lz, v->lz += x->lz;
        x->lz = 0;
    }
}
template<typename num_t>
node_t<num_t>* join(node_t<num_t>* x, node_t<num_t>* y) {
    if (!x) return y;
    if (!y) return x;
    if (x->h < y->h) {
        push(x);
        x->r = join(x->r, y);
        pull(x);
        return x;
    }
    push(y);
    y->l = join(x, y->l);
    pull(y);
    return y;
}
template<typename num_t>
void split(node_t<num_t>* x, node_t<num_t>*& l, node_t<num_t>*& r, int pos) {
    if (!x) {
        l = r = 0;
        return;
    }
    push(x);
    if (size(x->l) + 1 <= pos) {
        split(x->r, x->r, r, pos - size(x->l) - 1);
        pull(l = x);
    }
    else {
        split(x->l, l, x->l, pos);
        pull(r = x);
    }
}
template<typename num_t>
void split(node_t<num_t>* t, node_t<num_t>*& x, node_t<num_t>*& y, node_t<num_t>*& z, int l, int r) {
    split(t, x, y, l);
    split(y, y, z, r - l + 1);
}
template<typename num_t>
void reverse(node_t<num_t>*& x, int l, int r) {
    node_t<num_t> *y, *z;
    split(x, x, y, z, l, r);
    y->rev ^= 1;
    swap(y->l, y->r);
    x = join(x, join(y, z));
}
template<typename num_t>
void upd(node_t<num_t>*& x, int l, int r, num_t val) {
    node_t<num_t> *y, *z;
    split(x, x, y, z, l, r);
    y->lz += val;
    y->key += val;
    x = join(x, join(y, z));
}
template<typename num_t>
void split(node_t<num_t>* x, node_t<num_t>*& l, node_t<num_t>*& r, const function<bool(node_t<num_t>*)>& go_right) {
    if (!x) {
        l = r = 0;
        return;
    }
    push(x);
    if (go_right(x)) {
        split(x->r, x->r, r, go_right);
        pull(l = x);
    }
    else {
        split(x->l, l, x->l, go_right);
        pull(r = x);
    }
}
template<typename num_t>
void insert(node_t<num_t>*& x, num_t key, num_t s) {
    node_t<num_t>* y;
    split<num_t>(x, x, y, [&] (node_t<num_t>* x) {
            return x->key < key;
            }
            );
    x = join(x, join(new node_t<num_t>(key, s), y));
}
template<typename num_t>
node_t<num_t>* erase(node_t<num_t>*& x, num_t key) {
    node_t<num_t> *l, *r, *res;
    split<num_t>(x, l, res, [&] (node_t<num_t>* x) {
            return x->key < key;
            }
            );
    split<num_t>(res, res, r, [&] (node_t<num_t>* x) {
            return x->key <= key;
            }
            );
    x = join(l, r);
    return res;
}
template<typename num_t>
void free(node_t<num_t>* x) {
    if (!x) return;
    free(x->l);
    free(x->r);
    delete x;
}
template<typename num_t>
int depth(node_t<num_t>* x) {
    if (!x) return 0;
    push(x);
    return 1 + max(depth(x->l), depth(x->r));
}
template<typename num_t>
void trace(node_t<num_t>* x, int isrt = 1) {
    if (!x) return;
    push(x);
    trace(x->l, 0);
    cerr << "(" << x->key << ", " << x->s << ", " << x->ss << ") ";
    trace(x->r, 0);
    if (isrt) {
        cerr << "\n";
    }
}
template<typename num_t>
long double query(node_t<num_t>* x, num_t val, node_t<num_t>* prv) {
    node_t<num_t>* r = x->r;
    x->r = 0;
    pull(x);
    num_t ss = x->ss;
    x->r = r;
    pull(x);
    if (x->l && x->l->mn + val <= 0) {
        return query(x->l, val, prv);
    }
    if (ss + val <= 0) {
        if (x->l) prv = x->l->last_node;
        return x->key - (long double) (ss + val) / prv->s;
    }
    if (x->r) {
        return query(x->r, val + ss + x->s * (x->r->first_node->key - x->key), x);
    }
    return -1;
}

const int maxn = 1e5 + 5;
int q;

void chemthan() {
    node_t<long long>* rt = 0;
    cin >> q;
    while (q--) {
        int op; cin >> op;
        if (op == 1) {
            long long t, s; cin >> t >> s;
            insert(rt, t, s);
        }
        else if (op == 2) {
            long long t; cin >> t;
            assert(erase(rt, t));
        }
        else {
            long long l, r, v; cin >> l >> r >> v;
            if (!v) {
                cout << l << "\n";
                continue;
            }
            node_t<long long> *x, *y;
            split<long long>(rt, x, rt, [&] (node_t<long long>* t) {
                    return t->key < l;
                    }
                    );
            split<long long>(rt, rt, y, [&] (node_t<long long>* t) {
                    return t->key <= r;
                    }
                    );
            int fl = 0, fr = 0;
            if (!rt || l < rt->first_node->key) {
                insert<long long>(rt, l, 0);
                fl = 1;
            }
            if (!rt || rt->last_node->key < r) {
                insert<long long>(rt, r, 0);
                fr = 1;
            }
            long double res = query<long long>(rt, v, 0);
            if (fl) {
                erase(rt, l);
            }
            if (fr) {
                erase(rt, r);
            }
            if (res == -1) {
                cout << -1 << "\n";
            }
            else {
                cout << prec(9) << res << "\n";
            }
            rt = join(x, join(rt, y));
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long INT;
#define INF 0x3f3f3f3f3f3f3f3f

int xju[200005];
map<int,int> liss;
int dy[200005];
int lscnt=0;

typedef struct n0de{
	n0de *l,*r;
	INT wc;
	INT mn,fi;
	n0de(){
		l=r=0;
		mn=fi=0;
		wc=INF;
	}
}*node;

inline node newnode(){
	return new n0de();
}

inline void change(node now,int nl,int nr,int l,int r,INT x){
	if(!now->l){
		now->l=newnode();
	}
	if(!now->r){
		now->r=newnode();
	}
	if(now->wc!=INF){
		int m=(nl+nr)>>1;
		now->l->fi=now->wc*(dy[m+1]-dy[nl]);
		now->l->mn=(now->l->fi>=0?0:now->l->fi);
		now->l->wc=now->wc;
		now->r->fi=now->wc*(dy[nr+1]-dy[m+1]);
		now->r->mn=(now->l->fi>=0?0:now->r->fi);
		now->r->wc=now->wc;
		now->wc=INF;
	}
	if(nl>=l&&nr<=r){
		now->wc=x;
		now->fi=now->wc*(dy[nr+1]-dy[nl]);
		now->mn=(now->fi>=0?0:now->fi);
		return;
	}
	if(nr<l||nl>r){
		return;
	}
	int m=(nl+nr)>>1;
	change(now->l,nl,m,l,r,x);
	change(now->r,m+1,nr,l,r,x);
	now->fi=now->l->fi+now->r->fi;
	now->mn=min(now->l->mn,now->l->fi+now->r->mn);
}

inline pair<INT,INT> chmin(node now,int nl,int nr,int l,int r){
	if(l>r){
		return make_pair(0,0);
	}
	if(!now->l){
		now->l=newnode();
	}
	if(!now->r){
		now->r=newnode();
	}
	if(now->wc!=INF){
		int m=(nl+nr)>>1;
		now->l->fi=now->wc*(dy[m+1]-dy[nl]);
		now->l->mn=(now->l->fi>=0?0:now->l->fi);
		now->l->wc=now->wc;
		now->r->fi=now->wc*(dy[nr+1]-dy[m+1]);
		now->r->mn=(now->l->fi>=0?0:now->r->fi);
		now->r->wc=now->wc;
		now->wc=INF;
	}
	if(nl>=l&&nr<=r){
		return make_pair(now->mn,now->fi);
	}
	if(nr<l||nl>r){
		return make_pair(0,0);
	}
	int m=(nl+nr)>>1;
	pair<INT,INT> x=chmin(now->l,nl,m,l,r);
	pair<INT,INT> y=chmin(now->r,m+1,nr,l,r);
	return make_pair(min(x.first,x.second+y.first),x.second+y.second);
}

node root;

inline pair<INT,INT> Chmin(int l,int r){
	if(l>r){
		return make_pair(0,0);
	}
	int L=liss[l];
	map<int,int>::iterator rr=liss.upper_bound(r);
	rr--;
	int R=rr->second,rrr=rr->first;
	pair<INT,INT> x=chmin(root,0,lscnt-1,L,R-1);
	pair<INT,INT> y=chmin(root,0,lscnt-1,R,R);
	return make_pair(min(x.first,x.second+y.first/xju[R]*(r-rrr)),x.second+y.second/xju[R]*(r-rrr));
}

int q;
set<pair<int,INT> > evs;
#define spit set<pair<int,INT> >::iterator
int mmm[100005],lll[100005],rrr[100005],sss[100005];

int main(){
	root=newnode();
	evs.insert(make_pair(1000000000,0));
	evs.insert(make_pair(0,0));
	scanf("%d",&q);
	liss[0];
	liss[1000000000];
	for(int i=0;i<q;i++){
		scanf("%d",&mmm[i]);
		if(mmm[i]==1){
			scanf("%d%d",&lll[i],&sss[i]);
			liss[lll[i]];
		}else if(mmm[i]==2){
			scanf("%d",&lll[i]);
		}else{
			scanf("%d%d%d",&lll[i],&rrr[i],&sss[i]);
		}
	}
	for(map<int,int>::iterator it=liss.begin();it!=liss.end();it++){
		it->second=lscnt;
		dy[lscnt]=it->first;
		if(lscnt){
			xju[lscnt-1]=dy[lscnt]-dy[lscnt-1];
		}
		lscnt++;
	}
	xju[lscnt-1]=1;
	for(int I=0;I<q;I++){
		int mode=mmm[I];
		if(mode==1){
			int t=lll[I],s=sss[I];
			spit xx=evs.upper_bound(make_pair(t,s));
			pair<INT,INT> x=*xx;
			change(root,0,lscnt-1,liss[t],liss[x.first]-1,s);
			evs.insert(make_pair(t,s));
		}else if(mode==2){
			int t=lll[I];
			spit xx=evs.upper_bound(make_pair(t,INF));
			spit yy=xx;yy--;
			spit zz=yy;zz--;
			pair<INT,INT> x=*xx,z=*zz;
			change(root,0,lscnt-1,liss[t],liss[x.first]-1,z.second);
			evs.erase(yy);
		}else{
			int l=lll[I],r=rrr[I],v=sss[I];
			if(v==0){
				printf("%d\n",l);
				continue;
			}
			spit xxx=evs.lower_bound(make_pair(l,-INF));
			int frm=(*xxx).first;
			pair<INT,INT> fff;
			fff=Chmin(frm,r);
			INT rval=fff.first;
			if(rval+v>0){
				puts("-1");
				continue;
			}
			int L=frm,R=r;
			INT lval=0;
			while(R-L>1){
				INT m=(L+R)>>1;
				pair<INT,INT> fff=Chmin(frm,m);
				INT mnx=fff.first;
				if(mnx+v>0){
					L=m;
					lval=fff.second;
				}else{
					R=m;
					rval=fff.second;
				}
			}
			double vv;
			if(rval-lval==0){
				vv=L;
			}else{
				vv=1.00*(-v-lval)/(rval-lval)+L;
			}
			printf("%.10lf\n",vv);
		}
	}
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
	int x=0,w=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')w=0,ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
#define ll long long
const int N=1e5+5;

int ls[N],rs[N],tim[N],spd[N],tL[N],tR[N],spdR[N],rd[N],tot,rt;
ll res[N],mn[N];

void up(int x){
	tL[x]=tR[x]=tim[x];spdR[x]=spd[x];mn[x]=res[x]=0;
	if(ls[x]){
		tL[x]=tL[ls[x]];
		mn[x]=min(mn[x],mn[ls[x]]);
		res[x]+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
		mn[x]=min(mn[x],res[x]);
	}
	if(rs[x]){
		tR[x]=tR[rs[x]];spdR[x]=spdR[rs[x]];
		res[x]+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
		mn[x]=min(mn[x],res[x]+mn[rs[x]]);
		res[x]+=res[rs[x]];
		mn[x]=min(mn[x],res[x]);
	}
}
void split(int x,int k,int &a,int &b){
	if(!x){a=b=0;return;}
	if(tim[x]<=k)a=x,split(rs[x],k,rs[a],b),up(a);
	else b=x,split(ls[x],k,a,ls[b]),up(b);
}
int merge(int x,int y){
	if(!x||!y)return x|y;
	if(rd[x]<rd[y])return rs[x]=merge(rs[x],y),up(x),x;
	else return ls[y]=merge(x,ls[y]),up(y),y;
}

double query(int x,int r,ll v){
//	if(!x)return -1;
//	printf("v=%lld\n",v);
	if(ls[x]){
		if(v+mn[ls[x]]<=0)return query(ls[x],tim[x],v);
		v+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
//		printf("v=%lld\n",v);
		if(v<=0)return tim[x]-1.0*v/spdR[ls[x]];
	}
	if(rs[x]){
		v+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
//		printf("v=%lld\n",v);
		if(v<=0)return tL[rs[x]]-1.0*v/spd[x];
		if(v+mn[rs[x]]<=0)return query(rs[x],r,v);
		v+=res[rs[x]];
	}
	v+=1ll*spdR[x]*(r-tR[x]);
//	printf("v=%lld\n",v);
	if(v<=0)return r-1.0*v/spdR[x];
//	return -1;
}

int main(){
	int q=gi();while(q--){
		int op=gi();
		if(op==1){
			tim[++tot]=gi();spd[tot]=gi();rd[tot]=rand()*rand();
			int x,y;split(rt,tim[tot],x,y);
			up(tot);rt=merge(x,merge(tot,y));
		}else if(op==2){
			int t=gi(),x,y,z;
			split(rt,t,x,z);split(x,t-1,x,y);
			rt=merge(x,z);
		}else{
			int l=gi(),r=gi(),v=gi(),x,y,z;
			if(!v){printf("%d\n",l);continue;}
			split(rt,r,x,z);split(x,l-1,x,y);
//			dfs(y);
			if(!y||v+min(mn[y],res[y]+1ll*spdR[y]*(r-tR[y]))>0)puts("-1");
			else
				printf("%.6lf\n",query(y,r,v));
			rt=merge(x,merge(y,z));
//			++querycnt;
//			if(querycnt==101)return 0;
		}
	}
	return 0;
}

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod7=1000000007LL;
inline ll getint() {
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add(ll _x, ll _y, ll _mod=mod7) {
  _x+=_y;
  return _x>=_mod ? _x-_mod : _x;
}
inline ll sub(ll _x, ll _y, ll _mod=mod7) {
  _x-=_y;
  return _x<0 ? _x+_mod : _x;
}
inline ll mul(ll _x, ll _y ,ll _mod=mod7) {
  _x*=_y;
  return _x>=_mod ? _x%_mod : _x;
}
ll mypow(ll _a, ll _x, ll _mod) {
  if(_x == 0) return 1ll;
  ll _ret = mypow(mul(_a, _a, _mod), _x>>1, _mod);
  if(_x & 1) _ret=mul(_ret, _a, _mod);
  return _ret;
}
ll mymul(ll _a, ll _x, ll _mod) {
  if(_x == 0) return 0ll;
  ll _ret = mymul(add(_a, _a, _mod), _x>>1, _mod);
  if(_x & 1) _ret=add(_ret, _a, _mod);
  return _ret;
}
void sleep(double sec = 1021) {
	clock_t s = clock();
	while(clock() - s < CLOCKS_PER_SEC * sec);
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/

const int mxN=1e5+5, bs=200, bc=(mxN-1)/bs+1;
int nq, n;
array<int, 4> q[mxN];
vector<int> v;
ll s[mxN], ms[bc], ts[bc], lz2[bc];
bool lz1[bc];

void pb(int i) {
	if(lz1[i]) {
		for(int l=i*bs; l<min(n-1, (i+1)*bs); ++l)
			s[l]=lz2[i];
		lz1[i]=0;
	}
}
void ub(int i) {
	ts[i]=ms[i]=0;
	for(int l=i*bs; l<min(n-1, (i+1)*bs); ++l) {
		ts[i]+=s[l]*(v[l+1]-v[l]);
		ms[i]=min(ts[i], ms[i]);
	}
}

//[l, r]
void upd(int l, int r, ll x) {
	//cout << "upd " << l << " " << r << " " << x << endl;
	int bi=l/bs;
	pb(bi);
	for(; l<(bi+1)*bs&&l<=r; ++l)
		s[l]=x;
	//cout << s[3] << " " << s[4] << endl;
	ub(bi++);
	if(l>r)
		return;
	for(; l+bs<=r; l+=bs, ++bi) {
		lz1[bi]=1;
		lz2[bi]=x;
		ts[bi]=(v[l+bs]-v[l])*x;
		if(x>0)
			ms[bi]=0;
		else
			ms[bi]=ts[bi];
	}
	pb(bi);
	for(; l<=r; ++l) {
		s[l]=x;
	}
	ub(bi);
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);

	v.push_back(0);
	v.push_back(1e9+1);
	cin >> nq;
	for(int i=0; i<nq; ++i) {
		cin >> q[i][0] >> q[i][1];
		if(q[i][0]!=2)
			cin >> q[i][2];
		if(q[i][0]==3)
			cin >> q[i][3];
		if(q[i][0]==1)
			v.push_back(q[i][1]);
	}
	sort(v.begin(), v.end());
	v.resize(unique(v.begin(), v.end())-v.begin());
	n=v.size();
	for(int i=0; i<nq; ++i) {
		if(q[i][0]!=3)
			q[i][1]=lower_bound(v.begin(), v.end(), q[i][1])-v.begin();
		//if(q[i][0]==3)
			//q[i][2]=lower_bound(v.begin(), v.end(), q[i][2])-v.begin()-1;
	}
	cout << fixed << setprecision(9);
	//cout << n << endl;
	map<int, int> m{{0, 0}, {n-1, 0}};
	for(int qi=0; qi<nq; ++qi) {
		if(q[qi][0]==1) {
			auto it=m.lower_bound(q[qi][1]);
			upd(q[qi][1], it->first-1, q[qi][2]);
			m[q[qi][1]]=q[qi][2];
		} else if(q[qi][0]==2) {
			m.erase(q[qi][1]);
			auto it1=m.lower_bound(q[qi][1]), it2=it1--;
			upd(it1->first, it2->first-1, it1->second);
		} else {
			int li=lower_bound(v.begin(), v.end(), q[qi][1])-v.begin(), ri=lower_bound(v.begin(), v.end(), q[qi][2])-v.begin()-1;
			li=m.lower_bound(li)->first;
			int bi=li/bs;
			ll c=q[qi][3];
			//if(n>1e3)
				//cout << li << " " << ri << " ";
				//cout << q[qi][2] << " ";
			if(c<=0) {
				cout << q[qi][1] << "\n";
				continue;
			}
			if(li>ri) {
				cout << "-1\n";
				continue;
			}
			bool sc=0;
			pb(bi);
			for(; li<(bi+1)*bs&&li<=ri&&!sc; ++li) {
				//cout << li << " " << s[li] << " " << endl;
				int df=min(q[qi][2], v[li+1])-v[li];
				if(c+df*s[li]<=0) {
					cout << (long double)-c/s[li]+v[li] << "\n";
					sc=1;
				}
				c+=df*s[li];
			}
			if(sc)
				continue;
			++bi;
			for(; li+bs<=ri; li+=bs, ++bi) {
				//cout << li << " " << ts[bi] << " " << ms[bi] << endl;
				if(c+ms[bi]<=0)
					break;
				c+=ts[bi];
			}
			pb(bi);
			for(; li<=ri&&!sc; ++li) {
				int df=min(q[qi][2], v[li+1])-v[li];
				if(c+df*s[li]<=0) {
					cout << (long double)-c/s[li]+v[li] << "\n";
					sc=1;
				}
				c+=df*s[li];
			}
			if(sc)
				continue;
			cout << "-1\n";
		}
	}
}

#include<bits/stdc++.h>

#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct node{
	ll l,r,s;
	node(int l=0,int r=0,int s=0):l(l),r(r),s(s){}
	bool operator<(const node c)const{return l<c.l;}
	bool operator<=(const node c)const{return l<=c.l;}
	node operator+(const int c)const{return node(l+c,r,s);}
};

struct trp{
	node x;
	int ch[2],siz,lll,rrr;
	ll sum,mina;
}t[100005];

int n,rt,tot;

ll getsum(node x){return (x.r-x.l)*x.s;}
int newnode(int l,int r,int s){t[++tot].x=node(l,r,s),t[tot].mina=t[tot].sum=getsum(t[tot].x),t[tot].lll=l,t[tot].rrr=r,t[tot].siz=1;return tot;}

void update(int id){
	t[id].lll=t[id].ch[0]?t[t[id].ch[0]].lll:t[id].x.l,t[id].rrr=t[id].ch[1]?t[t[id].ch[1]].rrr:t[id].x.r;
	t[id].mina=min(min(t[t[id].ch[0]].mina,t[t[id].ch[0]].sum+getsum(t[id].x)),t[t[id].ch[0]].sum+getsum(t[id].x)+t[t[id].ch[1]].mina);
	t[id].sum=t[t[id].ch[0]].sum+t[t[id].ch[1]].sum+getsum(t[id].x);
	t[id].siz=1+t[t[id].ch[0]].siz+t[t[id].ch[1]].siz;
}

ll rnd(){
	static int seed=19260817;
	return (unsigned int)(seed*=48271ll);
}

int merge(int x,int y){
	if(!x||!y) return x+y;
	if(rnd()%(t[x].siz+t[y].siz)<t[x].siz){
		t[x].ch[1]=merge(t[x].ch[1],y); update(x);
		return x;
	}
	else{
		t[y].ch[0]=merge(x,t[y].ch[0]); update(y);
		return y;
	}
}

void split(int now,node k,int &x,int &y){
	if(!now) return (void)(x=y=0);
	if(k<=t[now].x) y=now,split(t[now].ch[0],k,x,t[now].ch[0]);
	else x=now,split(t[now].ch[1],k,t[now].ch[1],y);
	update(now);
}

int findr(int x){
	if(!t[x].ch[1]) return x;
	return findr(t[x].ch[1]);
}

int findl(int x){
	if(!t[x].ch[0]) return x;
	return findl(t[x].ch[0]);
}

double getans(int id,ll v){
	if(t[id].mina+v>0) return -1;
	if(t[t[id].ch[0]].mina+v<=0) return getans(t[id].ch[0],v);
	else if(t[t[id].ch[0]].sum+getsum(t[id].x)+v<=0) return t[t[id].ch[0]].rrr-t[t[id].ch[0]].lll+1.0*(v+t[t[id].ch[0]].sum)/(-t[id].x.s);
	else return t[t[id].ch[0]].rrr-t[t[id].ch[0]].lll+t[id].x.r-t[id].x.l+getans(t[id].ch[1],v+t[t[id].ch[0]].sum+getsum(t[id].x));
}

void print(int id){
	if(!id) return;
	cout<<"TEST "<<t[id].x.l<<' '<<t[id].x.r<<' '<<t[id].x.s<<' '<<getsum(t[id].x)<<' '<<t[id].sum<<' '<<t[id].mina<<' '<<t[id].lll<<' '<<t[id].rrr<<endl;
	print(t[id].ch[0]);
	print(t[id].ch[1]);
}

double query(int l,int r,ll v){
	if(v==0) return l;
	int a,b,c;
	split(rt,node(l),a,b);
	split(b,node(r+1),b,c);
//	cout<<"########################################"<<endl;
//	print(b);
//	cout<<"########################################"<<endl;
	double ret=getans(b,v);
	if(ret==-1){
		rt=merge(merge(a,b),c);
		return -1;
	}
	ret+=t[findl(b)].x.l;
	rt=merge(merge(a,b),c);
	return ret>r?-1:ret;
}

int main(){
	n=readint();
	t[0].mina=1e9+1;
	rt=newnode(0,1e9+1,0);
	int opt,x,y,a,b,c,d;
	for(int i=1;i<=n;i++){
//		print(rt);
		opt=readint(); x=readint();
		if(opt==1){
			split(rt,node(x),a,c);
			split(a,t[findr(a)].x,a,b);
			int tmp=newnode(x,t[b].x.r,readint());
			t[b].x.r=t[b].rrr=x,t[b].sum=t[b].mina=getsum(t[b].x);
			rt=merge(merge(merge(a,b),tmp),c);
		}
		else if(opt==2){
			split(rt,node(x),a,c);
			split(a,t[findr(a)].x,a,b);
			split(c,t[findl(c)].x+1,c,d);
			t[b].x.r=t[b].rrr=d?t[findl(d)].x.l:t[c].x.r,t[b].sum=t[b].mina=getsum(t[b].x);
			rt=merge(merge(a,b),d);
		}
		else{
			y=readint();
			printf("%.10lf\n",query(x,y,readint()));
		}
	}
	return 0;
}

// Code by Denverjin.
#pragma GCC optimize("Ofast", "unroll-loops")
#include <bits/stdc++.h>
using namespace std;

#define ld double
#define ll long long
#define pii pair <int, int>
#define ull unsigned long long
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

#define PI acos(-1)
#define MOD 1000000007
#define MUL 19260817
#define EPS 1e-10
#define INF 1e9
#define LINF 1e18

template <typename T> inline void chkmin(T &x, T y) {if (y < x) x = y;}
template <typename T> inline void chkmax(T &x, T y) {if (y > x) x = y;}

const int SZ = 1 << 13;
char buff[SZ], *pos = buff + SZ - 1;
#define getchar() (++ pos == buff + SZ ? fread(pos = buff, 1, SZ, stdin), *pos : *pos)

inline ll read() {
	ll x = 0; int f = 1, c = getchar();
	for (;!isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = (x<<3) + (x<<1) + (c^48);
	return x * f;
}

const int N = 1 << 18;

ll sum[N << 1], speed[N << 1], mn[N << 1], lazy[N << 1], mul[N << 1];
void init() {rep(i, N << 1) sum[i] =  speed[i] = mn[i] = mul[i] = 0, lazy[i] = -LINF;}
void pd(int i) {
	if (lazy[i] != -LINF) {
		speed[i] = lazy[i];
		sum[i] = lazy[i] * mul[i];
		mn[i] = min(0LL, sum[i]);
		if (i < N) lazy[i << 1] = lazy[i << 1 | 1] = lazy[i];
		lazy[i] = -LINF;
	}
}
void upd(int a, int b, int i, int l, int r, int v) {
	pd(i);
	if (l <= a && b <= r) {lazy[i] = v; pd(i); return;}
	if (r <= a || b <= l) return;
	int md = (a + b) >> 1;
	upd(a, md, i << 1, l, r, v);
	upd(md, b, i << 1 | 1, l, r, v);
	sum[i] = sum[i << 1] + sum[i << 1 | 1];
	mn[i] = min(mn[i << 1], sum[i << 1] + mn[i << 1 | 1]);
}
ll qry(int a, int b, int i, int l, int r) {
	pd(i);
	if (l <= a && b <= r) return sum[i];
	if (r <= a || b <= l) return 0;
	int md = (a + b) >> 1;
	ll L = qry(a, md, i << 1, l, r);
	ll R = qry(md, b, i << 1 | 1, l, r);
	return L + R;
}
struct Ans {
	ll sum, mn;
	Ans() {}
	Ans(ll a, ll b): sum(a), mn(b) {}
};
Ans qrymn(int a, int b, int i, int l, int r) {
	pd(i);
	if (l <= a && b <= r) return Ans(sum[i], mn[i]);
	if (r <= a || b <= l) return Ans(0, 0);
	int md = (a + b) >> 1;
	Ans L = qrymn(a, md, i << 1, l, r);
	Ans R = qrymn(md, b, i << 1 | 1, l, r);
	return Ans(L.sum + R.sum, min(L.mn, L.sum + R.mn));
}
ll qrys(int a, int b, int i, int x) {
	pd(i);
	if (a + 1 == b) return speed[i];
	int md = (a + b) >> 1;
	if (x < md) return qrys(a, md, i << 1, x);
	return qrys(md, b, i << 1 | 1, x);
}
struct P {
	int t, s;
	P() {}
	P(int a, int b): t(a), s(b) {}
	bool operator < (const P &x) const {return t < x.t;}
};

int vt[N], svt;
int qtp[N], qa[N], qb[N], qc[N];
set <P> events;

int main() {
//	freopen("in", "r", stdin);
//	freopen("out", "w", stdout);
	int q = read();
	rep(i, q) {
		qtp[i] = read();
		if (qtp[i] == 1) {
			qa[i] = read();
			qb[i] = read();
			vt[svt ++] = qa[i];
		}
		if (qtp[i] == 2) {
			qa[i] = read();
		}
		if (qtp[i] == 3) {
			qa[i] = read();
			qb[i] = read();
			qc[i] = read();
			vt[svt ++] = qa[i];
			vt[svt ++] = qb[i];
		}
	}
	vt[svt ++] = 0;
	vt[svt ++] = 1e9;
	sort(vt, vt + svt);
	svt = unique(vt, vt + svt) - vt;
	init();
	rep(i, svt - 1) mul[i + N] = vt[i + 1] - vt[i];
	for (int i = N - 1; i; -- i) mul[i] = mul[i << 1] + mul[i << 1 | 1];
	rep(i, q) {
		if (qtp[i] == 1) {
			int t = lower_bound(vt, vt + svt, qa[i]) - vt;
			int s = qb[i];
			set <P> :: iterator it = events.lower_bound(P(t, -1e9));
			int nxt = svt - 1;
			if (it != events.end()) nxt = it -> t;
			events.insert(P(t, s));
			upd(0, N, 1, t, nxt, s);
		}
		if (qtp[i] == 2) {
			int t = lower_bound(vt, vt + svt, qa[i]) - vt;
			set <P> :: iterator it = events.lower_bound(P(t, -1e9));
			it = events.erase(it);
			int nxt = 1e9;
			if (it != events.end()) nxt = it -> t;
			int lst = 0;
			if (it != events.begin()) {-- it; lst = it -> t;}
			int s = qrys(0, N, 1, lst);
			upd(0, N, 1, t, nxt, s);
		}
		if (qtp[i] == 3) {
			int L = lower_bound(vt, vt + svt, qa[i]) - vt;
			int R = lower_bound(vt, vt + svt, qb[i]) - vt;
			int v = qc[i];
			set <P> :: iterator it = events.lower_bound(P(L, -1e9));
			ld ans = -1;
			if (!v) ans = qa[i];
			else if (it != events.end() && it -> t <= R) {
				L = it -> t;
				if (qrymn(0, N, 1, L, R).mn + v <= 0) {
					int lb = L, rb = R;
					while (lb < rb) {
						int md = lb + rb >> 1;
						if (qrymn(0, N, 1, L, md).mn + v <= 0) rb = md;
						else lb = md + 1;
					}
					-- lb;
					ll lft = v + qry(0, N, 1, L, lb);
					ll nws = qrys(0, N, 1, lb);
					ans = vt[lb] - 1.0 * lft / nws;
				}
			}
			printf("%.7f\n", ans);
		}
	}
	return 0;
}

#include <bits/stdc++.h>                                                                                //YaLoh

#define f first
#define s second
#define pb push_back
#define mp make_pair

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;

const int N = (int)1e5 + 123, M = (int)2e5 + 123;
const double eps = 1e-10;

struct node{
	bool empty;
	int l, r;
	ll last, need, carry;
	node(){
		empty = 1;
	}
	node(int t, int s){
		empty = 0;
		l = r = t;
		last = s;
		need = carry = 1;
	}
    void Merge(node a, node b){
		if(a.empty && b.empty){
			empty = 1;
			return;
		}
		empty = 0;
		if(a.empty){
			l = b.l;
			r = b.r;
			last = b.last;
			need = b.need;
			carry = b.carry;
			return;
		}
        if(b.empty){
			l = a.l;
			r = a.r;
			last = a.last;
			need = a.need;
			carry = a.carry;
			return;
		}
		l = a.l;
		r = b.r;
		last = b.last;
		if(a.last < 0)
			b.need -= (b.l - a.r) * a.last;
		else
			a.carry += (b.l - a.r) * a.last;
		if(a.carry >= b.need){
			need = a.need;
			carry = a.carry - b.need + b.carry;
		}else{
			need = a.need + b.need - a.carry;
			carry = b.carry;
		}
	}
} t[M << 2];
int n, q, type[N], ti[N], s[N], l[N], r[N], w[N];
vector< int > vec;

ll ss, tt, cur;
bool was, fnd;
double ans;
void build(int v, int tl, int tr){
	if(tl == tr){
		t[v] = node();
		return;
	}
	int tm = (tl + tr) >> 1;
	build(v << 1, tl, tm);
	build(v << 1 | 1, tm + 1, tr);
	t[v].Merge(t[v << 1], t[v << 1 | 1]);
}
void upd(int v, int tl, int tr, int pos, int val){
	if(tl == tr){
		t[v] = node(vec[pos - 1], val);
		return;
	}
	int tm = (tl + tr) >> 1;
	if(pos <= tm)
		upd(v << 1, tl, tm, pos, val);
	else
		upd(v << 1 | 1, tm + 1, tr, pos, val);
	t[v].Merge(t[v << 1], t[v << 1 | 1]);
}
void del(int v, int tl, int tr, int pos){
	if(tl == tr){
		t[v] = node();
		return;
	}
	int tm = (tl + tr) >> 1;
	if(pos <= tm)
		del(v << 1, tl, tm, pos);
	else
		del(v << 1 | 1, tm + 1, tr, pos);
	t[v].Merge(t[v << 1], t[v << 1 | 1]);
}
void get(int v, int tl, int tr, int l){
	if(tr < l || fnd)
		return;
	int tm = (tl + tr) >> 1;
	if(l <= tl){
		if(!t[v].empty){
			if(!was){
				was = 1;
				tt = t[v].l;
				ss = 0;
			}
			if(cur + (t[v].l - tt) * ss < 1){
				fnd = 1;
				ans = tt - 1.0 * cur / ss;
				return;
			}
			cur += (t[v].l - tt) * ss;
			tt = t[v].l;
			if(cur >= t[v].need){
				tt = t[v].r;
				ss = t[v].last;
				cur = cur - t[v].need + t[v].carry;
				return;
			}
			get(v << 1, tl, tm, l);
			get(v << 1 | 1, tm + 1, tr, l);
		}
		return;
	}
	get(v << 1, tl, tm, l);
	get(v << 1 | 1, tm + 1, tr, l);
}
int main()
{
	scanf("%d", &q);
	for(int i = 1; i <= q; i++){
		scanf("%d", &type[i]);
		if(type[i] == 1){
			scanf("%d%d", &ti[i], &s[i]);
			vec.pb(ti[i]);
		}
        if(type[i] == 2){
        	scanf("%d", &ti[i]);
		}
		if(type[i] == 3){
			scanf("%d%d%d", &l[i], &r[i], &w[i]);
			vec.pb(l[i]);
			vec.pb(r[i]);
		}
	}
	sort(vec.begin(), vec.end());
	n = vec.size();
	build(1, 1, n);
    for(int i = 1; i <= q; i++){
		if(type[i] == 1){
			int id = lower_bound(vec.begin(), vec.end(), ti[i]) - vec.begin() + 1;
			upd(1, 1 , n, id, s[i]);
		}
        if(type[i] == 2){
			int id = lower_bound(vec.begin(), vec.end(), ti[i]) - vec.begin() + 1;
			del(1, 1 , n, id);
		}
		if(type[i] == 3){
			if(w[i] == 0){
				printf("%.10f\n", 0.0 + l[i]);
				continue;
			}
			int id = lower_bound(vec.begin(), vec.end(), l[i]) - vec.begin() + 1;
			fnd = was = 0;
			cur = w[i];
			get(1, 1, n, id);
			if(!fnd){
				if(was){
					if(ss >= 0)
						ans = 2e9;
					else
						ans = tt - 1.0 * cur / ss;
				}else{
					ans = -1;
				}
			}
			if(ans > r[i])
				ans = -1;
		    if(ans == -1)
		    	printf("-1\n");
			else
				printf("%.10f\n", ans);
		}
	}
	return 0;
}

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define MAX 100100
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
struct Data{int k,t;ll s,mxs;};
Data operator+(Data a,Data b)
{
	Data c;c.k=b.k;
	c.s=a.s+b.s;c.t=a.t+b.t;
	c.mxs=max(a.mxs,b.mxs+a.s);
	return c;
}
struct Node
{
	int ff,ch[2];
	int k,t,len;
	Data a;
	Data Pre(){return (Data){k,len,1ll*k*len,max(1ll*k*len,0ll)};}
}t[MAX];
int rt,tot;
void pushup(int x){t[x].a=t[lson].a+t[x].Pre()+t[rson].a;}
void rotate(int x)
{
	int y=t[x].ff,z=t[y].ff;
	int k=t[y].ch[1]==x;
	if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
	t[y].ch[k]=t[x].ch[k^1];if(t[x].ch[k^1])t[t[x].ch[k^1]].ff=y;
	t[x].ch[k^1]=y;t[y].ff=x;
	pushup(y);pushup(x);
}
void Splay(int x,int goal)
{
	while(t[x].ff!=goal)
	{
		int y=t[x].ff,z=t[y].ff;
		if(z!=goal)
			(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
		rotate(x);
	}
	if(!goal)rt=x;
}
void Insert(int a,int s)
{
	int x=rt,f=0;
	while(233)
	{
		if(t[x].t>a)f=x,x=lson;
		else f=x,x=rson;
		if(!x)break;
	}
	int k=t[f].t<a;x=++tot;
	if(f)t[f].ch[k]=x;t[x].ff=f;
	t[x].t=a;t[x].k=s;Splay(x,0);
}
int Next(int a,int p)
{
	int x=rt,u=0;bool fl=false;
	while(233)
	{
		if(t[x].t==a){fl=true;break;}
		int k=t[x].t<a;
		if(p^k)u=x;
		if(!t[x].ch[k])break;
		x=t[x].ch[k];
	}
	if(!fl)return u;
	if(!t[x].ch[p])return u;
	else x=t[x].ch[p];
	while(t[x].ch[p^1])x=t[x].ch[p^1];
	return x;
}
void Adding(int a,int s)
{
	Insert(a,s);
	int nw=tot,lt=Next(a,0),nt=Next(a,1);
	Splay(lt,0);t[lt].len=a-t[lt].t;pushup(lt);
	Splay(nw,0);t[nw].len=t[nt].t-a;pushup(nw);
}
void Delete(int a)
{
	int uL=Next(a,0),uR=Next(a,1);
	Splay(uL,0);Splay(uR,uL);
	t[uR].ch[0]=0;
	pushup(uR);
	t[uL].len=t[uR].t-t[uL].t;
	pushup(uL);
}
double Query(int l,int r,ll V)
{
	if(!V)return l;
	int uL=Next(l,0),uR=Next(r,1),QwQ;
	Splay(uL,0);Splay(uR,uL);
	int nw=t[uR].ch[0];QwQ=nw;
	if(t[nw].a.mxs<V)return -1;
	while(t[QwQ].ch[0])QwQ=t[QwQ].ch[0];
	int u=nw;Data now=(Data){0,0,0,0};
	while(233)
	{
		Data pre=now+t[t[u].ch[0]].a+t[u].Pre();
		if(pre.mxs<V)now=pre,u=t[u].ch[1];
		else
		{
			Data qwq=now+t[t[u].ch[0]].a;
			if(qwq.mxs<V)return 1.0*(V-qwq.s)/t[u].k+t[u].t;
			u=t[u].ch[0];
		}
		if(!u)return -1;
	}
}
int main()
{
	Insert(0,0);Insert(2e9+1,0);
	int Q=read();
	while(Q--)
	{
		int opt=read();
		if(opt==1)
		{
			int a=read(),s=read();
			Adding(a,-s);
		}
		else if(opt==2)Delete(read());
		else
		{
			int l=read(),r=read(),V=read();
			double s=Query(l,r,V);
			if(s>r)puts("-1");
			else printf("%.10lf\n",s);
		}
	}
	return 0;
}

#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <chrono>
#include <random>
#include <iostream>
#define FOR(i, n) for(int i = 0; i < n; i++)
#define D(x) cout << #x << ": " << x << endl;
using namespace std;

typedef pair<int,int> pii;
typedef long long ll;

#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)

#define time__(d) \
    for ( \
        auto blockTime = make_pair(chrono::high_resolution_clock::now(), true); \
        blockTime.second; \
        debug("%s: %ld ms\n", d, chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - blockTime.first).count()), blockTime.second = false \
    )

mt19937 rng (chrono::steady_clock::now().time_since_epoch().count());

const int MAXN = 100100;
const int inf = (int)1e9 + 1000;
const ll infll = (ll)1e18 + 1000;

int getRandom () {
	return uniform_int_distribution<int>(-inf, inf)(rng);
}

struct Node {
	int time, speed, pr;
	int sz;
	int tL, tR, speedR;
	ll sum, minSum;
	int l, r;
};

Node tree[MAXN];
int cnt = 1;

int getNode () {
	return cnt++;
}

int sz (int t) {
	return t ? tree[t].sz : 0;
}

void update (int v) {
	if (!v) return;
	int l = tree[v].l, r = tree[v].r;
	tree[v].sz = 1 + sz (l) + sz (r);
	tree[v].tL = tree[v].tR = tree[v].time;
	tree[v].speedR = tree[v].speed;
	tree[v].sum = 0;
	tree[v].minSum = 0;
	ll gap1, gap2;
	if (l) {
		tree[v].tL = tree[l].tL;
		gap1 = (ll) (tree[v].time - tree[l].tR) * tree[l].speedR;
		tree[v].sum += tree[l].sum + gap1;
		tree[v].minSum = min (tree[v].minSum, min (tree[l].minSum, tree[v].sum));
	}
	if (r) {
		tree[v].tR = tree[r].tR;
		tree[v].speedR = tree[r].speedR;
		gap2 = (ll) (tree[r].tL - tree[v].time) * tree[v].speed;
		tree[v].sum += gap2 + tree[r].sum;
		if (!l) tree[v].minSum = min (tree[v].minSum, min (gap2, gap2 + tree[r].minSum));
	}
	if (l && r) tree[v].minSum = min (tree[v].minSum, tree[l].sum + gap1 + gap2 + tree[r].minSum);
	tree[v].minSum = min (tree[v].minSum, tree[v].sum);
}

void split (int t, int &L, int &R, int val) {
	if (!t) {
		L = R = 0;
	} else if (val >= tree[t].time) {
		split (tree[t].r, tree[t].r, R, val);
		L = t;
	} else {
		split (tree[t].l, L, tree[t].l, val);
		R = t;
	}
	update (t);
}

void merge (int &t, int l, int r) {
	if (!l || !r) {
		t = l ? l : r;
	} else if (tree[l].pr > tree[r].pr) {
		merge (tree[l].r, tree[l].r, r);
		t = l;
	} else {
		merge (tree[r].l, l, tree[r].l);
		t = r;
	}
	update (t);
}

void insert (int &t, int it) {
	if (!t) {
		t = it;
	} else if (tree[it].pr > tree[t].pr) {
		split (t, tree[it].l, tree[it].r, tree[it].time);
		t = it;
	} else {
		insert (tree[it].time >= tree[t].time ? tree[t].r : tree[t].l, it);
	}
	update (t);
}

void erase (int &t, int val) {
	if (!t) return;
	else if (tree[t].time == val) {
		merge (t, tree[t].l, tree[t].r);
	} else {
		erase (val > tree[t].time ? tree[t].r : tree[t].l, val);
	}
	update (t);
}

bool member (int t, int val) {
	if (!t) return false;
	if (tree[t].time == val) return true;
	if (val > tree[t].time) return member (tree[t].r, val);
	return member (tree[t].l, val);
}

void printTreap (int t) {
	if (!t) return;
	printTreap (tree[t].l);
	printf("((%d-%d), %d, %d, %lld, %lld) ", tree[t].tL, tree[t].tR, tree[t].time, tree[t].speed, tree[t].sum, tree[t].minSum);
	printTreap (tree[t].r);
}

double query (int t, ll v) {
	//printf("(%d - %d): ", tree[t].tL, tree[t].tR); D(tree[t].minSum);
	if (tree[t].minSum + v > 0) return -1;
	int l = tree[t].l, r = tree[t].r;
	if (l) {
		if (v + tree[l].minSum <= 0) return query (l, v);
		ll gap1 = (ll) tree[l].speedR * (tree[t].time - tree[l].tR);
		if (v + tree[l].sum + gap1 <= 0) return (double) (v + tree[l].sum) / -tree[l].speedR + tree[l].tR;
		v += tree[l].sum + gap1;
	}
	if (r) {
		ll gap2 = (ll) tree[t].speed * (tree[r].tL - tree[t].time);
		if (v + gap2 <= 0) return (double) (v) / -tree[t].speed + tree[t].time;
		v += gap2;
		return query (r, v);
	}
	printf("This should never happen!!\n");
	return -1; // should never happen
}

void printTreap (int t, const char s[100]) {
	printf("%s : ", s); printTreap (t); printf("\n");
}

double query (int &t, int a, int b, int v) {
	int l, r;
	if (v == 0) return a;
	split (t, l, r, a - 1);
	//printTreap (l, "left");
	//printTreap (r, "right");
	//D(gap);
	double ret;
	ret = query (r, v);
	merge (t, l, r);
	return ret;
}
int q;

void load() {
	scanf("%d", &q);
}

void solve() {
	int t = 0;
	int it = getNode ();
	tree[it].time = tree[it].speed = 0;
	tree[it].pr = getRandom ();
	insert (t, it);
	it = getNode();
	tree[it].time = inf;
	tree[it].speed = 0;
	tree[it].pr = getRandom ();
	insert (t, it);
	while (q--) {
		int a, b, c, d;
		scanf("%d", &a);
		if (a == 1) {
			scanf("%d%d", &b, &c);
			it = getNode ();
			tree[it].time = b;
			tree[it].speed = c;
			tree[it].pr = getRandom ();
			insert (t, it);
		} else if (a == 2) {
			scanf("%d", &b);
			erase (t, b);
		} else {
			scanf("%d%d%d", &b, &c, &d);
			double sol = query (t, b, c, d);
			if (sol > -1e-9 && sol - 1e-9 < c) printf("%.10lf\n", sol);
			else printf("-1\n");
		}
		//printTreap (t); printf("\n");
	}
}

int main() {
	load();
	solve();
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using pi = pair<int, int>;
const int MAXN = 100005;
const int MAXT = 270000;

struct seg{
	lint tree[MAXT], lazy[MAXT];
	void lazydown(int p){
		tree[2*p] += lazy[p];
		tree[2*p+1] += lazy[p];
		lazy[2*p] += lazy[p];
		lazy[2*p+1] += lazy[p];
		lazy[p] = 0;
	}
	void upd(int s, int e, int ps, int pe, int p, lint v){
		if(e < ps || pe < s) return;
		if(s <= ps && pe <= e){
			tree[p] += v;
			lazy[p] += v;
			return;
		}
		lazydown(p);
		int pm = (ps+pe)/2;
		upd(s, e, ps, pm, 2*p, v);
		upd(s, e, pm+1, pe, 2*p+1, v);
		tree[p] = min(tree[2*p], tree[2*p+1]);
	}
	lint query(int s, int e, int ps, int pe, int p){
		if(e < ps || pe < s) return 5e18;
		if(s <= ps && pe <= e) return tree[p];
		lazydown(p);
		int pm = (ps+pe)/2;
		return min(query(s, e, ps, pm, 2*p), query(s, e, pm+1, pe, 2*p+1));
	}

}seg;

int q;
int t[MAXN], x[MAXN], l[MAXN], r[MAXN], vel[MAXN];
lint val[MAXN];
map<int, int> mp;

void upd(int x, lint v){
	seg.upd(x, q, 0, q, 1, v - val[x]); // partial sum add
	val[x] = v;
}

int query(int st, int ed, int v){
	lint ret = seg.query(st-1, st-1, 0, q, 1);
	if(seg.query(st, ed - 1, 0, q, 1) - ret > v){
		return -1;
	}
	int s = st, e = ed - 1;
	while(s != e){
		int m = (s + e) / 2;
		if(seg.query(st, m, 0, q, 1) - ret <= v) e = m;
		else s = m + 1;
	}
	return s;
}

lint getsum(int s, int e){
	lint ret = seg.query(e, e, 0, q, 1) - seg.query(s-1, s-1, 0, q, 1);
	return ret;
}

int main(){
	scanf("%d",&q);
	vector<int> v = {-1};
	for(int i=0; i<q; i++){
		scanf("%d",&t[i]);
		if(t[i] == 1){
			scanf("%d %d",&x[i],&vel[i]);
		}
		if(t[i] == 2){
			scanf("%d",&x[i]);
		}
		if(t[i] == 3){
			scanf("%d %d %d",&l[i],&r[i],&vel[i]);
		}
		if(t[i] != 3) v.push_back(x[i]);
		else v.push_back(r[i]);
	}
	sort(v.begin(), v.end());
	v.resize(unique(v.begin(), v.end()) - v.begin());
	auto getcrd = [&](int x){
		return lower_bound(v.begin(), v.end(), x) - v.begin();
	};
	auto ERASE = [&](int x){
		upd(getcrd(x), 0);
		mp.erase(mp.find(x));
		auto l = mp.lower_bound(x);
		if(l != mp.begin()){
			auto prv = prev(l);
			if(l == mp.end()) upd(getcrd(prv->first), 0);
			else upd(getcrd(prv->first), 1ll * (l->first - prv->first) * prv->second);
		}
	};
	auto INSERT = [&](int x, int v){
		auto l = mp.lower_bound(x);
		if(l != mp.begin()){
			auto prv = prev(l);
			upd(getcrd(prv->first), 1ll * (x - prv->first) * prv->second);
		}
		mp[x] = v;
		l = mp.find(x);
		if(next(l) != mp.end()){
			auto nxt = next(l);
			upd(getcrd(x), 1ll * (nxt->first - x) * v);
		}
	};
	for(int i=0; i<q; i++){
		if(t[i] == 1){
			if(mp.find(x[i]) != mp.end()){
				ERASE(x[i]);
			}
			INSERT(x[i], vel[i]);
		}
		if(t[i] == 2){
			ERASE(x[i]);
		}
		if(t[i] == 3){
			if(vel[i] == 0){
				printf("%d\n", l[i]);
				continue;
			}
			int st = lower_bound(v.begin(), v.end(), l[i]) - v.begin();
			int ed = lower_bound(v.begin(), v.end(), r[i]) - v.begin();
			if(st == ed){
				puts("-1");
				continue;
			}
			bool flag = 0;
			if(mp.find(r[i]) == mp.end()){
				INSERT(r[i], 0);
				flag = 1;
			}
			lint ret = 0;
			int interesting = query(st, ed, -vel[i]);
			if(interesting != -1){
				ret = getsum(st, interesting);
				auto itr = mp.upper_bound(v[interesting]);
				int prv_speed = mp[v[interesting]];
				lint eudori = -vel[i] - ret;
				printf("%.10f\n", itr->first - 1.0 * eudori / (-prv_speed));
			}
			else{
				puts("-1");
			}
			if(flag){
				ERASE(r[i]);
			}
		}
	}
}

#include<bits/stdc++.h>
using namespace std;
#define pr pair<LL,LL>
#define mk(a,b) make_pair(a,b)
#define LL long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

const int maxn=3e5+5;
struct NODE{
    LL mn,edsum,edval,bgpos;
    int l,r;//离散化前表示的区间
    NODE(){
        mn=edval=bgpos=edsum=0;
    }
    NODE operator +(const NODE&p)const{
        NODE tp;
    //    printf("r=%d p.l=%d\n",r,p.l);
        assert(r+1==p.l);
        if(p.bgpos==0){
            tp.edsum=edsum+edval*(p.r-p.l+1);
            tp.edval=edval;
            tp.bgpos=bgpos;
            tp.mn=min(mn,tp.edsum);
            tp.l=l,tp.r=p.r;
        }else{
            tp.edsum=edsum+p.edsum+edval*(p.bgpos-r-1);
            tp.edval=p.edval;
            tp.bgpos=bgpos==0?p.bgpos:bgpos;
            tp.mn=min(mn,edsum+p.mn+edval*(p.bgpos-r-1));
            tp.l=l,tp.r=p.r;
        }
        return tp;
    }
    void print(){
        printf("l=%d r=%d mn=%lld edsum=%lld edval=%lld bgpos=%lld\n",l,r,mn,edsum,edval,bgpos);
    }
}T[maxn<<2];
//LL mn[maxn<<2],ed[maxn<<2];
    vector<int>v;
void updata(int rt){
    T[rt]=T[rt<<1]+T[rt<<1|1];
}
void build(int l,int r,int rt){
    if(l==r){
        T[rt]=NODE();
        T[rt].l=v[l-1];
        assert(l<=v.size());
        if(l==v.size())T[rt].r=v[l-1];
        else T[rt].r=(v[l]-1);
    //    printf("pos=%d l=%d r=%lld\n",l,T[rt].l,T[rt].r);
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
 //   printf("l=%d r=%d\n",l,r);
    updata(rt);
}
const int inf=1e9+7;
void modify(int l,int r,int rt,int pos,int val){
    if(l==r){
        if(val==inf){
            NODE tp=NODE();
            tp.l=T[rt].l,tp.r=T[rt].r;
            T[rt]=tp;
            return;
        }else{
            T[rt].edsum=(LL)val*(LL)(T[rt].r-T[rt].l+1);
            T[rt].mn=min(0ll,T[rt].edsum);
            T[rt].bgpos=T[rt].l;
            T[rt].edval=val;
         //   mn[rt]=min(0ll,ed[rt]);
            return;
        }
    }
    int mid=(l+r)>>1;
    if(pos<=mid)modify(lson,pos,val);
    else modify(rson,pos,val);
    updata(rt);
}
NODE query(int l,int r,int rt,int nl,int nr){
 //   printf("l=%d r=%d ed=%lld mn=%lld\n",l,r,ed[rt],mn[rt]);
 //   if(nl>nr)return mk(0,0);
    assert(nl<=nr);
    if(nl<=l&&nr>=r){
        return T[rt];
    }
    int mid=(l+r)>>1;
    if(nl<=mid&&nr>mid){
        return query(lson,nl,nr)+query(rson,nl,nr);
    //    return mk(u.first+v.first,min(u.second,u.first+v.second));
    }else if(nl<=mid)return query(lson,nl,nr);
    else if(nr>mid)return query(rson,nl,nr);
}
void print(int l,int r,int rt){
    printf("l=%d r=%d rt=%d\n",l,r,rt);
    T[rt].print();
    if(l==r)return;
    int mid=(l+r)>>1;
    print(lson);
    print(rson);
}
namespace santongding{
    struct Q{
        int l,r,v,ck;
    }qr[maxn];
    double solve(int l,int r,int val){
    //    puts("@!#");
        if(l==r){
        //    puts("!!!");
            if(val==0)return l;
            else return -1.0;
        }
        assert(l<r);
        r--;
        NODE ans=query(1,v.size(),1,l,r);
        if(ans.mn+val>0)return -1.0;
        int bg=l;
        while(l!=r){
            int mid=(l+r)>>1;
        //    printf("l=%d r=%d\n",l,r);
            NODE tp=query(1,v.size(),1,bg,mid);
            if(tp.mn+val<=0){
                r=mid;
            }else{
                l=mid+1;
            }
        }
    //    printf("bg=%d l=%d\n",bg,l);
      //  printf("%lld %lld \n",ans.first,ans.second);
     //   exit(0);
     //   if(ans.edsum+val>0)return -1.0;
     //   puts("!(@");
        ans=query(1,v.size(),1,bg,l);
        assert(ans.edval<0);
        assert(ans.mn==ans.edsum);
  //      ans.print();
    //    exit(0);
      //  printf("%lld %lld %lld %lld\n",a.first,a.second,b.first,b.second);
        return (double)ans.r+1.0-(double)(ans.edsum+val)/(double)ans.edval;

    }
    int getpos(int pos){
        return lower_bound(v.begin(),v.end(),pos)-v.begin()+1;
    }
    void solve(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&qr[i].ck);
            if(qr[i].ck==1){
                scanf("%d%d",&qr[i].l,&qr[i].v);
                v.push_back(qr[i].l);
            }
            else if(qr[i].ck==2){
                scanf("%d",&qr[i].l);
                v.push_back(qr[i].l);
            }else{
                scanf("%d%d%d",&qr[i].l,&qr[i].r,&qr[i].v);
                v.push_back(qr[i].l);
                v.push_back(qr[i].r);
            }
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
     //   printf("siz=%d\n",v.size());
    //    for(auto x:v)printf("%d ",x);
     //   puts("");
        build(1,v.size(),1);
      //  print(1,v.size(),1);
        for(int i=1;i<=n;i++){
            if(qr[i].ck==1)modify(1,v.size(),1,getpos(qr[i].l),qr[i].v);
            else if(qr[i].ck==2)modify(1,v.size(),1,getpos(qr[i].l),inf);
            else{
            //    print(1,v.size(),1);
           //     exit(0);
                if(qr[i].v==0){
                    printf("%d\n",qr[i].l);
                }else{
                printf("%.8f\n",solve(getpos(qr[i].l),getpos(qr[i].r),qr[i].v));
                }
            }
        }
    }
}
int main(){
//   freopen("in.txt","r",stdin);
    int t=1;
//    scanf("%d",&t);
    while(t--){
        santongding::solve();
    }
}

#include <bits/stdc++.h>

typedef long long LL;
const int N = 800005;

int q;

int opt[N], x[N], y[N];
LL z[N];
int val[N], tot;

std::set<int> set;

int prev(int x) {
	std::set<int>::iterator it = set.find(x);
	return it == set.begin() ? 0 : *--it;
}
int next(int x) {
	std::set<int>::iterator it = set.find(x);
	return ++it == set.end() ? tot : *it;
}

int weight[N];
LL tag[N], min[N], max[N];

void setadd(int o, LL v) { tag[o] += v, min[o] += v, max[o] += v; }
void pushdown(int o) { setadd(o << 1, tag[o]), setadd(o << 1 | 1, tag[o]), tag[o] = 0; }
void pushup(int o) {
	min[o] = std::min(min[o << 1], min[o << 1 | 1]);
	max[o] = std::max(max[o << 1], max[o << 1 | 1]);
}

void modify(int L, int R, LL v, int o = 1, int l = 1, int r = tot) {
	if (L <= l && R >= r) return setadd(o, v);
	int mid = l + r >> 1; pushdown(o);
	if (L <= mid) modify(L, R, v, o << 1, l, mid);
	if (R > mid) modify(L, R, v, o << 1 | 1, mid + 1, r);
	pushup(o);
}
LL query(int pos, int o = 1, int l = 1, int r = tot) {
	if (l == r) return min[o];
	int mid = l + r >> 1; pushdown(o);
	if (pos <= mid)
		return query(pos, o << 1, l, mid);
	else
		return query(pos, o << 1 | 1, mid + 1, r);
}

int find(int L, LL val, bool &m, bool &M, int o = 1, int l = 1, int r = tot) {
	if (L <= l && (!(m || min[o] <= val) || !(M || max[o] >= val)))
		return m |= min[o] <= val, M |= max[o] >= val, -1;
	if (l == r) return l;
	int mid = l + r >> 1; pushdown(o);
	int ret = -1;
	if (L <= mid)
		ret = find(L, val, m, M, o << 1, l, mid);
	if (ret != -1) return ret;
	return find(L, val, m, M, o << 1 | 1, mid + 1, r);
}

int main() {
	std::ios::sync_with_stdio(0), std::cin.tie(0);
	std::cin >> q;
	for (int i = 1; i <= q; ++i) {
		std::cin >> opt[i];
		if (opt[i] == 1)
			std::cin >> x[i] >> y[i], val[++tot] = x[i];
		else if (opt[i] == 2) std::cin >> x[i];
		else {
			std::cin >> x[i] >> y[i] >> z[i];
			val[++tot] = x[i], val[++tot] = y[i];
		}
	}
	val[++tot] = 1e9, val[++tot] = 0;
	std::sort(val + 1, val + tot + 1);
	tot = std::unique(val + 1, val + tot + 1) - val - 1;
	for (int i = 1; i <= q; ++i) {
		x[i] = std::lower_bound(val + 1, val + tot + 1, x[i]) - val;
		if (opt[i] == 3)
			y[i] = std::lower_bound(val + 1, val + tot + 1, y[i]) - val;
	}
	for (int i = 1; i <= q; ++i) {
		if (opt[i] == 1) {
			set.insert(x[i]), weight[x[i]] = y[i];
			int pre = prev(x[i]), nxt = next(x[i]);
			if (nxt > x[i]) modify(x[i], nxt - 1, (LL) (val[x[i]] - val[pre]) * weight[pre]);
			modify(nxt, tot, (LL) (val[nxt] - val[x[i]]) * (weight[x[i]] - weight[pre]));
		} else if (opt[i] == 2) {
			int pre = prev(x[i]), nxt = next(x[i]);
			set.erase(x[i]);
			if (nxt > x[i]) modify(x[i], nxt - 1, (LL) -(val[x[i]] - val[pre]) * weight[pre]);
			modify(nxt, tot, (LL) -(val[nxt] - val[x[i]]) * (weight[x[i]] - weight[pre]));
		} else {
			if (z[i] == 0) {std::cout << val[x[i]] << '\n'; continue; }
			std::set<int>::iterator it = set.lower_bound(x[i]);
			if (it == set.end() || *it > y[i]) {std::cout << "-1\n"; continue; }
			x[i] = *it, z[i] = query(x[i]) - z[i];
			bool m = 0, M = 0;
			int q = find(x[i], z[i], m, M);
			if (q == -1) {std::cout << "-1\n"; continue; }
			int lst = prev(q); z[i] -= query(lst);
			if (weight[lst] > 0) {
				if (z[i] > (LL) (val[y[i]] - val[lst]) * weight[lst]) {std::cout << "-1\n"; continue; }
			} else {
				if (z[i] < (LL) (val[y[i]] - val[lst]) * weight[lst]) {std::cout << "-1\n"; continue; }
			}
			std::cout << std::fixed << std::setprecision(10) << val[lst] + (double)z[i] / weight[lst] << '\n';
		}
	}
	return 0;
}

#include <bits/stdc++.h>
using std::cerr;using std::cin;using std::cout;using std::abs;using std::min;using std::max;using std::swap;using std::map;using std::unordered_map;using std::unordered_set;using std::bitset;using std::pair;using std::set;using std::string;using std::vector;using std::sort;using ll=long long;using uint=unsigned int;using pii=pair<int,int>;using pll=pair<ll,ll>;using ull = unsigned long long;using ld=long double;using vci=vector<int>;using vcl=vector<ll>;template<typename T>void _dbg(const char*_s,T _h){cerr<<_s<<" = "<<_h<<"\n";}template<typename T,typename...Ts>void _dbg(const char*_s,T _h,Ts..._t){int _b=0;while(((_b+=*_s=='(')-=*_s==')')!=0||*_s!=',')cerr<<*_s++;cerr<<" = "<<_h<<",";_dbg(_s+1,_t...);}
#define f first
#define s second
#define pb emplace_back
#define sz(a) ((int)a.size())
#define forn(i,n) for(int i=0;i<(n);++i)
struct init{init(){cin.tie(0);std::iostream::sync_with_stdio(0);cout<<std::fixed<<std::setprecision(10);cerr<<std::fixed<<std::setprecision(5);}~init(){
#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__,__VA_ARGS__)
cerr<<"Time elapsed: "<<(double)clock()/CLOCKS_PER_SEC<<"s.\n";
#else
#define dbg(...)
#endif
}}init;template<typename T,typename U>void upx(T&x,U y){if(x<y)x=y;}template<typename T,typename U>void upn(T&x,U y){if(x>y)x=y;}
#define int ll
const int N=1e5+444,K=200,OO=1e9;
int xs[N];
struct query{
    int type,a,b,c;
}qs[N];
struct block{
    int x[K+1]={0},a[K+1]={0},u[K+1]={0};
    int mn=0,delta=0,lasts=0,ub=0,ftx;
    void recalc(){
        mn=ub=0,ftx=x[K];
        int s=0,val=0,pos=x[0];
        forn(i,K+1){
            val+=(x[i]-pos)*s;
            pos=x[i];
            if(u[i]){
                upn(ftx,x[i]);
                lasts=s=a[i];
                ub=1;
            }
            upn(mn,val);
            if(pos>OO)break;
        }
        delta=val;
    }
    int getmn(int starts){
        return min(starts*(ftx-x[0]),starts*(ftx-x[0])+mn);
    }
    int getdelta(int starts){
        return starts*(ftx-x[0])+delta;
    }
    void upd(int i,int v){
        u[i]=1;
        a[i]=v;
        recalc();
    }
    void rem(int i){
        u[i]=0;
        recalc();
    }
    bool go(int i,int val,double&ans,int&ls,int starts){
        int s=starts;
        int pos=x[i];
        for(int j=i;j<=K;++j){
            dbg(j,val,pos,x[j]);
            if(val+(x[j]-pos)*s<=0){
                ans=-((double)val)/s+pos;
                return 1;
            }
            val+=(x[j]-pos)*s;
            if(u[j])s=a[j];
            pos=x[j];
            if(pos>OO)break;
        }
        ans=val;
        ls=s;
        return 0;
    }
}bs[N/K+5];
int b;
int32_t main() {
    int n;
    cin>>n;
    int m=0;
    forn(i,n){
        cin>>qs[i].type;
        if(qs[i].type==1){
            cin>>qs[i].a>>qs[i].b;
            xs[m++]=qs[i].a;
        }
        if(qs[i].type==2)cin>>qs[i].a;
        if(qs[i].type==3){
            cin>>qs[i].a>>qs[i].b>>qs[i].c;
            xs[m++]=qs[i].a;
        }
    }
    xs[m++]=1e9+1;
    sort(xs,xs+m);
    m=std::unique(xs,xs+m)-xs;
    b=(m+K-1)/K;
    forn(i,b){
        for(int j=i*K;j<=(i+1)*K;++j)bs[i].x[j-i*K]=xs[j];
        bs[i].recalc();
    }
    for(int i=K;i>=0;--i){
        if(bs[b-1].x[i]>OO)break;
        bs[b-1].x[i]=OO;
    }
    bs[b-1].recalc();
    forn(i,n){
        if(qs[i].type==1){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            bs[x/K].upd(x%K,qs[i].b);
        }
        if(qs[i].type==2){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            bs[x/K].rem(x%K);
        }
        if(qs[i].type==3){
            int x=std::lower_bound(xs,xs+m,qs[i].a)-xs;
            int val=qs[i].c;
            if(val==0){
                cout<<qs[i].a<<'\n';
                continue;
            }
            double ans;
            int f=0,s;
            if(!bs[x/K].go(x%K,val,ans,s,0)){
                val=(ll)(ans+0.5);
                dbg(ans,val);
                for(int j=x/K+1;j<b;++j){
                    dbg(j,bs[j].x[0],val,s);
                    if(val+bs[j].getmn(s)<=0){
                        dbg(bs[j].getmn(s));
                        bs[j].go(0,val,ans,s,s);
                        f=1;
                        break;
                    }
                    val+=bs[j].getdelta(s);
                    if(bs[j].ub)s=bs[j].lasts;
                }
            }else f=1;
            if(f&&ans<=(double)qs[i].b+1e-9){
                cout<<ans<<'\n';
            }else{
                cout<<"-1\n";
            }
        }
    }

    return 0;
}

#include<cstdio>
#include<algorithm>
#define int long long
#define random Mr_Spade
using std::max;
inline int random()
{
	static int x=1984;
	return x^=x<<13,x^=x>>17,x^=x<<7,x;
}
const int N=1e5+5;
int q;
int root,tot;
struct node
{
	int prio;
	int t,s;
	int tl,tr,sr;
	int res,Min;
	int ch[2];
}t[N];
inline void push_up(int x)
{
	if(t[x].ch[0])
		t[x].tl=t[t[x].ch[0]].tl;
	else
		t[x].tl=t[x].t;
	if(t[x].ch[1])
		t[x].tr=t[t[x].ch[1]].tr,t[x].sr=t[t[x].ch[1]].sr;
	else
		t[x].tr=t[x].t,t[x].sr=t[x].s;
	t[x].res=0;t[x].Min=0;
	if(t[x].ch[0])
	{
		t[x].Min=max(t[x].Min,t[t[x].ch[0]].Min);t[x].res+=t[t[x].ch[0]].res;
		t[x].res+=t[t[x].ch[0]].sr*(t[x].t-t[t[x].ch[0]].tr);t[x].Min=max(t[x].Min,-t[x].res);
	}
	if(t[x].ch[1])
	{
		t[x].res+=t[x].s*(t[t[x].ch[1]].tl-t[x].t);t[x].Min=max(t[x].Min,-t[x].res);
		t[x].Min=max(t[x].Min,t[t[x].ch[1]].Min-t[x].res);t[x].res+=t[t[x].ch[1]].res;
	}
	return;
}
void split(int now,int &x,int &y,int k)
{
	if(!now)
		return x=y=0,void();
	if(t[now].t<=k)
		x=now,split(t[now].ch[1],t[now].ch[1],y,k);
	else
		y=now,split(t[now].ch[0],x,t[now].ch[0],k);
	push_up(now);
	return;
}
int merge(int x,int y)
{
	if(!x||!y)
		return x^y;
	if(t[x].prio<t[y].prio)
		return t[x].ch[1]=merge(t[x].ch[1],y),push_up(x),x;
	else
		return t[y].ch[0]=merge(x,t[y].ch[0]),push_up(y),y;
}
double query(int x,int w)
{
	if(t[x].ch[0])
	{
		if(w<=t[t[x].ch[0]].Min)
			return query(t[x].ch[0],w);
		w+=t[t[x].ch[0]].res;
		if(w+t[t[x].ch[0]].sr*(t[x].t-t[t[x].ch[0]].tr)<=0)
			return t[t[x].ch[0]].tr-(double)w/t[t[x].ch[0]].sr;
		w+=t[t[x].ch[0]].sr*(t[x].t-t[t[x].ch[0]].tr);
	}
	if(t[x].ch[1])
	{
		if(w+t[x].s*(t[t[x].ch[1]].tl-t[x].t)<=0)
			return t[x].t-(double)w/t[x].s;
		w+=t[x].s*(t[t[x].ch[1]].tl-t[x].t);
		return query(t[x].ch[1],w);
	}
	return t[x].t-(double)w/t[x].s;
}
signed main()
{
	int opt,l,r,x;
	int dx,dy,dz,dw;
	register int i;
	for(i=1;i<=100000;i++)
		t[i].prio=random();
	scanf("%lld",&q);
	while(q--)
	{
		scanf("%lld",&opt);
		if(opt==1)
		{
			scanf("%lld%lld",&l,&x);
			split(root,dx,dy,l);
			tot++;
			t[tot].t=l;t[tot].s=x;
			t[tot].tl=t[tot].t;
			t[tot].tr=t[tot].t;
			t[tot].sr=t[tot].s;
			t[tot].res=t[tot].Min=0;
			t[tot].ch[0]=t[tot].ch[1]=0;
			root=merge(merge(dx,tot),dy);
		}
		else if(opt==2)
		{
			scanf("%lld",&l);
			split(root,dx,dy,l);
			split(dx,dz,dw,l-1);
			root=merge(dz,dy);
		}
		else
		{
			scanf("%lld%lld%lld",&l,&r,&x);
			split(root,dx,dy,r);
			split(dx,dz,dw,l-1);
			if(x==0)
			{
				printf("%.8lf\n",(double)l);
				root=merge(merge(dz,dw),dy);
				continue;
			}
			if(!dw)
			{
				puts("-1");
				root=merge(merge(dz,dw),dy);
				continue;
			}
			if(x>t[dw].Min)
			{
				x+=t[dw].res;
				if(x+(r-t[dw].tr)*t[dw].sr<=0)
					printf("%.8lf\n",t[dw].tr-(double)x/t[dw].sr);
				else
					puts("-1");
			}
			else
				printf("%.8lf\n",query(dw,x));
			root=merge(merge(dz,dw),dy);
		}
	}
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;const int N=2*1e5+10;typedef long long ll;typedef double db;
struct data
{
	ll k;ll b;ll mi;int st;int ed;
	inline ll f(ll t){return k*t+b;}
	inline db ctim(ll fr){return (double)(-b-fr)/k;}
	friend data operator +(data a,data b)
	{
		ll fv=a.f(b.st);data c;c.k=b.k;c.b=b.b+fv;
		c.mi=min(a.mi,b.mi+fv);c.st=a.st;c.ed=b.ed;return c;
	}friend bool operator <(data a,data b){return a.st<b.st;}
	friend bool operator <(data a,int b){return a.st<b;}
};struct splaytree
{
	int s[N][2];int fa[N];data v[N];data sum[N];int ct;int rot;
	splaytree()
	{
		v[1]=(data){0,0,0,-0x3f3f3f3f};v[2]=(data){0,0,0,0x3f3f3f3f};
		s[2][0]=1;fa[1]=2;ct=rot=2;sum[2]=v[1]+v[2];
	}inline int gc(int x){return s[fa[x]][1]==x;}
	inline void ud(int p)
	{
		if(s[p][0])sum[p]=sum[s[p][0]]+v[p];else sum[p]=v[p];
		if(s[p][1])sum[p]=sum[p]+sum[s[p][1]];
	}inline void rt(int x)
	{
		int d=fa[x];int t=gc(x);s[d][t]=s[x][t^1];fa[s[x][t^1]]=d;
		s[fa[d]][gc(d)]=x;fa[x]=fa[d];s[x][t^1]=d;fa[d]=x;ud(d);ud(x);
	}inline void rtup(int x){rt((gc(x)^gc(fa[x]))?x:fa[x]);rt(x);}
	inline void splay(int x,int nod=0)
	{
		for(;fa[x]!=nod&&fa[fa[x]]!=nod;rtup(x));
		if(fa[x]!=nod)rt(x);if(nod==0)rot=x;
	}inline void ins(data ke)
	{
		int p=rot;for(;s[p][v[p]<ke];p=s[p][v[p]<ke]);
		v[++ct]=ke;sum[ct]=ke;s[p][v[p]<ke]=ct;fa[ct]=p;splay(ct);
	}inline void del(int ke)
	{
		int p=rot;for(;s[p][v[p]<ke];p=s[p][v[p]<ke])if(v[p].st==ke)break;
		splay(p);int sub=s[p][0];for(;s[sub][1];sub=s[sub][1]);
		splay(sub);s[sub][1]=s[p][1];fa[s[p][1]]=sub;ud(sub);
	}inline int pres(int ke)
	{
		int res=1;
		for(int p=rot;p;)if(v[p].st<=ke)res=p,p=s[p][1];else p=s[p][0];
		return res;
	}inline int succ(int ke)
	{
		int res=2;
		for(int p=rot;p;)if(v[p].st<ke)p=s[p][1];else res=p,p=s[p][0];
		return res;
	}inline int split(int l,int r)
	{splay(pres(l-1));int nw;splay(nw=succ(r+1),rot);return s[nw][0];}
	inline db qry(int p,ll fr)
	{
		if(s[p][0])
		{
			if(sum[s[p][0]].mi+fr<=0)return qry(s[p][0],fr);
			db ret1=sum[s[p][0]].ctim(fr);
			if(sum[s[p][0]].ed<=ret1&&ret1<=v[p].st)return ret1;
		}data fuc;
		if(s[p][0])fuc=sum[s[p][0]]+v[p];else fuc=v[p];
		db lim=(s[p][1])?sum[s[p][1]].st:0x3f3f3f3f;
		db ret1=fuc.ctim(fr);
		if(v[p].ed<=ret1&&ret1<=lim)return ret1;
		if(s[p][1])
			return qry(s[p][1],fr+fuc.f(sum[s[p][1]].st));
		return v[p].ctim(fr);
	}
	inline void cqry(int l,int r,int fr)
	{
		int nw=split(l,r);
		if(fr==0){printf("%d\n",l);return;}
		if(nw==0){printf("-1\n");return;}
		db tim=sum[nw].ctim(fr);
		if(sum[nw].mi+fr>0&&(tim<sum[nw].ed||tim>r))printf("-1\n");
		else printf("%.10lf\n",qry(nw,fr));
	}
}spt;int q;
int main()
{
	scanf("%d",&q);
	for(int i=1,tp,tim,sec,l,r;i<=q;i++)
	{
		scanf("%d",&tp);
		switch (tp)
		{
			case 1:
			{
				scanf("%d%d",&tim,&sec);
				data nw=(data){sec,-(ll)tim*sec,0,tim,tim};
				spt.ins(nw);break;
			}
			case 2:{scanf("%d",&tim);spt.del(tim);break;}
			case 3:{scanf("%d%d%d",&l,&r,&tim);spt.cqry(l,r,tim);break;}
		}
	}return 0;
}

#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("-O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define sset ordered_set
#define sqr(x) (x)*(x)
#define pw(x) (1ll << x)

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
const ll MAXN = 1123456;
const ll N = 2e5;
mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T> void vout(T s){cout << s << endl;exit(0);}

struct node{
    bool us;
    int tl, tr, last_s;
    ll sum, min_pref, pref_sum;
    node *l, *r;
    node(int le, int ri): tl(le), tr(ri), pref_sum(ri - le + 1), last_s(0), sum(0), min_pref(0), us(0), l(r=nullptr){}
};

struct nd{
    bool us;
    int tl, tr, last_s;
    ll sum, min_pref, pref_sum;
};

ll pos;
pll val;

node *root;

nd rt, res;

nd add(node *a, ll last_s){
    res.sum = a -> sum + last_s * a -> pref_sum;
    res.min_pref = a -> min_pref;
    if(a -> pref_sum){
        res.min_pref = min(a -> min_pref, 0ll);
        res.min_pref += last_s * (a -> pref_sum);
        res.min_pref = min(res.min_pref, last_s);
    }
    return res;
}
ll RM;

void unite(node *a, node *l, node *r){
    a -> tl = l -> tl;
    a -> tr = r -> tr;
    a -> us = l -> us | r -> us;
    a -> sum = l -> sum + r -> sum;
    RM = r -> min_pref;
    if(l -> us && r -> pref_sum){
        RM = min(RM, 0ll);
        RM += (l -> last_s) * (r -> pref_sum);
        RM = min(RM, ll(l -> last_s));
        a -> sum += (l -> last_s) * (r -> pref_sum);
    }
    a -> l = l;
    a -> r = r;

    a -> min_pref = min(l -> min_pref, l -> sum + RM);
    a -> pref_sum = l -> pref_sum;
    if(l -> pref_sum == l -> tr - l -> tl + 1)a -> pref_sum += r -> pref_sum;

    if(r -> us)a -> last_s = r -> last_s;
    else a -> last_s = l -> last_s;
}

void modify(node *v){
    if(v -> tl == v -> tr){
        v -> us = val.se;
        v -> last_s = val.fi;
        if(val.se){
            v -> sum = v -> min_pref = val.fi;
            v -> pref_sum = 0;
        }else{
            v -> sum = v -> min_pref = 0;
            v -> pref_sum = 1;
        }
        return;
    }
    int tm = (v -> tl + v -> tr) >> 1;

    if(v -> l == nullptr){
        v -> l = new node(v -> tl, tm);
    }

    if(v -> r == nullptr){
        v -> r = new node(tm + 1, v -> tr);
    }

    if(pos <= tm)modify(v -> l);
    else modify(v -> r);
    unite(v, v -> l, v -> r);

}

node *Ans;

ll V;

bool ok;

ld ans = -1;
ll last_S;
void dfs(node *v){
    if(v -> tl == v -> tr){
        ok = 1;
        ans = v -> tl - 1;
        if(v -> us)last_S = v -> last_s;
        if(last_S != 0)ans += ld(V) / -last_S;
        return;
    }
    int tm = (v -> tl + v -> tr) >> 1;
    if(v -> l == nullptr){
        v -> l = new node(v -> tl, tm);
    }

    if(v -> r == nullptr){
        v -> r = new node(tm + 1, v -> tr);
    }

    rt = add(v -> l, last_S);

    if(!V || rt.min_pref + V <= 0)dfs(v -> l); else{
        V += rt.sum;
        if((v -> l) -> us)last_S = (v -> l) -> last_s;
        dfs(v -> r);
    }

}
void get(node *v, int l, int r){
    if(l > r)return;
    if(ok)return;
    if(v -> tl == l && v -> tr == r){
        rt = add(v, last_S);
        if(!V || V + rt.min_pref <= 0){
            dfs(v);
        }else{
            V += rt.sum;
            if(v -> us)last_S = v -> last_s;
        }
        return;
    }
    int tm = (v -> tl + v -> tr) >> 1;
    if(v -> l == nullptr){
        v -> l = new node(v -> tl, tm);
    }

    if(v -> r == nullptr){
        v -> r = new node(tm + 1, v -> tr);
    }
    get(v -> l, l, min(r, tm));
    get(v -> r, max(tm + 1, l), r);
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

    ll q;
    cin >> q;

    root = new node(1, 1e9);

    while(q--){
        short t;
        cin >> t;
        if(t == 1){
            int s;
            cin >> pos >> s;
            val = {s, 1};
            modify(root);
        }else if(t == 2){
            cin >> pos;
            val = {0ll, 0ll};
            modify(root);
        }else {
            ok = 0;
            ans = -1;
            last_S = 0;
            int l, r;
            cin >> l >> r >> V;
            get(root, l, r - 1);
            if(!ok)cout << "-1\n"; else cout << fixed << setprecision(6) << ans + 1 << "\n";
        }

    }

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define null NULL
#define mp make_pair
#define pb(a) push_back(a)
#define sz(a) ((int)(a).size())
#define all(a) a.begin() , a.end()
#define fi first
#define se second
#define relaxMin(a , b) (a) = min((a),(b))
#define relaxMax(a , b) (a) = max((a),(b))
#define SQR(a) ((a)*(a))
#define PI 3.14159265358979323846
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

int Rand(){
  return (rand() << 10) ^ rand();
}

const int SZ = 300;
const int MAX = 100010;

struct Block {
  ll add, start, end;
  int type;

  Block(ll _add, ll _start, ll _end,
        int _type){
    add = _add;
    start = _start;
    end = _end;
    type = _type;
  }

  double Zeroes(ll v){
    if(v + (end - start + 1) * add <= 0){
      return start + (v + 0.0) / abs(add);
    } else {
      return -1;
    }
  }

  ll Min(ll v){
    return min(v, v + (end - start + 1) * add);
  }

  ll AtEnd(ll v){
    return v + (end - start + 1) * add;
  }
};

typedef list<Block>::iterator Iter;
ll minv[MAX], at_end[MAX];
Iter lo[MAX], hi[MAX];

map<int, Iter> loc;

list<Block> arr;

void Init(){
  loc[0] = arr.insert(arr.begin(), Block(0, 0, 1E9 + 10, -1));
}

void RebuildBlock(Iter pos){
  int id = pos->type;
  lo[id] = hi[id] = pos;

  while(lo[id] != arr.begin() && (--Iter(lo[id]))->type == id)
    --lo[id];
  while((++Iter(hi[id])) != arr.end() &&
        (++Iter(hi[id]))->type == id)
    ++hi[id];

  ll val = 0;
  minv[id] = val;
  pos = lo[id];
  do{
    relaxMin(minv[id], pos->Min(val));
    val = pos->AtEnd(val);
    if(pos == hi[id]) break;
    ++pos;
  }while(true);

  at_end[id] = val;
}

void Build(){
  int cid = -1;
  Iter pos = arr.begin();

  while(pos != arr.end()){
    ++cid;
    lo[cid] = pos;
    hi[cid] = pos;
    ll val = 0;
    minv[cid] = val;
    for(int i = 0;i < SZ && pos != arr.end();++i){
      pos->type = cid;
      hi[cid] = pos;
      relaxMin(minv[cid], pos->Min(val));
      val = pos->AtEnd(val);
      ++pos;
    }
    at_end[cid] = val;
  }
}

void Delete(int t){
  Iter it = loc[t];
  int me = it->type;

  Iter par = it;
  --par;

  par->end = it->end;
  arr.erase(it);
  loc.erase(t);

  RebuildBlock(par);
  ++par;
  if(par != arr.end() && me == par->type)
    RebuildBlock(par);
}

void Insert(int t, ll add){
  auto it = loc.lower_bound(t);
  --it;

  Iter sp = it->se;
  Block neo(add, t, sp->end, sp->type);
  sp->end = t - 1;

  loc[t] = arr.insert(++sp, neo);
  RebuildBlock(loc[t]);
}

double FirstZero(int l, int r, ll v){
  if(v == 0) return l;

  auto start = loc.lower_bound(l);

  if(start == loc.end()){
    if(v == 0) return l;
    return -1;
  }

  Iter pos = start->se;
  int fg = pos->type;

  ll bal = v;

  while(true){
    if(pos == arr.end()) return -1;
    if(pos->start > r) return -1;

    if(pos->type != fg){
      int id = pos->type;
      if(minv[id] + bal > 0){
        fg = pos->type;
        bal = at_end[id] + bal;
        pos = hi[id];
        ++pos;
        continue;
      }
    }

    double zp = pos->Zeroes(bal);
    if(zp > -0.5 && zp < r + 1E-9) return zp;

    bal = pos->AtEnd(bal);
    fg = pos->type;
    ++pos;
  }
}

int main(){
  Init();
  Build();

  int n = 100000;
  scanf("%d", &n);

  int mods = 0;
  for(int i = 0;i < n;++i){
    if(mods % SZ == SZ - 1) Build();
    int op;
    scanf("%d", &op);
    if(op == 1){
      ++mods;
      int t, s;
      scanf("%d%d", &t, &s);
      Insert(t, s);
    } else if(op == 2){
      int t;
      scanf("%d", &t);
      Delete(t);
    } else if(op == 3){
      int l, r, v;
      scanf("%d%d%d", &l, &r, &v);
      double res = FirstZero(l, r, v);
      if(res < -0.5) printf("-1\n");
      else printf("%.12f\n", res);
    }
  }

  return 0;
}

#include<bits/stdc++.h>
using namespace std;

const int N=100100,inf=2e9;
typedef long long ll;

ll mx[N*70],mn[N*70],tag[N*70];
int lc[N*70],rc[N*70];
int cnt=1,q1,q2;
ll q3,q4,q5,q6;
int mdf(int o,int l,int r){
	if(!o)o=++cnt;
	if(q1<=l&&r<=q2){
		mx[o]+=q3;mn[o]+=q3;tag[o]+=q3;
		return o;
	}
	int mid=l+(r-l)/2;
	if(q1<=mid)lc[o]=mdf(lc[o],l,mid);
	if(q2>mid)rc[o]=mdf(rc[o],mid+1,r);
	mx[o]=max(mx[lc[o]],mx[rc[o]])+tag[o];
	mn[o]=min(mn[lc[o]],mn[rc[o]])+tag[o];
	return o;
}

void calc(int o,int l,int r){
	q3+=tag[o];
	if(!o||l==r)return;
	int mid=l+(r-l)/2;
	if(q1<=mid)calc(lc[o],l,mid);
	else calc(rc[o],mid+1,r);
}

void qry(int o,int l,int r,ll pd=0){
	if(q3!=-1)return;
	int mid=l+(r-l)/2;pd+=tag[o];
	if(l==r){
		if(min(q5,pd)<=q4&&q4<=max(q6,pd))
			q3=l,q4-=pd;
		else q5=min(q5,pd),q6=max(q6,pd);
		return;
	}
	if(q1<=l&&r<=q2){
		if(min(q5,mn[lc[o]]+pd)<=q4&&q4<=max(q6,mx[lc[o]]+pd))return qry(lc[o],l,mid,pd);
		q5=min(q5,mn[lc[o]]+pd);q6=max(q6,mx[lc[o]]+pd);
		if(min(q5,mn[rc[o]]+pd)<=q4&&q4<=max(q6,mx[rc[o]]+pd))return qry(rc[o],mid+1,r,pd);
		q5=min(q5,mn[rc[o]]+pd);q6=max(q6,mx[rc[o]]+pd);
		return;
	}
	if(q1<=mid)qry(lc[o],l,mid,pd);
	if(q2>mid)qry(rc[o],mid+1,r,pd);
}

int Q;
map<int,int>mp;
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	mp[0]=mp[inf]=0;cout<<fixed<<setprecision(10);
	for(cin>>Q;Q --> 0;){
		int op,x,y;cin>>op>>x;
		if(op==1){
			auto it=mp.upper_bound(x),it2=it--;
			q1=it2->first;q2=inf;cin>>q3;mp[x]=q3;
			q3-=it->second;q3*=it2->first-x;
			if(q1<=q2)mdf(1,1,inf);
			q1=x;q2=it2->first-1;q3=(ll)(x-it->first)*it->second;
			if(q1<=q2)mdf(1,1,inf);
		}else if(op==2){
			auto it=mp.find(x),it2=it--,it3=it2++;
			q1=it2->first;q2=inf;q3=(ll)(it->second-it3->second)*(it2->first-x);
			if(q1<=q2)mdf(1,1,inf);mp.erase(it3);
			q1=x;q2=it2->first-1;q3=(ll)(it->first-x)*it->second;
			if(q1<=q2)mdf(1,1,inf);
		}else{
			cin>>y>>q4;q4=-q4;q5=q6=0;
			if(!q4){cout<<x<<'\n';continue;}
			auto it=mp.lower_bound(x);
			if(it->first>=y){cout<<-1<<'\n';continue;}
			q1=it->first;q3=0;calc(1,1,inf);
			q5=q6=q3;
			q4+=q5;q3=-1;q2=inf;
			qry(1,1,inf);
			if(q3==-1)cout<<-1<<'\n';
			else{
				it=--mp.find(q3);
				int d=it->second;if(d<0)d=-d,q4=-q4;q4+=(ll)q3*d;
				if(q4>(ll)y*d)cout<<-1<<'\n';
				else cout<<(double)q4/d<<'\n';
			}
		}
	}
	return 0;
}

/*
ЗАПУСКАЕМ
░ГУСЯ░▄▀▀▀▄░РАБОТЯГУ░░
▄███▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▌░░░░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
*/
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>
#include <array>

using namespace std;
template<typename T1, typename T2>inline void chkmin(T1 &x, T2 y) { if (x > y) x = y; }
template<typename T1, typename T2>inline void chkmax(T1 &x, T2 y) { if (x < y) x = y; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const pair<T, U> &_p) { _out << _p.first << ' ' << _p.second; return _out; }
template<typename T, typename U> inline istream &operator>> (istream &_in, pair<T, U> &_p) { _in >> _p.first >> _p.second; return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const vector<T> &_v) { if (_v.empty()) { return _out; } _out << _v.front(); for (auto _it = ++_v.begin(); _it != _v.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline istream &operator>> (istream &_in, vector<T> &_v) { for (auto &_i : _v) { _in >> _i; } return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const unordered_map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }
#define sz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define left left228
#define right right228
#define rank rank228
#define y1 y1228
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define files(FILENAME) read(FILENAME), write(FILENAME)
#define pb push_back
const string FILENAME = "input";
const int MAXN = 400228;

int q;
int type[MAXN];
int t[MAXN], s[MAXN];
int ll[MAXN], rr[MAXN];
long long vv[MAXN];
vector<int> vt;
int m;
long long sum[MAXN];
int ss[MAXN];
set<int> cur;
map<int, int> whox;

struct rmq
{
    int ss;
    vector<long long> val;
    vector<long long> mod;
    void init(int n) {
        ss = 1;
        while (ss < n) {
            ss <<= 1;
        }
        val.resize(2 * ss, 0);
        mod.resize(2 * ss, 0);
    }
    void push(int v) {
        if (mod[v] != 0) {
            val[v] += mod[v];
            if (v < ss) {
                mod[v * 2] += mod[v];
                mod[v * 2 + 1] += mod[v];
            }
            mod[v] = 0;
        }
    }
    void add(int v, int vl, int vr, int l, int r, long long x) {
        if (l > r) {
            return;
        }
        if (vl > r || vr < l) {
            push(v);
            return;
        }
        if (l <= vl && vr <= r) {
            mod[v] += x;
            push(v);
            return;
        }
        push(v);
        add(v * 2, vl, (vl + vr) / 2, l, r, x);
        add(v * 2 + 1, (vl + vr) / 2 + 1, vr, l, r, x);
        val[v] = max(val[v * 2], val[v * 2 + 1]);
    }
    long long get(int v, int vl, int vr, int l, int r) {
        if (vl > r || vr < l) {
            return -3e18;
        }
        if (l <= vl && vr <= r) {
            return val[v] + mod[v];
        }
        push(v);
        return max(get(v * 2, vl, (vl + vr) / 2, l, r), get(v * 2 + 1, (vl + vr) / 2 + 1, vr, l, r));
    }
};

rmq tr;

void inc(int i, long long val) {
    tr.add(1, 1, tr.ss, i + 1, tr.ss, val);
    for (int j = i; j < m; j |= (j + 1)) {
        sum[j] += val;
    }
}

long long get(int i) {
    long long res = 0;
    for (int j = i; j >= 0; j = (j & (j + 1)) - 1) {
        res += sum[j];
    }
    return res;
}

long long get(int l, int r) {
    if (l > r) {
        return 0;
    }
    return get(r) - (l == 0 ? 0: get(l - 1));
}

long long getboundry(long long curt) {
    auto it = cur.upper_bound(curt);
    if (it == cur.end()) {
        return 2000000002LL;
    }
    return *it;
}

void del(long long curt) {
    int id = whox[curt];
    //cout << ss[id] << endl;
    inc(id, -1LL * ss[id] * (getboundry(curt) - curt));
}

void add(long long curt) {
    int id = whox[curt];
    //cout << ss[id] << endl;
    inc(id, 1LL * ss[id] * (getboundry(curt) - curt));
}

void add(int curt, int kek) {
    ss[whox[curt]] = kek;
    auto it = cur.lower_bound(curt);
    int f = -1;
    bool was = false;
    if (it != cur.begin()) {
        it--;
        f = *it;
        was = true;
        del(f);
    }
    cur.insert(curt);
    if (was) {
        add(f);
    }
    add(curt);
}

void dels(int curt) {
    del(curt);
    auto it = cur.lower_bound(curt);
    int f = -1;
    bool was = false;
    if (it != cur.begin()) {
        it--;
        f = *it;
        was = true;
        del(f);
    }
    cur.erase(curt);
    if (was) {
        add(f);
    }

}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //read(FILENAME);
    cin >> q;
    for (int i = 0; i < q; i++) {
        cin >> type[i];
        if (type[i] == 1) {
            cin >> t[i] >> s[i];
            s[i] *= -1;
            vt.pb(t[i]);
        } else if (type[i] == 2) {
            cin >> t[i];
        } else {
            cin >> ll[i] >> rr[i] >> vv[i];
            vt.pb(ll[i]);
            vt.pb(rr[i]);
        }
    }
    sort(all(vt));
    vt.resize(distance(vt.begin(), unique(all(vt))));
    m = sz(vt);
    tr.init(m);
    for (int i = 0; i < m; i++) {
        whox[vt[i]] = i;
    }
    cout.precision(10);
    for (int i = 0; i < q; i++) {
        if (type[i] == 1) {
            add(t[i], s[i]);
        } else if (type[i] == 2) {
            dels(t[i]);
        } else {
            //cout << get(whox[ll[i]], whox[rr[i]]) << endl;
            if (vv[i] == 0) {
                cout << ll[i] << '\n';
                continue;
            }
            long long f = get(0, whox[ll[i]] - 1);
            //cout << f << endl;
           // cout << tr.get(1, 1, tr.ss, whox[ll[i]] + 1, whox[rr[i]] + 1) - f << endl;
            if (tr.get(1, 1, tr.ss, whox[ll[i]] + 1, whox[rr[i]] + 1) - f < vv[i]) {
                cout << -1 << '\n';
            } else {
                int l = whox[ll[i]];
                int r = whox[rr[i]];
                int curl = whox[ll[i]];
                while (l < r) {
                    int mid = (l + r) >> 1;
                    if (tr.get(1, 1, tr.ss, curl + 1, mid + 1) - f >= vv[i]) {
                        r = mid;
                    } else {
                        l = mid + 1;
                    }
                }
               // cout << tr.get(1, 1, tr.ss, 1, 1) << ' ' << vv[i] << endl;
               // cout << get(0, 0) << endl;
                vv[i] -= get(curl, l - 1);
                int f = ss[l];
                double kek = vt[l] + double(vv[i]) / double(f);
                if (kek > rr[i]) {
                    cout << -1 << '\n';
                } else {
                    cout << fixed << kek << '\n';
                }
            }
        }
    }
    return 0;
}

/*----------------by syr----------------*/
/*
  -----  -----  -----
  |   |  |---|    _/
  |   |  | \_    /
  -----  |   \  -----

  |---\  \   /  |\  /|
  |   |   \_/   | \/ |
  |   |   / \   |    |
  |---/  /   \  |    |
*/
#include<bits/stdc++.h>

using namespace std;

#define PH push
#define MP make_pair
#define PB push_back
#define fst first
#define snd second
#define FOR(i,x,y) for(int i=(x);i<(y);++i)
#define REP(i,x,y) for(int i=(x);i<=(y);++i)
#define x0 x0123456789
#define y0 y0123456789
#define x1 x1234567890
#define y1 y1234567890
#define x2 x2345678901
#define y2 y2345678901
typedef double db;
typedef long long ll;
typedef long double ldb;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int INF=1e9+7;
const int maxn=1e5+5;

class Treap{
private:
	class Node{
	public:
		ll s,t;
		ll l,r;
		ll lst;
		ll sum,mns;
		int ls,rs;
		int fix;
		Node(){}
		Node(ll s,ll t):s(s),t(t),l(s),r(s),lst(t),sum(0),mns(0),ls(0),rs(0),fix(1ll*rand()*rand()%INF){}
		void print(){
			printf("s=%lld t=%lld l=%lld r=%lld lst=%lld sum=%lld mns=%lld ls=%lld rs=%lld\n",s,t,l,r,lst,sum,mns,ls,rs);
			return;
		}
    }dat[maxn<<2];
    int tot;
public:
	int rt;
    void init(){
		rt=tot=0;
		dat[rt]=Node(0,0);
		return;
	}
    int buildNode(ll s,ll t){
		++tot;
		dat[tot]=Node(s,t);
		return tot;
	}
	void pushUp(int x){
		//printf("x=%d\n",x);
		int p=dat[x].ls,q=dat[x].rs;
		if(!p&&!q){
			dat[x].l=dat[x].r=dat[x].s;
			dat[x].lst=dat[x].t;
			dat[x].sum=dat[x].mns=0;
		}
		else if(!p){
			ll res=dat[x].t*(dat[q].l-dat[x].s);
			dat[x].l=dat[x].s;
			dat[x].r=dat[q].r;
			dat[x].lst=dat[q].lst;
			dat[x].sum=dat[q].sum+res;
			dat[x].mns=min(res,res+dat[q].mns);
		}
		else if(!q){
			ll res=dat[p].lst*(dat[x].s-dat[p].r);
			dat[x].l=dat[p].l;
			dat[x].r=dat[x].s;
			dat[x].lst=dat[x].t;
			dat[x].sum=dat[p].sum+res;
			dat[x].mns=min(dat[p].mns,dat[p].sum+res);
		}
		else{
			ll res1=dat[p].lst*(dat[x].s-dat[p].r);
			ll res2=dat[x].t*(dat[q].l-dat[x].s);
			dat[x].l=dat[p].l;
			dat[x].r=dat[q].r;
			dat[x].lst=dat[q].lst;
			dat[x].sum=dat[p].sum+res1+res2+dat[q].sum;
			dat[x].mns=min(min(dat[p].mns,dat[p].sum+res1),min(dat[p].sum+res1+res2,dat[p].sum+res1+res2+dat[q].mns));
		}
		dat[x].mns=min(dat[x].mns,0ll);
		return;
	}
	void split(int u,int &x,int &y,int k){
		if(!u){
			x=y=0;
			return;
		}
		if(dat[u].s>k){
			split(dat[u].ls,x,dat[u].ls,k);
			y=u;
		}
		else{
			split(dat[u].rs,dat[u].rs,y,k);
			x=u;
		}
		pushUp(u);
		return;
	}
	void merge(int &u,int x,int y){
		//printf("merge: u=%d x=%d y=%d\n",u,x,y);
		if(!(x&&y)){
			u=(x|y);
			return;
		}
		if(dat[x].fix>dat[y].fix){
			u=y;
			merge(dat[y].ls,x,dat[y].ls);
		}
		else{
			u=x;
			merge(dat[x].rs,dat[x].rs,y);
		}
		pushUp(u);
		return;
	}
	db query(int u,ll k){
		int p=dat[u].ls,q=dat[u].rs;
		ll res1,res2;
		if(p) res1=dat[p].lst*(dat[u].s-dat[p].r);
		else res1=0;
		if(q) res2=dat[u].t*(dat[q].l-dat[u].s);
		else res2=0;
		if(!p){
			if(res2<=-k) return dat[u].s+1.0*k/(-dat[u].t);
			return query(q,k+res2);
		}
		if(!q){
			if(dat[p].mns<=-k) return query(p,k);
			return dat[p].r+1.0*(k+dat[p].sum)/(-dat[p].lst);
		}
		if(dat[p].mns<=-k) return query(p,k);
		if(dat[p].sum+res1<=-k)	return dat[p].r+1.0*(k+dat[p].sum)/(-dat[p].lst);
		if(dat[p].sum+res1+res2<=-k) return dat[u].s+1.0*(k+dat[p].sum+res1)/(-dat[u].t);
		if(dat[p].sum+res1+res2+dat[q].mns<=-k) return query(q,k+dat[p].sum+res1+res2);
	}
	db solve(int u,ll k,ll x,ll y){
		ll res=dat[u].lst*(y-dat[u].r);
		//printf("u=%d %lld %lld %lld\n",u,dat[u].mns,res,k);
		//dat[u].print();
		if(dat[u].mns>-k){
			if(dat[u].sum+res<=-k) return dat[u].r+1.0*(k+dat[u].sum)/(-dat[u].lst);
			else return -1;
		}
		else return query(u,k);
	}
	void print(){
		printf("root=%d\n",rt);
		REP(u,1,tot){
			printf("u=%d\n",u);
			dat[u].print();
		}
		return;
	}
}trp;

int q;

int main(){
	scanf("%d",&q);
	//trp.init();
	FOR(i,0,q){
		int tp,x,y,z;
		scanf("%d",&tp);
		//trp.print();
		if(tp==1){
			scanf("%d%d",&x,&y);
			int tl,tr,v=trp.buildNode(x,y);
			trp.split(trp.rt,tl,tr,x);
			trp.merge(tl,tl,v);
			trp.merge(trp.rt,tl,tr);
		}
		else if(tp==2){
			scanf("%d",&x);
			int tl,tr,v;
			trp.split(trp.rt,tl,tr,x-1);
			trp.split(tr,v,tr,x);
			trp.merge(trp.rt,tl,tr);
		}
		else{
			scanf("%d%d%d",&x,&y,&z);
			int tl,tr,v;
			if(!z){
				printf("%d\n",x);
				continue;
			}
			trp.split(trp.rt,tl,tr,x-1);
			//trp.print();
			trp.split(tr,v,tr,y);
			//printf("tl=%d tr=%d v=%d\n",tl,tr,v);
			//trp.print();
			printf("%.10f\n",trp.solve(v,z,x,y));
			trp.merge(tr,v,tr);
			trp.merge(trp.rt,tl,tr);
		}
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int tot, root;
map<int,int> mp;
struct node
{
    int l, r, val; bool cov;
    ll lsum, sum;
} tree[maxn*50];
void pushdown(int rt,int l,int r)
{
    if(!tree[rt].cov) return ;
    int mid = (l+r)>>1;
    if(!tree[rt].l) tree[rt].l = ++tot;
    if(!tree[rt].r) tree[rt].r = ++tot;
    int ls = tree[rt].l, rs = tree[rt].r;
    tree[ls].cov = 1;
    tree[ls].val = tree[rt].val;
    tree[ls].sum = (ll)(mid-l+1)*tree[rt].val;
    tree[ls].lsum = tree[rt].val < 0 ? tree[ls].sum : 0;
    tree[rs].cov = 1;
    tree[rs].val = tree[rt].val;
    tree[rs].sum = (ll)(r-mid)*tree[rt].val;
    tree[rs].lsum = tree[rt].val < 0 ? tree[rs].sum : 0;
    tree[rt].cov = tree[rt].val = 0;
}
void update(int &rt,int L,int R,int l,int r,int x)
{
    if(!rt) rt = ++tot;
    if(l >= L && r <= R){
        tree[rt].cov = 1; tree[rt].val = x;
        tree[rt].sum = (ll)(r-l+1)*x;
        tree[rt].lsum = x < 0 ? tree[rt].sum : 0;
        return ;
    }
    pushdown(rt,l,r);
    int mid = (l+r)>>1;
    if(mid >= L) update(tree[rt].l,L,R,l,mid,x);
    if(mid < R) update(tree[rt].r,L,R,mid+1,r,x);
    tree[rt].sum = tree[tree[rt].l].sum+tree[tree[rt].r].sum;
    tree[rt].lsum = min(tree[tree[rt].l].lsum,tree[tree[rt].l].sum+tree[tree[rt].r].lsum);
}
pair<double,ll> query(int &rt,int L,int R,int l,int r,ll x)
{
    if(!rt) return make_pair(0,0);
    if(l == L && r == R){
        if(x+tree[rt].lsum > 0) return make_pair(-1,tree[rt].sum);
        if(l == r || tree[rt].cov) return make_pair(L-x*1.0/(tree[rt].sum/(r-l+1)),tree[rt].sum);
    }
    pushdown(rt,l,r);
    int mid = (l+r)>>1;
    if(mid >= R) return query(tree[rt].l,L,R,l,mid,x);
    else if(mid < L) return query(tree[rt].r,L,R,mid+1,r,x);
    else{
        pair<double,ll> tmp1 = query(tree[rt].l,L,mid,l,mid,x);
        if(tmp1.first > 0) return tmp1;
        else{
            pair<double,ll> tmp2 = query(tree[rt].r,mid+1,R,mid+1,r,x+tmp1.second);
            return make_pair(tmp2.first,tmp1.second+tmp2.second);
        }
    }
}
int main()
{
    int n, op, x, y, z;
    scanf("%d",&n);
    int L = 1, R = 1e9;
    mp[L-1] = mp[R+1] = 0;
    while(n--){
        scanf("%d%d",&op,&x);
        if(op == 1){
            scanf("%d",&y);
            mp[x] = y;
            auto it = mp.find(x); it++;
            update(root,x,(*it).first-1,L,R,y);
        }
        else if(op == 2){
            auto it = mp.find(x), pre = it, nxt = it;
            --pre; ++nxt;
            update(root,x,(*nxt).first-1,L,R,(*pre).second);
            mp.erase(it);
        }
        else{
            scanf("%d%d",&y,&z);
            if(z == 0){ printf("%d\n",x); continue; }
            auto it = mp.lower_bound(x);
            if((*it).first >= y){ printf("-1\n"); continue; }
            pair<double,ll> ans = query(root,(*it).first,y-1,L,R,z);
            //cout<<"*"<<ans.first<<" "<<ans.second<<endl;
            if(ans.first < 0) printf("-1\n");
            else printf("%.8f\n",ans.first);
        }
    }
    return 0;
}

//时间节点离散化，用线段树维护时间区间上的二次函数，最终线段树上应当存了一些互不相交的函数区间。
//修改操作：modify 更改一段区间上的二次函数，如果破坏了原有的函数区间，需要将原有的函数pushdown
//修改操作：cover 直接重置一段区间上的二次函数，不管有没有原有的函数
//查询操作：query 应当先查询左子树，再查询右子树。一旦有了答案就停止查询。对于每个线段树区间维护增量的min和sum，查询完左子树之后要加上sum。如果min值带入计算仍大于等于0则提前返回。如果当前到达的区间是一个整块的函数区间，无论是否完全被查询区间包含，都只在当前区间查询并且停止递归

#include <bits/stdc++.h>
#define eps 1e-6
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int maxt=(1<<20)+10;
int n;
ll datk[maxt],datb[maxt],sum[maxt],mn[maxt];
int id[maxt];
int leftmostid[maxt],rightmostid[maxt];
ll read_tl[maxn],read_tr[maxn],read_tval[maxn],cal_tl[maxn],cal_tr[maxn],tp[maxn],covr[maxn];
vector<ll> lsh;
map<ll,int> ttoi;
set<ll> st;
set<ll>::iterator it;
int pred,curd;
double ans;
ll preval;
void modify(int x,int l,int r,int tl,int tr,ll k,ll b,int ii)
{
	if(!k)ii=-2;
	if(l>tr||r<tl)return;
//	cout<<"modify "<<x<<" "<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<k<<" "<<b<<" "<<ii<<endl;
	if(tl<=l&&r<=tr)
	{
		id[x]=ii;datk[x]=k;datb[x]=b;
		if(ii==-2||l==cal_tl[ii])sum[x]=k*(lsh[r]-lsh[l]+1);
		else sum[x]=k*(lsh[r]-lsh[l-1]);
		mn[x]=min(0ll,sum[x]);
		leftmostid[x]=rightmostid[x]=ii;
		return;
	}
	id[x]=-1;datk[x]=datb[x]=0;
	int mid=(l+r)/2;modify(x*2,l,mid,tl,tr,k,b,ii);modify(x*2+1,mid+1,r,tl,tr,k,b,ii);
	sum[x]=sum[x*2]+sum[x*2+1];
	mn[x]=min(mn[x*2],sum[x*2]+mn[x*2+1]);
	leftmostid[x]=leftmostid[x*2];
	if(leftmostid[x]==-2)leftmostid[x]=rightmostid[x*2];
	if(leftmostid[x]==-2)leftmostid[x]=leftmostid[x*2+1];
	if(leftmostid[x]==-2)leftmostid[x]=rightmostid[x*2+1];
	rightmostid[x]=rightmostid[x*2+1];
	if(rightmostid[x]==-2)rightmostid[x]=leftmostid[x*2+1];
	if(rightmostid[x]==-2)rightmostid[x]=rightmostid[x*2];
	if(rightmostid[x]==-2)rightmostid[x]=leftmostid[x*2];
//	assert(id[x]!=-2&&leftmostid[x]!=-2&&rightmostid[x]!=-2);
//	cout<<x<<" "<<l<<" "<<r<<endl;
	if(leftmostid[x]==-2&&rightmostid[x]==-2)id[x]=-2;
}
void query(int x,int l,int r,int tl,int tr)
{
	if(l>tr||r<tl||!(ans<0))return;
//	cout<<x<<" "<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<id[x]<<endl;
//	cout<<lsh[l]<<" "<<lsh[r]<<" "<<lsh[tl]<<" "<<lsh[tr]<<endl;
//	cout<<preval<<" "<<ans<<endl;
//	system("pause");
	if(tl<=l&&r<=tr)
	{
//		cout<<"111 "<<x<<" "<<l<<" "<<r<<" "<<id[x]<<" "<<preval<<" "<<datk[x]<<endl;
//		cout<<mn[x]<<" "<<sum[x]<<endl;
//		system("pause");
	//	if(preval+mn[x]>0){preval+=sum[x];return;}
		if(id[x]==-1)
		{
//			cout<<tl<<" "<<cal_tl[leftmostid[x]]-1<<" "<<cal_tl[rightmostid[x]]-1<<endl;system("pause");
			if(tl>cal_tl[rightmostid[x]]-1){if(preval<=0)ans=lsh[tl];return;}
			if(tl<=cal_tl[leftmostid[x]]-1){if(preval+mn[x]>0){preval+=sum[x];return;}}
			if(l==r){if(preval<=0)ans=max(lsh[l]-1,lsh[tl]);return;}
			int mid=(l+r)/2;
			query(x*2,l,mid,tl,tr);if(ans>=0)return;
			query(x*2+1,mid+1,r,tl,tr);return;
		}
		else//preval+kx+b=0
		{
		//	cout<<tl<<" "<<cal_tl[id[x]]<<endl;
			if(id[x]==-2||tl>cal_tl[id[x]]-1){if(preval<=0)ans=lsh[tl];return;}
			if(preval+mn[x]>0){preval+=sum[x];return;}
			double pos=1.0*(-preval)/datk[x];
			if(l==cal_tl[id[x]])pos+=lsh[l]-1;
			else pos+=lsh[l-1];
		//	cout<<pos<<endl;
			double Lbound=(l==cal_tl[id[x]]?lsh[l]-1:lsh[l-1]);
			if((Lbound)<=(pos+eps)&&pos<=(1.0*lsh[r]+eps)&&lsh[tl]*1.0<=(pos+eps)){ans=pos;return;}
		}
		preval+=sum[x];return;
	}
	else
	{
//		cout<<"222 "<<x<<" "<<l<<" "<<r<<" "<<id[x]<<" "<<preval<<" "<<datk[x]<<endl;system("pause");
		if(id[x]==-1)
		{
			int mid=(l+r)/2;
			query(x*2,l,mid,tl,tr);if(!(ans<0))return;
			query(x*2+1,mid+1,r,tl,tr);return;
		}
		else//在某种程度上包含一段区间，但是不完全包含
		{
			if(id[x]==-2||tl>cal_tl[id[x]]-1){if(preval<=0)ans=lsh[tl];return;}//cout<<id[x]<<" "<<datk[x]<<endl;
			double pos=1.0*(-preval)/datk[x];
			if(l==cal_tl[id[x]])pos+=lsh[l]-1;
			else pos+=lsh[l-1];
		//	cout<<pos<<endl;
			double Lbound=(l==cal_tl[id[x]]?lsh[l]-1:lsh[l-1]);
			if((Lbound)<=(pos+eps)&&pos<=1.0*lsh[r]+eps&&lsh[tl]*1.0<=pos+eps&&pos<=lsh[tr]*1.0+eps){ans=pos;return;}
			preval+=datk[x]*(lsh[r]-lsh[l]+1);return;
		}
	}
}
int main()
{
//	freopen("data.in","r",stdin);
	int q;scanf("%d",&q);for(int i=0;i<q;i++){scanf("%d",&tp[i]);if(tp[i]==1){scanf("%I64d%I64d",&read_tl[i],&read_tval[i]);lsh.push_back(read_tl[i]);lsh.push_back(read_tl[i]+1);}else if(tp[i]==2){scanf("%I64d",&read_tl[i]);}else{scanf("%I64d%I64d%I64d",&read_tl[i],&read_tr[i],&read_tval[i]);lsh.push_back(read_tl[i]);lsh.push_back(read_tr[i]);}}

	sort(lsh.begin(),lsh.end());lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end());n=lsh.size();
	memset(id,-1,sizeof(id));modify(1,0,n-1,0,n-1,0,0,-2);
	for(int i=0;i<q;i++)
	{
		if(tp[i]==1)
		{
			cal_tl[i]=lower_bound(lsh.begin(),lsh.end(),read_tl[i]+1)-lsh.begin();
			it=st.lower_bound(read_tl[i]);
			covr[i]=(it==st.end()?n:cal_tl[ttoi[*it]])-1;
		//	cout<<"insert "<<i<<" "<<cal_tl[i]<<" "<<covr[i]<<endl;
		//	system("pause");
			modify(1,0,n-1,cal_tl[i],covr[i],read_tval[i],-read_tval[i]*1ll*read_tl[i],i);
			if(it!=st.begin())
			{
				--it;
				pred=ttoi[*it];
				covr[pred]=cal_tl[i]-1;
			//	cout<<"modify "<<pred<<" "<<cal_tl[pred]<<" "<<covr[pred]<<endl;
			//	system("pause");
				modify(1,0,n-1,cal_tl[pred],covr[pred],read_tval[pred],-read_tval[pred]*1ll*read_tl[pred],pred);
			}
			else
			{
				if(cal_tl[i]-1>=0)
				{
				//	cout<<"modify "<<-2<<" "<<0<<" "<<cal_tl[i]-1<<endl;
				//	system("pause");
					modify(1,0,n-1,0,cal_tl[i]-1,0,0,-2);
				}
			}
			st.insert(read_tl[i]);ttoi[read_tl[i]]=i;
		}
		else if(tp[i]==2)
		{
			it=st.lower_bound(read_tl[i]);
			curd=ttoi[read_tl[i]];
			if(it!=st.begin())
			{
				--it;
				pred=ttoi[*it];
				covr[pred]=covr[curd];
			//	cout<<"erase "<<i<<" "<<pred<<" "<<cal_tl[pred]<<" "<<covr[pred]<<endl;
			//	system("pause");
				modify(1,0,n-1,cal_tl[pred],covr[pred],read_tval[pred],-read_tval[pred]*1ll*read_tl[pred],pred);
			}
			else
			{
			//	cout<<"erase "<<i<<" "<<0<<" "<<covr[curd]<<endl;
			//	system("pause");
				modify(1,0,n-1,0,covr[curd],0,0,-2);
			}
			st.erase(read_tl[i]);
		}
		else
		{
			cal_tl[i]=lower_bound(lsh.begin(),lsh.end(),read_tl[i])-lsh.begin();
			cal_tr[i]=lower_bound(lsh.begin(),lsh.end(),read_tr[i])-lsh.begin();
			ans=-1;preval=read_tval[i];
			query(1,0,n-1,cal_tl[i],cal_tr[i]);
			printf("%.8f\n",ans);//system("pause");
		}
	}
	return 0;
}
//-1 表示当前区间没有被某事件完全覆盖，和-2的含义不同。-2表示的是覆盖为0

#include <bits/stdc++.h>

using namespace std;

const int N = 200010;
const int K = sqrt(N) + 1;
const int INF = (int)1e9 + 10;
const long long INF_LL = (long long)2e18;

int q, k;
vector<int> a[N];
vector<int> moment;
int val[N];

struct Bucket {
    int cnt, firstApp, lastS;
    long long minVal, delta;

    Bucket(int cnt = 0, int firstApp = -1, int lastS = -INF, long long minVal = 0, long long delta = 0) :
        cnt(cnt), firstApp(firstApp), lastS(lastS), minVal(minVal), delta(delta) {}

    void reset() {
        cnt = 0;
        firstApp = -1;
        lastS = -INF;
        minVal = 0;
        delta = 0;
    }

    void debug() {
        cerr << cnt << ' ' << firstApp << ' ' << lastS << ' ' << minVal << ' ' << delta << endl;
    }
} b[N / K + 10];

void init() {
    sort(moment.begin(), moment.end());
    moment.resize(unique(moment.begin(), moment.end()) - moment.begin());
    for (int i = 0; i < moment.size(); i++) val[i] = INF;
}

void updateBucket(int pos) {
    int u = pos / k;
    b[u].reset();
    int curS = 0;
    for (int i = k * u; i < min(k * (u + 1), (int)moment.size() - 1); i++) {
        if (val[i] == INF) {
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        } else {
            b[u].cnt++;
            if (b[u].firstApp == -1) b[u].firstApp = i;
            curS = val[i];
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        }
        b[u].minVal = min(b[u].minVal, b[u].delta);
    }
    b[u].lastS = curS;
}

bool go(long long &v, int &curS, int l, int r, long double &res) {
    for (int i = l; i < r; i++) {
        if (val[i] != INF) curS = val[i];
        if (v + 1ll * curS * (moment[i + 1] - moment[i]) <= 0ll) {
            res = -(long double)v / curS + moment[i];
            return 1;
        }
        v += 1ll * curS * (moment[i + 1] - moment[i]);
    }
    return 0;
}

long double getRes(int l, int r, long long v) {
    l = lower_bound(moment.begin(), moment.end(), l) - moment.begin();
    r = lower_bound(moment.begin(), moment.end(), r) - moment.begin();
    if (v == 0) return moment[l];
    if (moment.size() == 1) {
        return -1;
    }
    r--;
    int ll = l / k;
    int rr = r / k;
    if (ll == rr) {
        int curS = 0;
        long double res = -1;
        if (go(v, curS, l, r + 1, res)) return res;
        else return -1;
    }
    int curS = 0;
    long double res = -1;
    if (go(v, curS, l, min(k * (ll + 1), (int)moment.size() - 1), res)) return res;
    for (int i = ll + 1; i < rr; i++) {
        if (b[i].cnt == 0) {
            int fullTime = moment[k * (i + 1)] - moment[k * i];
            if (v + 1ll * curS * fullTime <= 0) return -(long double)v / curS + moment[k * i];
            v += 1ll * curS * fullTime;
            continue;
        }
        int foo = moment[b[i].firstApp] - moment[i * k];
        if (v + 1ll * curS * foo <= 0ll) {
            return -(long double)v / curS + moment[i * k];
        }
        v += 1ll * curS * foo;
        if (v + b[i].minVal <= 0) {
            if (go(v, curS, b[i].firstApp, min(k * (i + 1), (int)moment.size() - 1), res)) return res;
        } else {
            v += b[i].delta;
            curS = b[i].lastS;
        }
    }
    if (go(v, curS, k * rr, r + 1, res)) return res;
    return -1;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        int op;
        cin >> op;
        a[i].push_back(op);
        if (op == 1) {
            int t, s;
            cin >> t >> s;
            moment.push_back(t);
            a[i].push_back(t);
            a[i].push_back(s);
        } else if (op == 2) {
            int t;
            cin >> t;
            moment.push_back(t);
            a[i].push_back(t);
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            moment.push_back(l);
            moment.push_back(r);
            a[i].push_back(l);
            a[i].push_back(r);
            a[i].push_back(v);
        }
    }
    init();
    k = sqrt(moment.size()) + 1;

    for (int i = 1; i <= q; i++) {
        if (a[i][0] == 1) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = a[i][2];
            updateBucket(pos);
        } else if (a[i][0] == 2) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = INF;
            updateBucket(pos);
        } else {
            double ans = getRes(a[i][1], a[i][2], a[i][3]);
            if (ans < 0) cout << -1 << '\n';
            else cout << fixed << setprecision(10) << ans << '\n';
        }
        // cerr << "q " << i << ' ' << endl;
        // for (int i = 0; i < (int)moment.size() / k; i++) {
        //     cerr << "number " <<  i << ' ' ;
        //     b[i].debug();
        // }
    }
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution<int> distr;

int mrand()
{
    return distr(rng);
}

struct Node
{
    int key, prior;
    ll cap;
    ll min, finish;
    int id;
    int left, right;
    int leftmost, rightmost;

    Node(int _key, ll _cap, int _id): key(_key), cap(_cap), id(_id) {
        prior = mrand();
        min = finish = 0;
        left = right = 0;
        leftmost = rightmost = id;
    }
    Node() {};

    void show() {
        printf("%d %d %lld %lld %lld\n", id, key, cap, min, finish);
    }

    void recalc();
    void dfs();
};

const int N = (int)1e5 + 5;

int sz = 1;
Node treap[2 * N];

int build(int key, int cap) {
    treap[sz] = Node(key, cap, sz);
    return sz++;
}

ll get_min(int T) {
    return T ? treap[T].min : 0;
}
ll get_finish(int T) {
    return T ? treap[T].finish : 0;
}

void Node::recalc() {
    leftmost = (left ? treap[left].leftmost : id);
    rightmost = (right ? treap[right].rightmost : id);

    ll Tmin = get_min(left);
    ll Tfinish = get_finish(left);
    if (left)
        Tfinish += (key - treap[treap[left].rightmost].key) * treap[treap[left].rightmost].cap;
    Tmin = std::min(Tmin, Tfinish);
    if (right)
        Tfinish += (treap[treap[right].leftmost].key - key) * cap;
    Tmin = std::min(Tmin, Tfinish + get_min(right));
    Tfinish += get_finish(right);
    Tmin = std::min(Tmin, Tfinish);

    min = Tmin;
    finish = Tfinish;
}
void Node::dfs() {
    show();
    if (left) printf("%d->left\n", id), treap[left].dfs();
    if (right) printf("%d->right\n", id), treap[right].dfs();
}

void recalc(int T) {
    if (!T) return;
    treap[T].recalc();
}

int merge(int T1, int T2) {
    if (!T1) return T2;
    if (!T2) return T1;

    if (treap[T1].prior > treap[T2].prior) {
        treap[T2].left = merge(T1, treap[T2].left);
        recalc(T2);
        return T2;
    } else {
        treap[T1].right = merge(treap[T1].right, T2);
        recalc(T1);
        return T1;
    }
}
void split(int T, int key, int & T1, int & T2) {
    if (!T) {
        T1 = T2 = 0;
        return;
    }
    if (key < treap[T].key) {
        split(treap[T].left, key, T1, T2);
        treap[T].left = T2;
        T2 = T;
    } else {
        split(treap[T].right, key, T1, T2);
        treap[T].right = T1;
        T1 = T;
    }
    recalc(T);
}

void insert(int & T, int key, int val) {
    int T1, T2;
    split(T, key - 1, T1, T2);
    T = merge(merge(T1, build(key, val)), T2);
}
void erase(int & T, int key) {
    int T1, T2, T3, T4;
    split(T, key - 1, T1, T2);
    split(T2, key, T3, T4);
    T = merge(T1, T4);
}
double calc(ll start, ll time, ll cap) {
    //printf("%lld %lld %lld\n", start, time, cap);
    if (start == 0)
        return time;
    if (cap >= 0)
        return -1;
    return time - double(start) / cap;
}
double get_ans(int T, ll start) {
    if (!T) return -1;
    //printf("%d %lld\n", T, treap[T].finish);
    while(true) {
        if (start + treap[T].min > 0) {
            return calc(start + treap[T].finish, treap[treap[T].rightmost].key, treap[treap[T].rightmost].cap);
        }
        double tm, sp;
        if (treap[T].left) {
            if (start + treap[treap[T].left].min <= 0) {
                T = treap[T].left;
                continue;
            }
            start += get_finish(treap[T].left);
            tm = treap[treap[treap[T].left].rightmost].key;
            sp = treap[treap[treap[T].left].rightmost].cap;
            if (start + (treap[T].key - tm) * sp <= 0) {
                return calc(start, tm, sp);
            }
            start += (treap[T].key - tm) * sp;
        }
        if (treap[T].right) {
            tm = treap[treap[treap[T].right].leftmost].key;
            sp = treap[T].cap;
            if (start + (tm - treap[T].key) * sp <= 0) {
                return calc(start, treap[T].key, sp);
            }
            start += (tm - treap[T].key) * sp;
            T = treap[T].right;
        }
    }
}

void dfsT(int T) {
    if (!T) return;
    printf("\n\n");
    treap[T].dfs();
    printf("\n\n");
}

int main()
{
    //freopen("input.txt", "r", stdin);

    int q;
    scanf("%d", &q);

    int T = 0;
    for (int i = 0; i < q; ++i) {
        int type;
        scanf("%d", &type);
        if (type == 1) {
            int t, cap;
            scanf("%d %d", &t, &cap);
            insert(T, t, cap);
        }
        if (type == 2) {
            int t;
            scanf("%d", &t);
            erase(T, t);
        }
        if (type == 3) {
            int l, r, start;
            scanf("%d %d %d", &l, &r, &start);
            if (start == 0) {
                printf("%d\n", l);
                continue;
            }
            int T1, T2, T3, T4;
            split(T, l - 1, T1, T2);
            split(T2, r, T3, T4);
            double ans = get_ans(T3, start);
            if (ans < 0 || ans > r + 1e-9)
                printf("-1\n");
            else
                printf("%.15f\n", ans);
            T = merge(merge(T1, T3), T4);
        }
    }
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;

#define pb push_back
#define forn(i, n) for (int i = 0; i < (int)(n); i++)
#define forrn(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define PYMOD(a, m) ((((a) % (m)) + (m)) % (m))
#define all(v) v.begin(), v.end()
#define mp make_pair
#define ff first
#define ss second

template<class T>
class splay_tree_base {
    struct node {
        T value;
        node *L, *R, *par;
        node(const T& val)
            : value(val)
            , L(nullptr)
            , R(nullptr)
            , par(nullptr)
        {}

        void update() {
            value.update(L ? &L->value : nullptr, R ? &R->value : nullptr);
        }
    };

    void update(node *v) {
        if (v) {
            v->update();
        }
    }

    void single_rotate(node *y) {
        assert(y != nullptr);
        assert(y->par != nullptr);
        node *x = y->par;
        if (x->par) {
            if (x->par->L == x)
                x->par->L = y;
            else
                x->par->R = y;
        }
        y->par = x->par;
        if (x->L == y) {
            node *B = y->R;
            x->L = B;
            if (B) B->par = x;
            y->R = x;
            x->par = y;
        } else {
            assert(x->R == y);
            node *B = y->L;
            x->R = B;
            if (B) B->par = x;
            y->L = x;
            x->par = y;
        }
        update(x);
        update(y);
    }

    node *root = nullptr;

    void splay(node *v) {
        while (v->par) {
            if (v->par->par == nullptr) {
                single_rotate(v);
            } else if ((v->par->par->L == v->par && v->par->L == v)
                    || (v->par->par->R == v->par && v->par->R == v)) {
                single_rotate(v->par);
                single_rotate(v);
            } else {
                single_rotate(v);
                single_rotate(v);
            }
        }
    }

    template<class X>
    node *lower_bound_internal(X& value) {
        node *cur = root;
        node *ans = nullptr;
        while (cur != nullptr) {
            if (cur->value < value) {
                value.to_right(cur->L ? &cur->L->value : nullptr);
                cur = cur->R;
            } else {
                ans = cur;
                value.to_left(cur->R ? &cur->R->value : nullptr);
                cur = cur->L;
            }
        }
        return ans;
    }

    template<class X>
    void split_left(X& value, node *&left, node *&right) {
        node *v = lower_bound_internal(value);
        if (v == nullptr) {
            left = root;
            right = nullptr;
        } else if (value < v->value) {
            splay(v);
            left = v->L;
            right = v;
            if (v->L)
                v->L->par = nullptr;
            v->L = nullptr;
            update(v);
        } else {
            splay(v);
            left = v;
            right = v->R;
            if (v->R)
                v->R->par = nullptr;
            v->R = nullptr;
            update(v);
        }
    }

    template<class X>
    void split_right(X& value, node *&left, node *&right) {
        node *v = lower_bound_internal(value);
        if (v == nullptr) {
            left = root;
            right = nullptr;
        } else {
            splay(v);
            left = v->L;
            right = v;
            if (v->L)
                v->L->par = nullptr;
            v->L = nullptr;
            update(v);
        }
    }

    node *merge(node *left, node *right) {
        if (!left)
            return right;
        node *v = left;
        while (v->R)
            v = v->R;
        splay(v);
        v->R = right;
        if (right) {
            right->par = v;
        }
        update(v);
        return v;
    }

    template<class F>
    void for_each(const F& f, node *v) {
        if (v->L) for_each(f, v->L);
        f(v->value);
        if (v->R) for_each(f, v->R);
    }

    splay_tree_base(node *rt)
        : root(rt)
    {}

public:
    splay_tree_base() {}

    splay_tree_base(const T& value)
        : root(new node(value))
    {}

    splay_tree_base(const splay_tree_base<T>&) = delete;
    splay_tree_base<T>& operator=(const splay_tree_base<T>&) = delete;
    splay_tree_base(splay_tree_base<T>&&) = default;
    splay_tree_base<T>& operator=(splay_tree_base<T>&&) = default;

    template<class X>
    pair<splay_tree_base<T>, splay_tree_base<T>> split_left(X value) {
        node *left, *right;
        split_left(value, left, right);
        root = nullptr;
        return mp(splay_tree_base<T>(left), splay_tree_base<T>(right));
    }

    template<class X>
    pair<splay_tree_base<T>, splay_tree_base<T>> split_right(X value) {
        node *left, *right;
        split_right(value, left, right);
        root = nullptr;
        return mp(splay_tree_base<T>(left), splay_tree_base<T>(right));
    }

    template<class X>
    T* lower_bound(X value) {
        node *v = lower_bound_internal(value);
        return v ? &v->value : nullptr;
    }

    void merge_to(splay_tree_base<T>&& right) {
        root = merge(root, right.root);
    }

    T* root_value() {
        return root ? &root->value : nullptr;
    }

    template<class F>
    void for_each(const F& functor) {
        if (root) {
            for_each(functor, root);
        }
    }

    class iterator {
        node *v;
    public:
        iterator(node *n)
            : v(n)
        {}

        const T& value() {
            return v->value;
        }

        bool has_left() {
            return v->L;
        }

        bool has_right() {
            return v->R;
        }

        iterator left() {
            return iterator(v->L);
        }

        iterator right() {
            return iterator(v->R);
        }
    };

    iterator root_iterator() const {
        return iterator(root);
    }

    bool empty() const {
        return root == nullptr;
    }
};

template<class T>
struct explicit_key {
    T value;

    explicit_key(const T& val)
        : value(val)
    {}

    void update(explicit_key<T>*, explicit_key<T>*) {}

    void to_left(explicit_key<T>*) {}

    void to_right(explicit_key<T>*) {}

    bool operator<(const explicit_key<T>& other) const {
        return value < other.value;
    }
};

template<class T, template<class> class K = explicit_key>
class splay_tree {
    using base_t = splay_tree_base<K<T>>;
    base_t tree;

    splay_tree(base_t&& b)
        : tree(std::forward<base_t>(b))
    {}

public:
    splay_tree() {}

    splay_tree(const splay_tree<T, K>&) = delete;
    splay_tree<T, K>& operator=(const splay_tree<T, K>&) = delete;
    splay_tree(splay_tree<T, K>&&) = default;
    splay_tree<T, K>& operator=(splay_tree<T, K>&&) = default;

    void insert(const T& value) {
        auto p = tree.split_left(K<T>(value));
        p.first.merge_to(base_t(value));
        p.first.merge_to(std::move(p.second));
        tree = std::move(p.first);
    }

    bool count(const T& value) {
        auto v = tree.lower_bound(K<T>(value));
        return v && v->value == value;
    }

    void erase(const T& value) {
        auto p = tree.split_left(K<T>(value));
        auto q = p.first.split_right(K<T>(value));
        tree = std::move(q.first);
        tree.merge_to(std::move(p.second));
    }

    template<class F>
    void for_each(const F& f) {
        tree.for_each([&f](const K<T>& x) { f(x.value); });
    }

    using iterator = typename base_t::iterator;

    iterator root_iterator() {
        return tree.root_iterator();
    }

    template<class X>
    pair<splay_tree<T, K>, splay_tree<T, K>> split_left(const X& value) {
        auto p = tree.split_left(K<X>(value));
        return make_pair(splay_tree<T, K>(std::move(p.first)), splay_tree<T, K>(std::move(p.second)));
    }

    template<class X>
    pair<splay_tree<T, K>, splay_tree<T, K>> split_right(const X& value) {
        auto p = tree.split_right(K<X>(value));
        return make_pair(splay_tree<T, K>(std::move(p.first)), splay_tree<T, K>(std::move(p.second)));
    }

    void merge_to(splay_tree<T, K>&& right) {
        tree.merge_to(std::move(right.tree));
    }

    bool empty() const {
        return tree.empty();
    }

    const K<T>& root_key() const {
        return tree.root_iterator().value();
    }
};

struct event {
    ll time, speed;

    event(ll t, ll s)
        : time(t)
        , speed(s)
    {}

    event(ll t)
        : time(t)
    {}

    bool operator==(const event& other) const {
        return time == other.time;
    }

    bool operator<(const event& other) const {
        return time < other.time;
    }

    bool operator<(ll tm) const {
        return time < tm;
    }
};

template<class E>
struct event_key : public explicit_key<E> {
    ll tL, tR;
    ll speedR;
    ll res;
    ll mn;

    event_key(E e)
        : explicit_key<E>(e)
        , tL(e.time)
        , tR(e.time)
        , speedR(e.speed)
        , res(0)
        , mn(0)
    {}

    void update(event_key<E>* L, event_key<E>* R) {
        mn = 0, res = 0;
        if (L) {
            mn = min(mn, L->mn);
            res += L->res + L->speedR * (explicit_key<E>::value.time - L->tR);
        }
        mn = min(mn, res);
        if (R) {
            res += explicit_key<E>::value.speed * (R->tL - explicit_key<E>::value.time);
            mn = min(mn, res + R->mn);
            res += R->res;
        }
        mn = min(mn, res);

        tL = explicit_key<E>::value.time;
        if (L) tL = L->tL;
        tR = explicit_key<E>::value.time;
        if (R) tR = R->tR;
        speedR = explicit_key<E>::value.speed;
        if (R) speedR = R->speedR;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);

    splay_tree<event, event_key> tr;

    tr.insert(event(0, 0));

    int q;
    cin >> q;

    forn(i, q) {
        int type;
        cin >> type;
        if (type == 1) {
            ll t, s;
            cin >> t >> s;
            tr.erase(event(t));
            tr.insert(event(t, s));
        } else if (type == 2) {
            ll t;
            cin >> t;
            tr.erase(event(t));
        } else {
            ll l, r; ll s;
            cin >> l >> r >> s;
            auto p = tr.split_right(event(l));
            auto q = p.ss.split_left(event(r));

            event prev(0, 0);
            if (!p.ff.empty())
                prev = p.ff.root_key().value;
            if (q.ff.empty()) {
                if (s == 0) {
                    cout << l << endl;
                } /*else if (s + (r - l) * prev.speed <= 0) {
                    printT = true;
                    cout << l + (ld)s / (-prev.speed) << endl;
                }*/ else {
                    cout << -1 << endl;
                }
            } else {
                event_key first = event(-1);
                if (!q.ff.empty())
                    first = q.ff.root_key();
                if (s == 0) {
                    cout << l << endl;
                } /*else if (s + (first.tL - l) * prev.speed <= 0) {
                    cout << l + (ld)s / (-prev.speed) << endl;
                }*/ else {
                    //s += (first.tL - l) * prev.speed;
                    if (first.mn + s <= 0) {
                        ll ctime = first.tL;
                        auto it = q.ff.root_iterator();
                        while (true) {
                            assert(it.has_left() || it.has_right());
                            if (it.has_left()) {
                                if (s + it.left().value().mn <= 0) {
                                    it = it.left();
                                    continue;
                                }
                                s += it.left().value().res;
                                ctime = it.left().value().tR;
                                if (s + (it.value().value.time - ctime) * it.left().value().speedR <= 0) {
                                    cout << ctime + (ld)s / (-it.left().value().speedR) << endl;
                                    break;
                                }
                                s += (it.value().value.time - ctime) * it.left().value().speedR;
                                ctime = it.value().value.time;
                            }
                            if (it.has_right()) {
                                if (s + (it.right().value().tL - ctime) * it.value().value.speed <= 0) {
                                    cout << ctime + (ld)s / (-it.value().value.speed) << endl;
                                    break;
                                }
                                s += (it.right().value().tL - ctime) * it.value().value.speed;
                                ctime = it.right().value().tL;
                                it = it.right();
                            }
                        }
                    } else {
                        s += first.res;
                        if (s + (r - first.tR) * first.speedR <= 0) {
                            cout << first.tR + (ld)s / (-first.speedR) << endl;
                        } else {
                            cout << -1 << endl;
                        }
                    }
                }
            }

            p.ff.merge_to(std::move(q.ff));
            p.ff.merge_to(std::move(q.ss));
            tr = std::move(p.ff);
        }
    }

    return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q,st,tcnt,jeste,tip2c;
ll inf=3e18;
mt19937 gen(500);
map<ll,ll> mapa;
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void upd(pnode x){
    if(x==NULL)return;
    x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
}
void ispis(pnode x,int &ct){

    if(ct<1)return;
    if(x==NULL)return;
    push(x);

    ispis(x->l,ct);
    ct--;
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r,ct);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(ll t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;tt=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        ll upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_mn(x->l)<=val)qry(x->l,val,tm);
    else if(x->val<=val){
        tm=x->t;
        if(jeste)cout<<x->val<<" "<<val<<" "<<x->t<<" EVEGGAA\n";
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    if(midtree==NULL){ret=-1;}
    else{

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*if(jeste){
            printf("\n\nISPIS A\n");
            int pm=12;
            ispis(midtree,pm);
            printf("\n");
        }*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
        if(jeste)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;

            last_node(midtree,lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            ////printf("%d TMTM\n",tm);

            pnode lst=NULL;
            last_node(pom1,lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            if(jeste)cout<<zero<<" "<<lst->val<<" "<<lst->s<<" "<<lst->t<<" "<<l<<" "<<r<<" EVOGA\n";

            mrg(midtree,pom1,pom2);
        }
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
ll nadji(pnode x,ll val){

    if(x==NULL)return inf;
    push(x);

    if(val==x->t)return x->val;
    else if(val<x->t)return nadji(x->l,val);
    else return nadji(x->r,val);
}
bool check(){

    ll curr=0;
    ll t,s;
    int br=0;
    for(map<ll,ll>::iterator it=mapa.begin();it!=mapa.end();){

        t=it->ff;
        s=it->ss;

        br++;

        ll pom=nadji(root,t);
        if(pom!=curr){
            printf("%lld %lld | %lld %d %d\n",pom,curr,t,br,tip2c);
            return false;
        }

        it++;

        if(it==mapa.end())break;
        curr=curr+(it->ff-t)*s;
    }

    return true;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    st=0;
    int inscnt=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(st==0)st=t;
            ///if(sq==100000 && st==940132043)if(mapa.find(t)!=mapa.end())continue;
            ins(t,s);
            mapa[t]=s;

            /*
            if(sq==100000 && st==940132043)printf("PROSAO\n");*/
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            ///if(sq==100000 && st==940132043)continue;
            del(t);

            tip2c++;
            mapa.erase(t);

            /*if(sq==100000 && st==940132043){
                ///int csap=100000;
                ///ispis(root,csap);
                if(!check())break;
            }

            if(sq==100000 && st==940132043)printf("PROSAO\n");*/

              /*  inscnt++;
            if(sq==100000 && st==940132043 && inscnt%1==0){
                ///int csap=100000;
                ///ispis(root,csap);
                if(!check())break;
            }*/
        }
        else{
            int l,r,v;
            tcnt++;
            scanf("%d %d %d",&l,&r,&v);
            if(v==0){
                printf("%d\n",l);
                continue;
            }
           /* if(sq==100000 && st==940132043){

             if(tcnt==2846){
                jeste=1;

                check();

                printf("NASAO\n");
                cout<<fixed;
                cout<<setprecision(6);
                cout<<query(l,r,v)<<endl;
             }
            }
            else{*/
                cout<<fixed;
                cout<<setprecision(6);
                cout<<query(l,r,v)<<endl;
            ///}
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>
using std::cin;using std::cerr;
using std::max;using std::min;
#define N 100005
#define eps 1e-9
#define ll long long
#define db double
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
int n,m,op,a,b,c;ll nowk,nowb;
class SegmentTree
{
#define lc t[x].ls
#define rc t[x].rs
#define mid (l+r>>1)
	struct node{int ls,rs,t,k;ll Min,b;}t[N*32];
	void cover(int x,int y) {int l=lc,r=rc;t[x]=t[y],lc=l,rc=r;}
	void pushup(int x,int l,int r)
	{
		if(!t[lc].t&&!t[rc].t) {t[x].t=t[x].k=t[x].Min=t[x].b=0;return;}
		if(!t[lc].t) return cover(x,rc);
		if(!t[rc].t)
		{
			cover(x,lc),t[x].b+=(ll)t[x].k*(r-mid),t[x].Min=min(t[x].Min,t[x].b);
			return;
		}
		cover(x,lc),t[x].b+=(ll)t[x].k*(t[rc].t-mid),t[x].Min=min(t[x].Min,t[x].b+t[rc].Min);
		t[x].k=t[rc].k,t[x].b+=t[rc].b,t[x].Min=min(t[x].Min,t[x].b);
	}
public:
	int root,cntnode;
	void change(int &x,int l,int r,int p,int v)
	{
		if(!x) x=++cntnode;
		if(l==r) {t[x].t=l,t[x].k=v;return;}
		p<=mid?change(lc,l,mid,p,v):change(rc,mid+1,r,p,v);
		pushup(x,l,r);
	}
	void Delete(int x,int l,int r,int p)
	{
		if(l==r) {t[x].t=t[x].k=t[x].Min=t[x].b=0;return;}
		p<=mid?Delete(lc,l,mid,p):Delete(rc,mid+1,r,p);
		pushup(x,l,r);
	}
	db ask(int x,int l,int r,int _l,int _r)
	{
		if(_l<=l&&r<=_r)
		{
			if(t[x].t)
			{
				if(nowb+(ll)(t[x].t-l+1)*nowk<=0) return l-1-nowb*1./nowk;
				if(nowb+(ll)(t[x].t-l+1)*nowk+t[x].Min<=0)
				{
					db res=ask(lc,l,mid,_l,_r);
					if(fabs(res+1)<eps) res=ask(rc,mid+1,r,_l,_r);
					return res;
				}
				nowb+=(ll)(t[x].t-l+1)*nowk;
				nowk=t[x].k,nowb+=t[x].b;
				return -1;
			}
			else
			{
				if(nowb+(ll)(r-l+1)*nowk<=0) return l-1-nowb*1./nowk;
				else return nowb+=(ll)(r-l+1)*nowk,-1;
			}
		}
		db res=-1;
		if(_l<=mid) res=ask(lc,l,mid,_l,_r);
		if(fabs(res+1)<eps&&_r>mid) res=ask(rc,mid+1,r,_l,_r);
		return res;
	}
}T;
int main()
{
	for(scanf("%d",&m);m--;)
	{
		scanf("%d%d",&op,&a);
		if(op==1) scanf("%d",&b),T.change(T.root,1,1e9,a,b);
		if(op==2) T.Delete(T.root,1,1e9,a);
		if(op==3)
		{
			scanf("%d%d",&b,&c),nowk=0,nowb=c;
			if(!c) {printf("%d\n",a);continue;}
			printf("%.6lf\n",T.ask(T.root,1,1e9,a,b));
		}
	}
	return 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=1<<30;
map<int,int> mp;
typedef pair<int,int> pp;
struct node {
	int ch[2],pri,mx,mi;
	pp val;
	ll sum,mn;
}t[100005];
int sz=0;
int read() {
	char c=getchar(); int x=0,f=1;
	while (c<'0' || c>'9') {
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
int newnode(int T,int S) {
	++sz;
	t[sz].ch[0]=t[sz].ch[1]=0;
	t[sz].val=make_pair(T,S);
	t[sz].pri=rand();
	t[sz].mx=t[sz].mi=sz;
	t[sz].sum=0;
	return sz;
}
ll calc(int x,int y) {
	return 1LL*t[x].val.second*(t[y].val.first-t[x].val.first);
}
void update(int x) {
	if (t[x].ch[1]) t[x].mx=t[t[x].ch[1]].mx;
	else t[x].mx=x;
	if (t[x].ch[0]) t[x].mi=t[t[x].ch[0]].mi;
	else t[x].mi=x;
	t[x].mn=0;
	t[x].mn=min(t[x].mn,t[t[x].ch[0]].mn);
	t[x].sum=t[t[x].ch[0]].sum;
	if (t[x].ch[0]) t[x].sum+=calc(t[t[x].ch[0]].mx,x);
	t[x].mn=min(t[x].mn,t[x].sum);
	if (t[x].ch[1]) t[x].sum+=calc(x,t[t[x].ch[1]].mi);
	t[x].mn=min(t[x].mn,t[x].sum+t[t[x].ch[1]].mn);
	t[x].sum+=t[t[x].ch[1]].sum;
	t[x].mn=min(t[x].mn,t[x].sum);
}
int merge(int x,int y) {
	if (!x || !y) return x^y;
	if (t[x].pri>t[y].pri) {
		t[x].ch[1]=merge(t[x].ch[1],y);
		update(x);
		return x;
	}
	else {
		t[y].ch[0]=merge(x,t[y].ch[0]);
		update(y);
		return y;
	}
}
void split(int now,pp k,int &x,int &y) {
	if (!now) x=y=0;
	else {
		if (t[now].val<=k) {
			x=now;
			split(t[x].ch[1],k,t[x].ch[1],y);
		}
		else {
			y=now;
			split(t[y].ch[0],k,x,t[y].ch[0]);
		}
		update(now);
	}
}
void insert(int &root,int T,int S) {
	int x,y;
	split(root,make_pair(T,S),x,y);
	root=merge(merge(x,newnode(T,S)),y);
}
void destroy(int &root,int T,int S) {
	int x,y,z;
	split(root,make_pair(T,S),y,z);
	split(y,make_pair(T,S-1),x,y);
	root=merge(x,z);
}
double find(int &root,int l,int r,ll v) {
	if (!v) return l;
	int x,y,z;
	split(root,make_pair(r,inf),y,z);
	split(y,make_pair(l-1,inf),x,y);
	if (!y) {
		root=merge(merge(x,y),z);
		return -1;
	}
	int now=y;
	while (now) {
		ll vv=v;
		if (vv+t[t[now].ch[0]].mn<=0 || vv+t[t[now].ch[0]].sum<=0) now=t[now].ch[0];
		else {
			vv+=t[t[now].ch[0]].sum;
			if (t[now].ch[0]) {
				vv+=calc(t[t[now].ch[0]].mx,now);
				if (vv<=0) break;
			}
			if (t[now].ch[1]) {
				vv+=calc(now,t[t[now].ch[1]].mi);
				if (vv<=0) break;
			}
			v+=t[now].sum-t[t[now].ch[1]].sum;
			now=t[now].ch[1];
		}
	}
	if (!now) {
		root=merge(merge(x,y),z);
		return -1;
	}
	if (t[now].ch[0]) {
		v+=t[t[now].ch[0]].sum;
		int p=t[t[now].ch[0]].mx;
		ll tmp=calc(p,now);
		if (v+tmp<=0) {
			root=merge(merge(x,y),z);
			return t[p].val.first-v*1.0/t[p].val.second;
		}
		v+=tmp;
	}
	root=merge(merge(x,y),z);
	return t[now].val.first-v*1.0/t[now].val.second;
}
int main() {
	srand((unsigned)time(NULL));
	int q=read(),root=0,x,y,z;
	for (int i=1; i<=q; i++) {
		int opt=read();
		if (opt==1) {
			int T=read(),S=read();
			insert(root,T,S);
			mp[T]=S;
		}
		else if (opt==2) {
			int T=read();
			destroy(root,T,mp[T]);
		}
		else {
			int l=read(),r=read(),v=read();
			insert(root,r,inf);
			printf("%.13f\n", find(root,l,r,v));
			destroy(root,r,inf);
		}
	}
	return 0;
}

/*----------------by syr----------------*/
/*
  -----  -----  -----
  |   |  |---|    _/
  |   |  | \_    /
  -----  |   \  -----

  |---\  \   /  |\  /|
  |   |   \_/   | \/ |
  |   |   / \   |    |
  |---/  /   \  |    |
*/
#include<bits/stdc++.h>

using namespace std;

#define PH push
#define MP make_pair
#define PB push_back
#define fst first
#define snd second
#define FOR(i,x,y) for(int i=(x);i<(y);++i)
#define REP(i,x,y) for(int i=(x);i<=(y);++i)
#define x0 x0123456789
#define y0 y0123456789
#define x1 x1234567890
#define y1 y1234567890
#define x2 x2345678901
#define y2 y2345678901
typedef double db;
typedef long long ll;
typedef long double ldb;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int maxn=1e5+5;
const ll INF=1e18;
const ll Inf=1e9+7;

ll tot=0;
db ans;
vector<ll> all;

class SegmentTree{
public:
    class Node{
    public:
        ll sum;
        ll mns;
        ll tag;
        Node():sum(0),mns(0),tag(INF){}
        Node operator +(const Node &b)const{
            Node ret;
            ret.sum=sum+b.sum;
            ret.mns=min(mns,sum+b.mns);
            return ret;
        }
        void print(){
        	printf("sum=%lld mns=%lld tag=%lld\n",sum,mns,tag);
        	return;
		}
    }dat[maxn*3<<2];
    int siz;
    int size(){return siz;}
    void init(int sz){
        for(siz=1;siz<sz;siz<<=1);
        return;
    }
    void pushDown(int x,int l,int r){
        ll tg=dat[x].tag;
        if(tg==INF) return;
        int md=l+r>>1;
        dat[x<<1].sum=tg*(all[md+1]-all[l]);
        dat[x<<1].tag=tg;
        dat[x<<1].mns=min(dat[x<<1].sum,0ll);
        dat[x<<1|1].sum=tg*(all[r+1]-all[md+1]);
        dat[x<<1|1].tag=tg;
        dat[x<<1|1].mns=min(dat[x<<1|1].sum,0ll);
        tg=0;
        return;
    }
    void update(int x,int l,int r,int s,int t,ll k){
		//printf("update: x=%d l=%d r=%d s=%d t=%d k=%lld\n",x,l,r,s,t,k);
        if(l>=s&&r<=t){
        	//puts("ok");
            dat[x].tag=k;
            dat[x].sum=k*(all[r+1]-all[l]);
            dat[x].mns=min(dat[x].sum,0ll);
            return;
        }
        int md=l+r>>1;
        pushDown(x,l,r);
        if(s<=md) update(x<<1,l,md,s,t,k);
        if(t>md) update(x<<1|1,md+1,r,s,t,k);
        dat[x]=dat[x<<1]+dat[x<<1|1];
        return;
    }
    bool query(int x,int l,int r,int s,int t,ll &v){
		//printf("query: x=%d l=%d r=%d s=%d t=%d v=%lld\n",x,l,r,s,t,v);
		//dat[x].print();
        if(l>=s&&r<=t){
            if(dat[x].mns>-v){
            	v+=dat[x].sum;
            	return false;
			}
            //puts("ok");
            if(l==r){
            	//printf("x=%d l=%d r=%d s=%d t=%d v=%lld sum=%lld mns=%lld tag=%lld\n",x,l,r,s,t,v,dat[x].sum,dat[x].mns,dat[x].tag);
                ans=all[l]+1.0*(-v)/(dat[x].tag);
                return true;
            }
            int md=l+r>>1;
            pushDown(x,l,r);
            if(!query(x<<1,l,md,s,t,v)) query(x<<1|1,md+1,r,s,t,v);
            dat[x]=dat[x<<1]+dat[x<<1|1];
            return true;
        }
        int md=l+r>>1;
        pushDown(x,l,r);
        dat[x]=dat[x<<1]+dat[x<<1|1];
        if(s<=md&&query(x<<1,l,md,s,t,v)) return true;
        if(t>md&&query(x<<1|1,md+1,r,s,t,v)) return true;
        return false;
    }
    void print(int x,int l,int r){
		printf("x=%d l=%d r=%d\n",x,l,r);
		dat[x].print();
		if(l==r) return;
		int md=l+r>>1;
		print(x<<1,l,md);
		print(x<<1|1,md+1,r);
		return;
	}
}seg;

int n,q;
int tp[maxn];
ll x[maxn],y[maxn],z[maxn];
set<pll> evn;
map<ll,int> mp;

int main(){
    scanf("%d",&q);
    FOR(i,0,q){
        scanf("%d",tp+i);
        if(tp[i]==1){
            scanf("%I64d%I64d",x+i,y+i);
            all.PB(x[i]);
        }
        else if(tp[i]==2){
            scanf("%I64d",x+i);
            all.PB(x[i]);
        }
        else{
            scanf("%I64d%I64d%I64d",x+i,y+i,z+i);
            all.PB(x[i]);
            all.PB(y[i]);
        }
    }
    all.PB(0);all.PB(Inf);
    sort(all.begin(),all.end());
    all.erase(unique(all.begin(),all.end()),all.end());
    n=all.size();
    seg.init(n);
    FOR(i,0,all.size()) mp[all[i]]=i;
    evn.insert(MP(0ll,0ll));
    evn.insert(MP(Inf,0ll));
    FOR(i,0,q){
        if(tp[i]==1){
        	//puts("ok");
            set<pll>::iterator it=evn.upper_bound(MP(x[i],-INF));
            //printf("it: (%lld %lld) %d\n",it->fst,it->snd,mp[it->fst]);
            seg.update(1,0,seg.size()-1,mp[x[i]],mp[it->fst]-1,y[i]);
            evn.insert(MP(x[i],y[i]));
        }
        else if(tp[i]==2){
            set<pll>::iterator it1=evn.lower_bound(MP(x[i],-INF));--it1;
            set<pll>::iterator it2=evn.upper_bound(MP(x[i],INF));
            seg.update(1,0,seg.size()-1,mp[x[i]],mp[it2->fst]-1,it1->snd);
            evn.erase(++it1);
        }
        else{
			if(!z[i]){
				printf("%I64d\n",x[i]);
				continue;
			}
			tot=ans=0;
            set<pll>::iterator it1=evn.lower_bound(MP(x[i],-INF));
            set<pll>::iterator it2=evn.upper_bound(MP(y[i],INF));
			//if((it2->fst)!=Inf) --it2;
            if(!seg.query(1,0,seg.size()-1,mp[it1->fst],mp[it2->fst],z[i])||ans>y[i]) puts("-1");
            else printf("%.10f\n",ans);
        }
//        seg.print(1,0,seg.size());
    }
    return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <random>
#include <climits>
#include <iomanip>
#include <queue>
#include <bitset>
#include <cctype>

using namespace std;

#define forn(i,n) for (int i = 0;i < int(n);i++)
#define ford(i,n) for (int i = n-1;i >=0;i--)
#define fore(i,l,r) for (int i = int(l);i < int(r);i++)
#define forv(a) for(int i = 0;i < (a).size();i++) cin >> a[i]
#define correct(x,n) (((x) >= 0) && ((x) < n))
#define sort_all(a) sort((a).begin(),(a).end())
#define mp(a,b) make_pair((a),(b))
#define all(a) (a).begin(),(a).end()
#define pb(a) push_back(a)
#define rnd() (rand() + (RAND_MAX+1)*rand())
#define fi first
#define se second
#define V(A) vector<A>
//#define DEBUG_

//#define x first
//#define y second

typedef long long li;
typedef vector<int> vi;
typedef vector<li> vli;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<vi> vvi;
typedef vector<vli> vvli;
typedef long double ld;
typedef pair<li, li> Point;

const ld EPS = 1e-9;

class Node
{
public:
	li key,pr,s;
	li mn, mx, smx,d,dmn;//Min t,max t, s of max t,d,and minimum of d in subtree
	Node* l, *r;
	Node() {}

	Node(li key, li s) : key(key), s(s), mn(key), pr(rnd()), mx(key), smx(s),d(0),dmn(0),l(nullptr),r(nullptr) {}
};

typedef Node* DTree;

li getMin(DTree t)
{
	if (!t)
		return 1500000000;
	return t->mn;
}

li getMax(DTree t)
{
	if (!t)
		return 0;
	return t->mx;
}

li getSMax(DTree t)
{
	if (!t)
		return 0;
	return t->smx;
}

li getD(DTree t)
{
	if (!t)
		return 0;
	return t->d;
}

li getDMin(DTree t)
{
	if (!t)
		return 0;
	return t->dmn;
}

void update(DTree t)
{
	if (!t)
		return;

	t->mn = min(t->key, getMin(t->l));
	t->mx = max(t->key, getMax(t->r));

	if (t->key > getMax(t->r))
		t->smx = t->s;
	else
		t->smx = getSMax(t->r);

	li d = 0, dmn = 0;
	dmn = min(dmn, getDMin(t->l));
	d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	dmn = min(dmn, d);
	d += (t->r ? t->s*(getMin(t->r) - t->key) : 0);
	dmn = min(dmn, d + getDMin(t->r));
	d += getD(t->r);
	dmn = min(dmn, d);
	t->d = d;
	t->dmn = dmn;
}

void split(DTree t, DTree &l, DTree &r,li key)
{
	if (!t)
	{
		l = r = nullptr;
		return;
	}
	if (key < t->key)
		split(t->l, l, t->l, key), r = t;
	else
		split(t->r, t->r, r, key), l = t;
	update(t);
}

void merge(DTree &t, DTree l, DTree r)
{
	if (!l || !r)
	{
		t = (l ? l : r);
		return;
	}
	if (l->pr > r->pr)
		merge(l->r, l->r, r), t = l;
	else
		merge(r->l, l, r->l), t = r;
	update(t);
}

void insert(DTree &t,li key,li s)
{
	DTree tl, tm = new Node(key, s), tr;
	split(t, tl, tr, key);
	merge(t, tl, tm);
	merge(t, t, tr);
}

void erase(DTree &t, li key)
{
	DTree tl, tm, tr;
	split(t, tl, tm, key-1);
	split(tm, tm, tr, key);
	merge(t, tl, tr);
}

double getAns(DTree t,li r,li v)
{
	if (!t)
		return -1;

	if (t->dmn + v > 0)
		return (t->smx >= 0 || t->mx * t->smx - (t->d + v) < r * t->smx ? -1 : t->mx - (ld)(t->d + v) / t->smx);

	li dl = getDMin(t->l);
	li d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	li dr = d + (t->r ? t->s*(getMin(t->r) - t->key) : 0);

	if (dl + v <= 0)
		return getAns(t->l, r, v);

	if (d + v <= 0)
		return getMax(t->l) - (ld)(v + getD(t->l)) / getSMax(t->l);

	if (dr + v <= 0)
		return t->key - (ld)(v + d) / t->s;

	return getAns(t->r, r, v + dr);
}

double getAns(DTree t, li l, li r, li v)
{
	if (!v)
		return l;
	DTree tl, tm,tr;
	split(t, tl, tm, l - 1);
	split(tm, tm, tr, r);
	double ans = getAns(tm, r, v);
	merge(t, tl, tm);
	merge(t, t, tr);
	return ans;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	DTree t = nullptr;

	int n;
	cin >> n;
	forn(i, n)
	{
		int q;
		cin >> q;
		if (q == 1)
		{
			li key, s;
			cin >> key >> s;
			insert(t, key, s);
		}
		if (q == 2)
		{
			li key;
			cin >> key;
			erase(t, key);
		}
		if (q == 3)
		{
			li l, r, v;
			cin >> l >> r >> v;
			cout << setprecision(20) << getAns(t, l, r, v) << '\n';
		}
	}
}

#include <iostream>
#include <cstdio>

#include <set>
#include <algorithm>
#include <cmath>
#include <array>
#include <utility>

#include <cassert>

using namespace std;

#define ti(X) static_cast<int>(X)
using ll = long long;
#define tl(X) static_cast<ll>(X)
using ld = double;
#define tld(X) static_cast<ld>(X)

const int MQ = 1e5 + 100;
const int MV = 1e9 + 100;

int p[MQ<<1], P;

const ld EPS = 1e-4;
bool equ(ld a, ld b) {return fabs(a-b)<EPS;}

struct DT {
public:
  int l, r;
  ll v, u;
  int z;
  DT() : l(0), r(0), v(0LL), u(0LL), z(MV) {}
  DT(int l, int r) : l(l), r(r), v(0LL), u(0LL), z(MV) {}
  void set(int l, int r) {this->l = l, this->r = r;}
  ld operator [] (ll& q) const {
    if(q == 0) return l;
    assert(q + v <= 0);
    return l + tld(q)*(r-l)/(-v);
  }
};
template<int MS = MQ<<3> struct ST {
public:
  DT v[MS];
  int s;
  void sv(int n, int d) {
    v[n].v = tl(v[n].r-v[n].l)*d;
    v[n].u = d<0?v[n].v:0LL;
  }
  void sz(int n, int d) {
    sv(n, d);
    v[n].z = d;
  }
  void down(int n, int l, int r) {
    if(v[n].z == MV) return;
    if(r-l>1) sz(n<<1, v[n].z), sz(n<<1|1, v[n].z);
    v[n].z = MV;
  }
  void up(int n) {
    v[n].v = v[n<<1].v + v[n<<1|1].v;
    v[n].u = min(v[n<<1].u, v[n<<1].v + v[n<<1|1].u);
  }
  void init(int n, int l, int r) {
    if(r-l>1) {
      int m = l + ((r-l)>>1);
      init(n<<1, l, m), init(n<<1|1, m, r);
    }
    v[n].set(p[l], p[r]);
  }
  void init(int S) {
    s = S;
    init(1, 0, s);
  }
  void upd(int n, int l, int r, int ql, int qr, int q) {
    if(ql <= l&&r <= qr) sz(n, q);
    else {
      down(n, l, r);
      int m = l + ((r-l)>>1);
      if(ql < m) upd(n<<1, l, m, ql, qr, q);
      if(m < qr) upd(n<<1|1, m, r, ql, qr, q);
      up(n);
    }
  }
  void upd(int ql, int qr, int q) {upd(1, 0, s, ql, qr, q);}
  ld qry(int n, int l, int r, int ql, int qr, ll& q) {
    down(n, l, r);
    if(ql <= l&&r <= qr) {
      if(q + v[n].u > 0) return q += v[n].v, -1.0;
      if(r-l>1) {
        int m = l + ((r-l)>>1);
        if(q + v[n<<1].u <= 0) return qry(n<<1, l, m, ql, qr, q);
        else return qry(n<<1|1, m, r, ql, qr, q += v[n<<1].v);
      } else return v[n][q];
    } else {
      int m = l + ((r-l)>>1);
      ld f = -1.0;
      if(ql < m) {
        f = qry(n<<1, l, m, ql, qr, q);
        if(!equ(f, -1.0)) return f;
      }
      if(m < qr) return qry(n<<1|1, m, r, ql, qr, q);
      return -1.0;
    }
  }
  ld qry(int ql, int qr, ll& q) {return qry(1, 0, s, ql, qr, q);}
};
ST<> st;

int Q;
int q[MQ][4];

void cmpr() {
  sort(p, p + P);
  P = unique(p, p + P) - p;
  for(int i = 0;i < Q;i++) {
    q[i][1] = lower_bound(p, p + P, q[i][1])-p;
    if(q[i][0]==3)
      q[i][2] = lower_bound(p, p+P, q[i][2])-p;
  }
  p[P] = MV;
}
using i2 = array<int, 2>;
bool operator < (const i2& a, const i2& b) {return a[0] < b[0] || (!(b[0] < a[0]) && a[1] < b[1]);}
using si = set<i2>;
#define IT iterator
using sit = si::IT;
si v;
void ins(int t, int s) {
  sit l = v.insert({t, s}).first;
  st.upd(t, (++l)->at(0), s);
}
void rem(int t) {
  sit p = v.lower_bound({t, -MV}), n = p;
  assert(p->at(0)==t);
  n = v.erase(n), p = n;
  if(p == v.begin()) st.upd(t, n->at(0), 0);
  else st.upd(t, n->at(0), (--p)->at(1));
}
int qry(int l, int r, ll& q) {
  if(q <= 0) return printf("%d\n", p[l]);
  l = v.lower_bound({l, -MV})->at(0);
  if(l >= r) return printf("-1\n"), 0;
  ld x = st.qry(l, r, q);
  if(equ(x, -1)) printf("-1\n");
  else printf("%.15f\n", x);
  return 0;
}
void solve() {
  v.insert({P, -1});
  ll t;
  for(int i = 0;i < Q;i++) {
    int * c = q[i];
    if(c[0] == 1) ins(c[1], c[2]);
    if(c[0] == 2) rem(c[1]);
    if(c[0] == 3) qry(c[1], c[2], t = tl(c[3]));
  }
}
int main() {
  scanf("%d", &Q);
  P = 0;
  for(int i = 0;i < Q;i++) {
    scanf("%d", q[i]);
    if(q[i][0] == 1) scanf("%d%d", q[i]+1, q[i]+2), p[P++] = q[i][1];
    if(q[i][0] == 2) scanf("%d", q[i]+1);
    if(q[i][0] == 3) scanf("%d%d%d", q[i]+1, q[i]+2, q[i]+3), p[P++] = q[i][1], p[P++] = q[i][2];
  }
  cmpr();
  st.init(P);
  solve();

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long INT;
#define INF 0x3f3f3f3f3f3f3f3f

int xju[200005];
map<int,int> liss;
int dy[200005];
int lscnt=0;

typedef struct n0de{
	n0de *l,*r;
	INT wc;
	INT mn,fi;
	n0de(){
		l=r=0;
		mn=fi=0;
		wc=INF;
	}
}*node;

inline node newnode(){
	return new n0de();
}

inline void change(node now,int nl,int nr,int l,int r,INT x){
	if(!now->l){
		now->l=newnode();
	}
	if(!now->r){
		now->r=newnode();
	}
	if(now->wc!=INF){
		int m=(nl+nr)>>1;
		now->l->fi=now->wc*(dy[m+1]-dy[nl]);
		now->l->mn=(now->l->fi>=0?0:now->l->fi);
		now->l->wc=now->wc;
		now->r->fi=now->wc*(dy[nr+1]-dy[m+1]);
		now->r->mn=(now->l->fi>=0?0:now->r->fi);
		now->r->wc=now->wc;
		now->wc=INF;
	}
	if(nl>=l&&nr<=r){
		now->wc=x;
		now->fi=now->wc*(dy[nr+1]-dy[nl]);
		now->mn=(now->fi>=0?0:now->fi);
		return;
	}
	if(nr<l||nl>r){
		return;
	}
	int m=(nl+nr)>>1;
	change(now->l,nl,m,l,r,x);
	change(now->r,m+1,nr,l,r,x);
	now->fi=now->l->fi+now->r->fi;
	now->mn=min(now->l->mn,now->l->fi+now->r->mn);
}

inline pair<INT,INT> chmin(node now,int nl,int nr,int l,int r){
	if(l>r){
		return make_pair(0,0);
	}
	if(!now->l){
		now->l=newnode();
	}
	if(!now->r){
		now->r=newnode();
	}
	if(now->wc!=INF){
		int m=(nl+nr)>>1;
		now->l->fi=now->wc*(dy[m+1]-dy[nl]);
		now->l->mn=(now->l->fi>=0?0:now->l->fi);
		now->l->wc=now->wc;
		now->r->fi=now->wc*(dy[nr+1]-dy[m+1]);
		now->r->mn=(now->l->fi>=0?0:now->r->fi);
		now->r->wc=now->wc;
		now->wc=INF;
	}
	if(nl>=l&&nr<=r){
		return make_pair(now->mn,now->fi);
	}
	if(nr<l||nl>r){
		return make_pair(0,0);
	}
	int m=(nl+nr)>>1;
	pair<INT,INT> x=chmin(now->l,nl,m,l,r);
	pair<INT,INT> y=chmin(now->r,m+1,nr,l,r);
	return make_pair(min(x.first,x.second+y.first),x.second+y.second);
}

node root;

inline pair<INT,INT> Chmin(int l,int r){
	if(l>r){
		return make_pair(0,0);
	}
	int L=liss[l];
	map<int,int>::iterator rr=liss.upper_bound(r);
	rr--;
	int R=rr->second,rrr=rr->first;
	pair<INT,INT> x=chmin(root,0,lscnt-1,L,R-1);
	pair<INT,INT> y=chmin(root,0,lscnt-1,R,R);
	return make_pair(min(x.first,x.second+y.first/xju[R]*(r-rrr)),x.second+y.second/xju[R]*(r-rrr));
}

int q;
set<pair<int,INT> > evs;
#define spit set<pair<int,INT> >::iterator
int mmm[100005],lll[100005],rrr[100005],sss[100005];

int main(){
	root=newnode();
	evs.insert(make_pair(1000000000,0));
	evs.insert(make_pair(0,0));
	scanf("%d",&q);
	liss[0];
	liss[1000000000];
	for(int i=0;i<q;i++){
		scanf("%d",&mmm[i]);
		if(mmm[i]==1){
			scanf("%d%d",&lll[i],&sss[i]);
			liss[lll[i]];
		}else if(mmm[i]==2){
			scanf("%d",&lll[i]);
		}else{
			scanf("%d%d%d",&lll[i],&rrr[i],&sss[i]);
		}
	}
	for(map<int,int>::iterator it=liss.begin();it!=liss.end();it++){
		it->second=lscnt;
		dy[lscnt]=it->first;
		if(lscnt){
			xju[lscnt-1]=dy[lscnt]-dy[lscnt-1];
		}
		lscnt++;
	}
	xju[lscnt-1]=1;
	for(int I=0;I<q;I++){
		int mode=mmm[I];
		if(mode==1){
			int t=lll[I],s=sss[I];
			spit xx=evs.upper_bound(make_pair(t,s));
			pair<INT,INT> x=*xx;
			change(root,0,lscnt-1,liss[t],liss[x.first]-1,s);
			evs.insert(make_pair(t,s));
		}else if(mode==2){
			int t=lll[I];
			spit xx=evs.upper_bound(make_pair(t,INF));
			spit yy=xx;yy--;
			spit zz=yy;zz--;
			pair<INT,INT> x=*xx,z=*zz;
			change(root,0,lscnt-1,liss[t],liss[x.first]-1,z.second);
			evs.erase(yy);
		}else{
			int l=lll[I],r=rrr[I],v=sss[I];
			if(v==0){
				printf("%d\n",l);
				continue;
			}
			spit xxx=evs.lower_bound(make_pair(l,-INF));
			int frm=(*xxx).first;
			pair<INT,INT> fff;
			fff=Chmin(frm,r);
			INT rval=fff.first;
			if(rval+v>0){
				puts("-1");
				continue;
			}
			int L=frm,R=r;
			INT lval=0;
			while(R-L>1){
				INT m=(L+R)>>1;
				pair<INT,INT> fff=Chmin(frm,m);
				INT mnx=fff.first;
				if(mnx+v>0){
					L=m;
					lval=fff.second;
				}else{
					R=m;
					rval=fff.second;
				}
			}
			double vv;
			if(rval-lval==0){
				vv=L;
			}else{
				vv=1.00*(-v-lval)/(rval-lval)+L;
			}
			printf("%.10lf\n",vv);
		}
	}
	return 0;
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y0998244353
#define y1 y1998244353
#define die(cond) if (cond) for (;;) {}
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acosl(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct vertex {
	ll time, speed;
	ll tl, tr, speedR;
	ll res = 0, minn = 0;
	ll l = -1, r = -1;
	ll par = -1;
};
struct treap {
	vector<vertex> t;
	treap() {}
	ll newv(ll t_, ll s_) {
		vertex v;
		v.time = t_, v.speed = s_;
		t.pb(v);
		upd(sz(t) - 1);
		return sz(t) - 1;
	}
	void setpar(ll v, ll p) {
		if (v == -1) {
			return;
		}
		t[v].par = p;
	}
	void $upd(ll v) {
		if (v == -1) {
			return;
		}
		ll& time = t[v].time;
		ll& speed = t[v].speed;
		ll& res = t[v].res;
		ll& minn = t[v].minn;
		ll l = t[v].l, r = t[v].r;
		res = 0, minn = 0;
		if (l != -1) {
			mineq(minn, t[l].minn);
			res += t[l].res;
			res += t[l].speedR * (time - t[l].tr);
			mineq(minn, res);
			t[v].tl = t[l].tl;
		} else {
			t[v].tl = time;
		}
		if (r != -1) {
			res += speed * (t[r].tl - time);
			mineq(minn, res + t[r].minn);
			res += t[r].res;
			mineq(minn, res);
			t[v].tr = t[r].tr;
			t[v].speedR = t[r].speedR;
		} else {
			t[v].tr = time;
			t[v].speedR = speed;
		}
	}
	void upd(ll v) {
		if (v == -1) {
			return;
		}
		$upd(v);
		setpar(t[v].l, v);
		setpar(t[v].r, v);
	}
	ll rotate(ll v) {
		ll p = t[v].par;
		ll gp = t[p].par;
		if (gp != -1) {
			if (t[gp].l == p) {
				t[gp].l = v;
			} else {
				t[gp].r = v;
			}
		}
		if (t[p].l == v) {
			t[p].l = t[v].r;
			t[v].r = p;
		} else {
			t[p].r = t[v].l;
			t[v].l = p;
		}
		upd(v), upd(p);
		setpar(v, gp);
		return v;
	}
	ll splay(ll v) {
		if (v == -1) {
			return -1;
		}
		if (t[v].par == -1) {
			return v;
		}
		ll p = t[v].par;
		ll gp = t[p].par;
		if (gp == -1) {
			return rotate(v);
		}
		if (t[gp].l == p && t[p].l == v || t[gp].r == t[p].r == v) {
			rotate(v);
			rotate(v);
		} else {
			rotate(p);
			rotate(v);
		}
		return splay(v);
	}
	ll find(ll v, ll k) {
		if (v == -1) {
			return -1;
		}
		if (t[v].time == k) {
			return splay(v);
		}
		if (t[v].time > k && t[v].l != -1) {
			return find(t[v].l, k);
		}
		if (t[v].time < k && t[v].r != -1) {
			return find(t[v].r, k);
		}
		return splay(v);
	}
	pll split(ll v, ll k) {
		if (v == -1) {
			return { -1, -1 };
		}
		v = find(v, k);
		if (t[v].time < k) {
			ll r = t[v].r;
			setpar(r, -1), t[v].r = -1;
			upd(v);
			return { v, r };
		} else {
			ll l = t[v].l;
			setpar(l, -1), t[v].l = -1;
			upd(v);
			return { l, v };
		}
	}
	ll merge(ll f, ll s) {
		if (f == -1) {
			return s;
		}
		if (s == -1) {
			return f;
		}
		s = find(s, t[f].time);
		t[s].l = f;
		upd(s);
		return s;
	}
	void add(ll& root, ll t_, ll s_) {
		ll a, b;
		tie(a, b) = split(root, t_);
		ll v = newv(t_, s_);
		t[v].l = a, t[v].r = b;
		upd(v);
		root = v;
	}
	void del(ll& root, ll t_) {
		ll v = find(root, t_);
		setpar(t[v].l, -1);
		setpar(t[v].r, -1);
		root = merge(t[v].l, t[v].r);
	}
	ld down(ll v, ll V, ll R) {
		if (v == -1) {
			return -1;
		}
		ll lres = 0;
		if (t[v].l != -1) {
			ll minn = t[t[v].l].minn;
			lres += t[t[v].l].res + t[t[v].l].speedR * (t[v].time - t[t[v].l].tr);
			mineq(minn, lres);
			if (V + minn <= 0) {
				return down(t[v].l, V, t[v].time);
			}
		}
		V += lres;
		ll tr = R;
		if (t[v].r != -1) {
			tr = t[t[v].r].tl;
		}
		if (V + t[v].speed * (tr - t[v].time) <= 0) {
			ld ans = t[v].time - ld(V) / ld(t[v].speed);
			return ans;
		}
		if (t[v].r != -1) {
			V += t[v].speed * (t[t[v].r].tl - t[v].time);
			return down(t[v].r, V, R);
		}
		return -1;
	}
	ld getans(ll& root, ll l, ll r, ll v) {
		if (v == 0) {
			return l;
		}
		ll a, b, c;
		tie(a, b) = split(root, l);
		tie(b, c) = split(b, r + 1);
		ld ans = down(b, v, r);
		root = merge(merge(a, b), c);
		return ans;
	}
};

ll q;
treap tr;

inline void solve() {
	cout << setprecision(7) << fixed;
	ll root = -1;
	for (ll i = 0; i < q; i++) {
		ll t;
		cin >> t;
		if (t == 1) {
			ll time, s;
			cin >> time >> s;
			tr.add(root, time, s);
		} else if (t == 2) {
			ll time;
			cin >> time;
			tr.del(root, time);
		} else if (t == 3) {
			ll l, r, v;
			cin >> l >> r >> v;
			ld ans = tr.getans(root, l, r, v);
			cout << ans << endl;
		}
	}
}

inline void read() {
	cin >> q;
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long

const int mxQ=1e5;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int q;

template<size_t S>
struct treap {
	int rt, lc[S+1], rc[S+1], k[S+1], s[S+1], lk[S+1], rk[S+1], rs[S+1];
	ll pr[S+1], ts[S+1], ms[S+1];
	int cmb(int u) {
		lk[u]=lc[u]?lk[lc[u]]:k[u];
		rk[u]=rc[u]?rk[rc[u]]:k[u];
		rs[u]=rc[u]?rs[rc[u]]:s[u];
		ts[u]=ms[u]=0;
		if(lc[u]) {
			ts[u]=ts[lc[u]]+(ll)(k[u]-rk[lc[u]])*rs[lc[u]];
			ms[u]=min({ms[lc[u]], ts[u], 0ll});
		}
		if(rc[u]) {
			ts[u]+=(ll)(lk[rc[u]]-k[u])*s[u];
			ms[u]=min(ts[u]+ms[rc[u]], ms[u]);
			ts[u]+=ts[rc[u]];
		}
		return u;
	}
	int mrg(int u, int v) {
		if(!u||!v)
			return u^v;
		if(pr[u]>pr[v]) {
			rc[u]=mrg(rc[u], v);
			return cmb(u);
		} else {
			lc[v]=mrg(u, lc[v]);
			return cmb(v);
		}
	}
	array<int, 2> spl(int u, int x) {
		if(!u)
			return {0, 0};
		if(k[u]<x) {
			array<int, 2> a=spl(rc[u], x);
			rc[u]=a[0];
			return {cmb(u), a[1]};
		} else {
			array<int, 2> a=spl(lc[u], x);
			lc[u]=a[1];
			return {a[0], cmb(u)};
		}
	}
	int ins(int u, int v, int ki, int si) {
		k[v]=ki;
		s[v]=si;
		pr[v]=rng();
		array<int, 2> a=spl(u, ki), b=spl(a[1], ki+1);
		return mrg(a[0], mrg(cmb(v), b[1]));
	}
	int del(int u, int ki) {
		array<int, 2> a=spl(u, ki), b=spl(a[1], ki+1);
		return mrg(a[0], b[1]);
	}
	void qry(int l, int r, ll d, int v) {
		if(!d) {
			cout << l << "\n";
			return;
		}
		array<int, 2> a=spl(rt, l), b=spl(a[1], r);
		v=b[0]=ins(b[0], v, r, 0);
		if(d+ms[v]<=0) {
			while(1) {
				if(lc[v]) {
					if(d+ms[lc[v]]<=0) {
						v=lc[v];
						continue;
					}
					d+=ts[lc[v]];
					if(d+(ll)(k[v]-rk[lc[v]])*rs[lc[v]]<=0) {
						cout << rk[lc[v]]+(long double)-d/rs[lc[v]] << "\n";
						break;
					}
					d+=(ll)(k[v]-rk[lc[v]])*rs[lc[v]];
				}
				if(d+(ll)(lk[rc[v]]-k[v])*s[v]<=0) {
					cout << k[v]+(long double)-d/s[v] << "\n";
					break;
				}
				d+=(ll)(lk[rc[v]]-k[v])*s[v];
				v=rc[v];
			}
		} else
			cout << "-1\n";
		b[0]=del(b[0], r);
		rt=mrg(a[0], mrg(b[0], b[1]));
	}
};
treap<mxQ> tr;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> q;
	cout << setprecision(9);
	for(int a, b, c, d; q--; ) {
		cin >> a >> b;
		if(a==1) {
			cin >> c;
			tr.rt=tr.ins(tr.rt, q+1, b, c);
		} else if(a==3) {
			cin >> c >> d;
			tr.qry(b, c, d, q+1);
		} else
			tr.rt=tr.del(tr.rt, b);
	}
}

#include<bits/stdc++.h>

using namespace std;

//const int NMAX = 100;
const int NMAX = 350009;

long long Q, N, currentS[NMAX], s[NMAX], t[NMAX], l[NMAX], r[NMAX], v[NMAX], type[NMAX];
vector < long long > ts;
map < long long, long long > inverseT;

void read ()
{
    scanf ("%I64d", &Q);
    for (int i=1; i<=Q; i++)
    {
        scanf ("%I64d", &type[i]);
        if (type[i] == 1) scanf ("%I64d %I64d", &t[i], &s[i]), ts.push_back (t[i]);
        else
        if (type[i] == 2) scanf ("%I64d", &t[i]);
        else
        {
            scanf ("%I64d %I64d %I64d", &l[i], &r[i], &v[i]);
            ts.push_back (l[i]), ts.push_back (r[i]);
        }
    }
    sort (ts.begin (), ts.end ());
    ts.erase (unique (ts.begin (), ts.end ()), ts.end ()), N = ts.size ();
/*    for (auto it : ts)
        printf ("%I64d\n", it);*/
    for (long long i=0; i<N; i++)
        inverseT[ts[i]] = i + 1;
    long long lastVal = ts[N - 1];
    ts.push_back (lastVal);
    for (int i=1; i<=Q; i++)
        if (type[i] <= 2) t[i] = inverseT[t[i]];
        else l[i] = inverseT[l[i]], r[i] = inverseT[r[i]];
}

set < long long > currTimes;
long long sum[4 * NMAX], mi[4 * NMAX];
long long vl[4 * NMAX];
bool lzy[4 * NMAX];

long long getLength (long long x, long long y) {return ts[y] - ts[x - 1];}

void split (long long nod, long long st, long long mij, long long dr, long long f1, long long f2)
{
    if (lzy[nod] == 0) return ;
    lzy[f1] = lzy[f2] = 1;
    vl[f1] = vl[f2] = vl[nod];
    sum[f1] = 1LL * vl[nod] * getLength (st, mij);
    mi[f1] = min (0LL, sum[f1]);
    sum[f2] = 1LL * vl[nod] * getLength (mij + 1, dr);
    mi[f2] = min (0LL, sum[f2]);
    lzy[nod] = 0;
}

void setValue (long long nod, long long st, long long dr, long long x, long long y, long long s)
{
/*    if (nod == 1)
        printf ("set %I64d [%I64d, %I64d]\n", s, x, y);*/
    if (x <= st && dr <= y)
    {
        vl[nod] = s, lzy[nod] = 1;
        sum[nod] = 1LL * s * getLength (st, dr);
        mi[nod] = min (0LL, sum[nod]);
        return ;
    }
    long long mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    split (nod, st, mij, dr, f1, f2);
    if (x <= mij) setValue (f1, st, mij, x, y, s);
    if (mij < y) setValue (f2, mij + 1, dr, x, y, s);
    sum[nod] = sum[f1] + sum[f2];
    mi[nod] = min (mi[f1], sum[f1] + mi[f2]);
}

long double ansQ = -1.0;
const long double eps = 1e-9;
long long curr;
void query (long long nod, long long st, long long dr, long long x, long long y)
{
    if (ansQ > -0.5)
        return ;
    if (x <= st && dr <= y)
    {
        long long mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
        if (st == dr)
        {
            if (mi[nod] + curr > 0)
            {
                curr += sum[nod];
                return ;
            }
            long long t1 = ts[st - 1], t2 = ts[st];
            assert (vl[nod] < 0);
            ansQ = t1 + 1.0 * curr / (-vl[nod]);
            assert (ansQ > -0.5);
            return ;
        }
        split (nod, st, mij, dr, f1, f2);
        if (curr + mi[f1] <= 0)
        {
            query (f1, st, mij, x, y);
            assert (ansQ > -0.5);
        }
        else
        if (curr + sum[f1] + mi[f2] <= 0)
        {
            curr += sum[f1], query (f2, mij + 1, dr, x, y);
            assert (ansQ > -0.5);
        }
        else curr += sum[nod];
        return ;
    }
    long long mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    split (nod, st, mij, dr, f1, f2);
    if (x <= mij) query (f1, st, mij, x, y);
    if (mij < y) query (f2, mij + 1, dr, x, y);
}

int main ()
{
//freopen ("input", "r", stdin);
//freopen ("output", "w", stdout);

read ();
for (long long i=1; i<=Q; i++)
{
    if (type[i] == 1)
    {
        currTimes.insert (t[i]);
        auto it = currTimes.find (t[i]); it ++;
        long long rgt = N;
        if (it != currTimes.end ()) rgt = (*it) - 1;
        setValue (1, 1, N, t[i], rgt, s[i]);
        currentS[t[i]] = s[i];
        continue;
    }
    if (type[i] == 2)
    {
        auto it = currTimes.find (t[i]);
        long long s = 0;
        if (it != currTimes.begin ())
        {
            auto it2 = it;
            it2 --; s = currentS[*it2];
        }
        it ++;
        long long rgt = N;
        if (it != currTimes.end ()) rgt = (*it) - 1;
        setValue (1, 1, N, t[i], rgt, s);
        currTimes.erase (t[i]), currentS[t[i]] = 0;
        continue;
    }
    ansQ = -1.0;
    if (v[i] == 0)
    {
        printf ("%I64d\n", ts[l[i] - 1]);
        continue;
    }
    if (l[i] != r[i])
    {
/*        printf ("l[i]=%d\ntimes: ", l[i]);
        for (auto it : currTimes)
            printf ("%d ", it);
        printf ("\n");*/
        auto it = currTimes.lower_bound (l[i]);
        if (it != currTimes.end () && (*it) < r[i])
            curr = v[i], query (1, 1, N, *it, r[i] - 1);
    }
    assert (ansQ <= ts[r[i] - 1] + eps);
    cout << setprecision (15) << ansQ << '\n';
}
return 0;
}

#ifdef _LOCAL
//#include "debug.h"
#else
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("-O3")
//#pragma GCC optimize("Ofast")
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
#define sz(x) int(x.size())
#define all(x) x.begin(),x.end()
#define pii pair<int,int>
#define PB push_back
#define MP make_pair
#define pll pair<ll,ll>
#define pii pair<int,int>
#define pi3 pair<int,pll>
#define pl3 pair<ll,pll>
#define MP3(a,b,c) MP(a,MP(b,c))
#define F first
#define S second
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
template<class T>
using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
const int PW = 18;
const int N = 200100;
const int K = 10100;
const int oo = 2e9;
const ll OO = 1e18;
const int md = 998244353;
vector<int> vc;
vector<ll> vec;
map<int,int> mem;
int q,tp[N],t[N],l[N],r[N],vl[N],m,pr;
ld ans;
ll cur;
struct seg_tree{
    int l,r;
    ll mn,res;
};
seg_tree st[4*N];

inline seg_tree combine(seg_tree l,seg_tree r){
    seg_tree res;
    if (l.l==oo) return r;
    if (r.l==oo) return l;
    res.l=l.l; res.r=r.r;
    res.mn=l.mn;
    ll lbd=vc[l.r],rbd=vc[r.l],val=vec[l.r];
    res.mn=min(res.mn,l.res+(rbd-lbd)*val+r.mn);
    res.res=l.res+(rbd-lbd)*val+r.res;
    return res;
}

void build(int v,int l,int r){
    if (l==r) {
        st[v].l=st[v].r=st[v].mn=st[v].res=oo;
        return;
    }
    int md=(l+r)>>1;
    build(v+v,l,md);
    build(v+v+1,md+1,r);
    st[v]=combine(st[v+v],st[v+v+1]);
}

void update(int v,int l,int r,int ps,int val){
    if (l==r){
        if (val<oo){
            st[v].l=st[v].r=l;
            st[v].res=st[v].mn=0ll;
            vec[l]=val;
        } else {
            st[v].l=st[v].r=st[v].mn=st[v].res=oo;
        }
        return;
    }
    int md=(l+r)>>1;
    if (ps<=md)
        update(v+v,l,md,ps,val);
    else update(v+v+1,md+1,r,ps,val);
    st[v]=combine(st[v+v],st[v+v+1]);
}

void Real_Search(int v,int l,int r){
    if (l==r){
        ans=min(ans,ld(vc[l])+ld(cur)/ld(-vec[l])); cur=OO;
        return;
    }
    int md=(l+r)>>1;
    if (st[v+v].l==oo) {
        Real_Search(v+v+1,md+1,r); return;
    }
    if (st[v+v+1].l==oo){
        Real_Search(v+v,l,md); return;
    }
    if (cur+st[v+v].mn<=0){
        Real_Search(v+v,l,md); return;
    }
    ll lbd=vc[st[v+v].r],rbd=vc[st[v+v+1].l],val=vec[st[v+v].r];
    if (cur+st[v+v].res+(rbd-lbd)*val<=0){
        Real_Search(v+v,l,md); return;
    }
    cur+=st[v+v].res+(rbd-lbd)*val;
    Real_Search(v+v+1,md+1,r);
}

void Search(int v,int tl,int tr,int l,int r){
    if (ans<ld(OO)) return;
    if (l>r) return;
    if (tl==l && tr==r){
        if (st[v].l==oo) return;
        if (pr<oo){
            ll lbd=vc[pr],rbd=vc[st[v].l],val=vec[pr];
            if (cur+(rbd-lbd)*val<=0){
                ans=min(ans,ld(lbd)+ld(cur)/ld(-val));  cur=OO; return;
            }
            cur+=(rbd-lbd)*val;
        }
        pr=st[v].r;
        if (cur+st[v].mn<=0)
            Real_Search(v,l,r);
        else cur+=st[v].res;
        return;
    }
    int md=(tl+tr)>>1;
    Search(v+v,tl,md,l,min(r,md));
    Search(v+v+1,md+1,tr,max(md+1,l),r);
}

int main() {
#ifndef _LOCAL
//    freopen("fencing.in","r",stdin); freopen("fencing.out","w",stdout);
	ios_base::sync_with_stdio(0); cin.tie(0);
#else
	freopen("input.txt","r",stdin);
#endif
    cin>>q; vc.clear(); mem.clear();
    for (int i=0;i<q;i++){
        cin>>tp[i];
        if (tp[i]==1){
            cin>>t[i]>>vl[i]; vc.PB(t[i]);
        } else if (tp[i]==3){
            cin>>l[i]>>r[i]>>vl[i];
            vc.PB(l[i]); vc.PB(r[i]);
        } else {
            cin>>t[i]; vc.PB(t[i]);
        }
    }
    sort(all(vc));
    vc.resize(unique(all(vc))-vc.begin());
    vec.resize(sz(vc));
    m=sz(vc);
    for (int i=0;i<m;i++) mem[vc[i]]=i;
    build(1,0,m-1);
    for (int i=0;i<q;i++)
        if (tp[i]==1)
            update(1,0,m-1,mem[t[i]],vl[i]);
        else if (tp[i]==2)
            update(1,0,m-1,mem[t[i]],oo);
        else {
            ans=ld(OO); cur=vl[i]; pr=oo;
            if (vl[i]<=0) ans=l[i];
            int lft=lower_bound(all(vc),l[i])-vc.begin();
            int rgt=lower_bound(all(vc),r[i])-vc.begin();
            Search(1,0,m-1,lft,rgt);
            if (pr<oo && vec[pr]<0)
                ans=min(ans,ld(vc[pr])+ld(cur)/ld(-vec[pr]));
            if (ans<=r[i])
                cout<<fixed<<setprecision(6)<<ans<<'\n';
            else cout<<"-1\n";
        }
    return 0;
}

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod7=1000000007LL;
inline ll getint() {
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add(ll _x, ll _y, ll _mod=mod7) {
  _x+=_y;
  return _x>=_mod ? _x-_mod : _x;
}
inline ll sub(ll _x, ll _y, ll _mod=mod7) {
  _x-=_y;
  return _x<0 ? _x+_mod : _x;
}
inline ll mul(ll _x, ll _y ,ll _mod=mod7) {
  _x*=_y;
  return _x>=_mod ? _x%_mod : _x;
}
ll mypow(ll _a, ll _x, ll _mod) {
  if(_x == 0) return 1ll;
  ll _ret = mypow(mul(_a, _a, _mod), _x>>1, _mod);
  if(_x & 1) _ret=mul(_ret, _a, _mod);
  return _ret;
}
ll mymul(ll _a, ll _x, ll _mod) {
  if(_x == 0) return 0ll;
  ll _ret = mymul(add(_a, _a, _mod), _x>>1, _mod);
  if(_x & 1) _ret=add(_ret, _a, _mod);
  return _ret;
}
void sleep(double sec = 1021) {
	clock_t s = clock();
	while(clock() - s < CLOCKS_PER_SEC * sec);
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/

const int mxN=1e5+5, bs=200, bc=(mxN-1)/bs+1;
int nq, n;
array<int, 4> q[mxN];
vector<int> v;
ll s[mxN], ms[bc], ts[bc], lz2[bc];
bool lz1[bc];

void pb(int i) {
	if(lz1[i]) {
		for(int l=i*bs; l<min(n-1, (i+1)*bs); ++l)
			s[l]=lz2[i];
		lz1[i]=0;
	}
}
void ub(int i) {
	ts[i]=ms[i]=0;
	for(int l=i*bs; l<min(n-1, (i+1)*bs); ++l) {
		ts[i]+=s[l]*(v[l+1]-v[l]);
		ms[i]=min(ts[i], ms[i]);
	}
}

//[l, r]
void upd(int l, int r, ll x) {
	//cout << "upd " << l << " " << r << " " << x << endl;
	int bi=l/bs;
	pb(bi);
	for(; l<(bi+1)*bs&&l<=r; ++l)
		s[l]=x;
	//cout << s[3] << " " << s[4] << endl;
	ub(bi++);
	if(l>r)
		return;
	for(; l+bs<=r; l+=bs, ++bi) {
		lz1[bi]=1;
		lz2[bi]=x;
		ts[bi]=(v[l+bs]-v[l])*x;
		if(x>0)
			ms[bi]=0;
		else
			ms[bi]=ts[bi];
	}
	pb(bi);
	for(; l<=r; ++l) {
		s[l]=x;
	}
	ub(bi);
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);

	v.push_back(0);
	v.push_back(1e9+1);
	cin >> nq;
	for(int i=0; i<nq; ++i) {
		cin >> q[i][0] >> q[i][1];
		if(q[i][0]!=2)
			cin >> q[i][2];
		if(q[i][0]==3)
			cin >> q[i][3];
		if(q[i][0]==1)
			v.push_back(q[i][1]);
	}
	sort(v.begin(), v.end());
	v.resize(unique(v.begin(), v.end())-v.begin());
	n=v.size();
	for(int i=0; i<nq; ++i) {
		if(q[i][0]!=3)
			q[i][1]=lower_bound(v.begin(), v.end(), q[i][1])-v.begin();
		//if(q[i][0]==3)
			//q[i][2]=lower_bound(v.begin(), v.end(), q[i][2])-v.begin()-1;
	}
	cout << fixed << setprecision(9);
	//cout << n << endl;
	map<int, int> m{{0, 0}, {n-1, 0}};
	for(int qi=0; qi<nq; ++qi) {
		if(q[qi][0]==1) {
			auto it=m.lower_bound(q[qi][1]);
			upd(q[qi][1], it->first-1, q[qi][2]);
			m[q[qi][1]]=q[qi][2];
		} else if(q[qi][0]==2) {
			m.erase(q[qi][1]);
			auto it1=m.lower_bound(q[qi][1]), it2=it1--;
			upd(it1->first, it2->first-1, it1->second);
		} else {
			int li=lower_bound(v.begin(), v.end(), q[qi][1])-v.begin(), ri=lower_bound(v.begin(), v.end(), q[qi][2])-v.begin()-1;
			li=m.lower_bound(li)->first;
			int bi=li/bs;
			ll c=q[qi][3];
			//if(n>1e3)
				//cout << li << " " << ri << " ";
				//cout << q[qi][2] << " ";
			if(c<=0) {
				cout << q[qi][1] << "\n";
				continue;
			}
			if(li>ri) {
				cout << "-1\n";
				continue;
			}
			bool sc=0;
			pb(bi);
			for(; li<(bi+1)*bs&&li<=ri&&!sc; ++li) {
				//cout << li << " " << s[li] << " " << endl;
				int df=min(q[qi][2], v[li+1])-v[li];
				if(c+df*s[li]<=0) {
					cout << (long double)-c/s[li]+v[li] << "\n";
					sc=1;
				}
				c+=df*s[li];
			}
			if(sc)
				continue;
			++bi;
			for(; li+bs<=ri; li+=bs, ++bi) {
				//cout << li << " " << ts[bi] << " " << ms[bi] << endl;
				if(c+ms[bi]<=0)
					break;
				c+=ts[bi];
			}
			pb(bi);
			for(; li<=ri&&!sc; ++li) {
				int df=min(q[qi][2], v[li+1])-v[li];
				if(c+df*s[li]<=0) {
					cout << (long double)-c/s[li]+v[li] << "\n";
					sc=1;
				}
				c+=df*s[li];
			}
			if(sc)
				continue;
			cout << "-1\n";
		}
	}
}

#include<bits/stdc++.h>
#define maxn 100005
#define x first
#define y second
#define LL long long
using namespace std;struct node{int ch[2],v;bool cov;LL sum,lsum;}t[maxn*40];
#define lc t[i].ch[0]
#define rc t[i].ch[1]
int Q,root,sz;void upd(int i){if(!lc)lc=++sz;if(!rc)rc=++sz;t[i].sum=t[lc].sum+t[rc].sum;t[i].lsum=min(t[lc].lsum,t[lc].sum+t[rc].lsum);}void cover(int&i,int l,int r,int v){if(!i)i=++sz;t[i].cov=1,t[i].v=v;t[i].sum=1ll*(r-l+1)*v;t[i].lsum=(v>=0?0:t[i].sum);}void pushdown(int i,int l,int mid,int r){if(t[i].cov){cover(lc,l,mid,t[i].v);cover(rc,mid+1,r,t[i].v);t[i].cov=0;}}void insert(int&i,int l,int r,int x,int y,int v){if(!i)i=++sz;if(x<=l&&r<=y){cover(i,l,r,v);return;}int mid=(l+r)>>1;pushdown(i,l,mid,r);if(x<=mid)insert(lc,l,mid,x,y,v);if(y>mid)insert(rc,mid+1,r,x,y,v);upd(i);}typedef pair<double,LL>pdl;pdl query(int&i,int l,int r,int x,int y,LL s){if(!i)i=++sz;if(x<=l&&r<=y){if(s+t[i].lsum>0)return make_pair(-1,t[i].sum);if(l==r||t[i].cov)return make_pair(l-1.0*s/t[i].v,t[i].sum);}int mid=(l+r)>>1;pushdown(i,l,mid,r);if(y<=mid)return query(lc,l,mid,x,y,s);if(x>mid)return query(rc,mid+1,r,x,y,s);pdl lret=query(lc,l,mid,x,y,s);if(lret.x>0)return lret;pdl rret=query(rc,mid+1,r,x,y,s+lret.y);return make_pair(rret.x,lret.y+rret.y);}const int N=1e9;map<int,int>T;int main(){scanf("%d",&Q);T[0]=T[N+1]=0;int op,l,r,v;while(Q--){scanf("%d%d",&op,&l);if(op==1){scanf("%d",&v);T[l]=v;auto it=T.find(l);it++;insert(root,1,N,l,it->x-1,v);}else if(op==2){auto it=T.find(l),pre=it,nxt=it;pre--,nxt++;T.erase(it);insert(root,1,N,l,nxt->x-1,pre->y);}else{scanf("%d%d",&r,&v);if(!v)printf("%d\n",l);else if((l=T.lower_bound(l)->x)>=r)puts("-1");else{auto ans=query(root,1,N,l,r-1,v);if(ans.x<0)puts("-1");else printf("%.10f\n",ans.x);}}}}

#pragma GCC optimize("Ofast")

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;

#define X first
#define Y second

//#include <boost/unordered_map.hpp>
//using namespace boost;

/*
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
rbtree T;
*/

namespace io{
    const int L = (1 << 20) + 1;

    char buf[L], *S , *T, c;

    char getchar() {
        if(__builtin_expect(S == T, 0)) {
            T = (S = buf) + fread(buf, 1, L, stdin);
            return (S == T ? EOF : *S++);
        }
        return *S++;
    }

    int inp() {
        int x = 0, f = 1; char ch;
        for(ch = getchar(); !isdigit(ch); ch = getchar())
            if(ch == '-') f = -1;
        for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
        return x * f;
    }

    unsigned inpu()
    {
        unsigned x = 0; char ch;
        for(ch = getchar(); !isdigit(ch); ch = getchar());
        for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
        return x;
    }

    ll inp_ll() {
        ll x = 0; int f = 1; char ch;
        for(ch = getchar(); !isdigit(ch); ch = getchar())
            if(ch == '-') f = -1;
        for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
        return x * f;
    }

    char B[25], *outs=B+20, *outr=B+20;
    template<class T>
    inline void print(register T a,register char x=0){
        if(x) *--outs = x, x = 0;

        if(!a)*--outs = '0';
        else
            while(a)
                *--outs = (a % 10) + 48, a /= 10;

        if(x)
            *--outs = x;

        fwrite(outs, outr - outs , 1, stdout);
        outs = outr;
    }
};

using io :: print;
using io :: inp;
using io :: inpu;
using io :: inp_ll;

using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;

ll power(ll a, ll b, ll p)
{
    if (!b) return 1;
    ll t = power(a, b/2, p);
    t = t*t%p;
    if (b&1) t = t*a%p;
    return t;
}

ll gcd(ll a, ll b)
{
    return b ? gcd(b, a%b) : a;
}

template<class T>
inline void freshmin(T &a, const T &b)
{
    if (a > b) a = b;
}

template<class T>
inline void freshmax(T &a, const T &b)
{
    if (a < b) a = b;
}

const int MAXN = 100010;
const int MOD = 1000000007;
const f80 MI = f80(1)/MOD;
const int INF = 1000000000;

struct node
{
    node *Lc, *Rc;
    int flag, set;
    ll sum, Lsum;
};

node *new_node()
{
    node *it = new node;
    it->Lc = it->Rc = 0;
    it->flag = it->set = it->sum = it->Lsum = 0;
    return it;
}

void clear(node *p, int L, int R)
{
    if (p->flag)
    {
        int m = (L+R)/2;
        p->flag = 0;
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        p->Lc->flag = p->Rc->flag = 1;
        p->Lc->set = p->Rc->set = p->set;
        p->Lc->sum = (ll)(m-L+1)*p->set;
        p->Lc->Lsum = p->set >= 0 ? 0 : p->Lc->sum;
        p->Rc->sum = (ll)(R-m)*p->set;
        p->Rc->Lsum = p->set >= 0 ? 0 : p->Rc->sum;
    }
}

void update(node *p)
{
    if (!p->Lc) p->Lc = new_node();
    if (!p->Rc) p->Rc = new_node();
    p->sum = p->Lc->sum+p->Rc->sum;
    p->Lsum = min(p->Lc->Lsum, p->Lc->sum+p->Rc->Lsum);
}

void modify(node *p, int L, int R, int x, int y, int v)
{
    if (L == x && R == y)
    {
        p->flag = 1;
        p->set = v;
        p->sum = (ll)(R-L+1)*v;
        p->Lsum = v >= 0 ? 0 : p->sum;
        return;
    }
    clear(p, L, R);
    int m = (L+R)/2;
    if (y <= m)
    {
        if (!p->Lc) p->Lc = new_node();
        modify(p->Lc, L, m, x, y, v);
    }
    else if (x > m)
    {
        if (!p->Rc) p->Rc = new_node();
        modify(p->Rc, m+1, R, x, y, v);
    }
    else
    {
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        modify(p->Lc, L, m, x, m, v);
        modify(p->Rc, m+1, R, m+1, y, v);
    }
    update(p);
}

pair<ld, ll> query(node *p, int L, int R, int x, int y, ll v)
{
    if (L == x && R == y)
    {
        if (p->Lsum+v > 0)
            return pair<ld, ll>(-1, p->sum);
        if (L == R)
            return pair<ld, ll>(L-(ld)v/p->sum, p->sum);
        if (p->flag)
            return pair<ld, ll>(L-(ld)v/(p->sum/(R-L+1)), p->sum);
        int m = (L+R)/2;
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        auto Lans = query(p->Lc, L, m, x, m, v);
        if (Lans.first > 0)
            return Lans;
        else
        {
            auto Rans = query(p->Rc, m+1, R, m+1, y, Lans.second+v);
            return pair<ld, ll>(Rans.first, Lans.second+Rans.second);
        }
    }
    clear(p, L, R);
    int m = (L+R)/2;
    if (y <= m)
    {
        if (!p->Lc) p->Lc = new_node();
        return query(p->Lc, L, m, x, y, v);
    }
    else if (x > m)
    {
        if (!p->Rc) p->Rc = new_node();
        return query(p->Rc, m+1, R, x, y, v);
    }
    else
    {
        if (!p->Lc) p->Lc = new_node();
        if (!p->Rc) p->Rc = new_node();
        auto Lans = query(p->Lc, L, m, x, m, v);
        if (Lans.first > 0)
            return Lans;
        else
        {
            auto Rans = query(p->Rc, m+1, R, m+1, y, Lans.second+v);
            return pair<ld, ll>(Rans.first, Lans.second+Rans.second);
        }
    }
}

int main()
{

    int q = inp();
    map<int, int> H;
    int L = 1, R = 1000000010;
    H[L-1] = H[R+1] = 0;
    node *root = new_node();
    while (q --)
    {
        int t = inp();
        if (t == 1)
        {
            int x = inp();
            int y = inp();
            H[x] = y;
            auto it = H.find(x);
            ++ it;
            modify(root, L, R-1, x, min(it->X, R)-1, y);
        }
        else if (t == 2)
        {
            int x = inp();
            auto it = H.find(x);
            auto ity = it;
            ++ ity;
            auto itx = it;
            -- itx;
            modify(root, L, R-1, x, min(ity->X, R)-1, itx->Y);
            H.erase(x);
        }
        else if (t == 3)
        {
            int x = inp();
            int y = inp();
            int v = inp();
            if (v == 0)
                printf("%d\n", x);
            else
            {
                auto it = H.lower_bound(x);
                x = it->X;
                if (x >= y)
                    puts("-1");
                else
                {
                    auto ans = query(root, L, R-1, x, y-1, v);
                    if (ans.first < 0)
                        puts("-1");
                    else
                       printf("%.8f\n", ans.first);
                }
            }
        }
    }

    return 0;
}

#include <stdio.h>
#include <map>

#define DEBUG 0
#define minn(a,b) (a<=b?a:b)
#define maxx(a,b) (a>=b?a:b)
const int INF=0x7fffffff;

#define SZ 6000005
int sfree=2;
int sa[SZ],sb[SZ];      // [a,b)
long long sadd[SZ];     // amount of flow added
long long smin[SZ];     // minimum reached, if starting at 0
int sprop[SZ];          // does nothing when it's equal to INF
int s1[SZ],s2[SZ];

void segprop(int s)
{
    if (sb[s]-sa[s]==1) return;
    if (sprop[s]==INF) return;
    if (s1[s]==0) {
        int mid=sa[s]+(sb[s]-sa[s])/2;
        sa[sfree]=sa[s];
        sb[sfree]=mid;
        sprop[sfree]=INF;
        s1[s]=sfree++;
        sa[sfree]=mid;
        sb[sfree]=sb[s];
        sprop[sfree]=INF;
        s2[s]=sfree++;
    }
    sadd[s1[s]]=sprop[s]*1LL*(sb[s1[s]]-sa[s1[s]]);
    smin[s1[s]]=minn(0,sadd[s1[s]]);
    sadd[s2[s]]=sprop[s]*1LL*(sb[s2[s]]-sa[s2[s]]);
    smin[s2[s]]=minn(0,sadd[s2[s]]);
    sprop[s1[s]]=sprop[s2[s]]=sprop[s];
    sprop[s]=INF;
}

void paint(int s,int a,int b,int v)
{
    segprop(s);
    //if (DEBUG) printf("paint seg [%d %d)\n",s->a,s->b);
    // paint [a,b) with v
    if (sb[s]<=a || b<=sa[s]) return;
    if (a<=sa[s] && sb[s]<=b) {
        //if (DEBUG) printf("paint seg [%d %d) with %d\n",s->a,s->b,v);
        sadd[s]=v*1LL*(sb[s]-sa[s]);        // stupid
        smin[s]=minn(0,sadd[s]);
        sprop[s]=v;
        return;
    }
    // do subranges
    paint(s1[s],a,b,v);
    paint(s2[s],a,b,v);
    sadd[s]=sadd[s1[s]]+sadd[s2[s]];
    long long t1=smin[s1[s]];               // stupid
    long long t2=sadd[s1[s]]+smin[s2[s]];   // stupid
    smin[s]=minn(t1,t2);
    sprop[s]=INF;
}

long long remain;
double ans;
// state = 0, continue reading ranges
// state = 1, done and found
// state = 2, nothing found (because doubles can't handle 10^9 + 10^-9)
int state;
void getans(int s,int a,int b)
{
    //if (DEBUG) printf("getans [%d %d)\n",s->a,s->b);
    segprop(s);
    if (sb[s]<=a || b<=sa[s]) return;
    if (a<=sa[s] && sb[s]<=b) {
        //if (DEBUG) printf("getans [%d %d) init %I64d\n",s->a,s->b,remain);
        //if (DEBUG) printf("node has %I64d %I64d %I64d\n",s->add,s->min,s->prop);
        if (remain+smin[s]<=0) {
            if (sb[s]-sa[s]==1) {
                //if (DEBUG) printf("done %d init %I64d\n",s->a,remain);
                ans=sa[s]-remain/1.0/sprop[s];
                state=1;
                remain=0;
            }
            else {
                getans(s1[s],a,b);
                if (!state) getans(s2[s],a,b);
            }
        }
        else {
            remain+=sadd[s];
        }
        return;
    }
    getans(s1[s],a,b);
    if (!state) getans(s2[s],a,b);
}

/*void printseg(seg *s)
{
    if (s==nullptr) return;
    if (s->a>20) return;
    segprop(s);
    printseg(s->s1);
    printseg(s->s2);
    printf("[%d %d) has %I64d %I64d %I64d\n",s->a,s->b,s->add,s->min,s->prop);
}*/

std::map<int,int> flow;
std::map<int,int>::iterator it;

int q;
int q1,q2,q3;

int main()
{
    #ifdef NOT_DMOJ
    freopen("data.txt","r",stdin);
    #endif // NOT_DMOJ
    sb[1]=0x7ffffffe;
    scanf("%d",&q);
    flow[0]=0;
    flow[0x7ffffffd]=0;
    while (q--) {
        scanf("%d",&q1);
        if (q1==1) {
            scanf("%d%d",&q1,&q2);
            it=flow.lower_bound(q1);
            if (DEBUG) printf("paint %d %d %d\n\n",q1,it->first,q2);
            paint(1,q1,it->first,q2);
            flow[q1]=q2;
        }
        else if (q1==2) {
            scanf("%d",&q1);
            flow.erase(q1);
            it=flow.lower_bound(q1);
            q2=it->first;
            --it;
            if (DEBUG) printf("paint %d %d %d\n\n",it->first,q2,it->second);
            paint(1,it->first,q2,it->second);
        }
        else {
            scanf("%d%d%d",&q1,&q2,&q3);
            if (q3==0) {
                // so very bad
                printf("%d\n",q1);
                continue;
            }
            // so very bad #2
            q1=flow.lower_bound(q1)->first;
            if (q1>=q2) {
                printf("-1\n");
                continue;
            }
            remain=q3;
            state=0;
            getans(1,q1,q2);
            if (remain>0 || state==2) printf("-1\n");
            else printf("%.9f\n",ans);
        }
    }
    //printseg(root);
}

#include <bits/stdc++.h>
#include <chrono>
#define INF 1000 * 1000 * 1000
#define LINF INF * (LL)INF
#define LL long long
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
LL l , r , v;
int Q;
struct node
{
	int L , R;
	int y;
	LL time , speed , tL , tR , speedR , res , mn;
	node()
	{
		L = -1 , R = -1;
		speed = 0;
		mn = 0;
		y = rng();
	}
}
t[100005];
int nodeCnt;
int getNode()
{
	return nodeCnt++;
}
int update(int v)
{
	if(v == -1)
		return v;
	t[v].tL = t[v].tR = t[v].time;
	t[v].speedR = t[v].speed;

	LL Mn = 0 , Res = 0;
	if(t[v].L != -1)
	{
		t[v].tL = t[t[v].L].tL;
		Mn = min(Mn , t[t[v].L].mn);
		Mn = min(Mn , t[t[v].L].res + (t[v].time - t[t[v].L].tR) * (LL) t[t[v].L].speedR);
		Res = t[t[v].L].res + (t[v].time - t[t[v].L].tR) * (LL) t[t[v].L].speedR;
	}
	if(t[v].R != -1)
	{
		Mn = min(Mn , Res + (t[t[v].R].tL - t[v].time) * (LL)t[v].speed + t[t[v].R].mn);
		Res += (t[t[v].R].tL - t[v].time) * t[v].speed;
		Res += t[t[v].R].res;
		t[v].speedR = t[t[v].R].speedR;
		t[v].tR = t[t[v].R].tR;
	}
	t[v].mn = Mn;
	t[v].res = Res;

	return v;
}
void split(int v , int T , int &L , int &R)
{
	if(v == -1)
	{
		L = -1 , R = -1;
		return;
	}
	if(t[v].time > T)
	{
		split(t[v].L , T , L , t[v].L);
		R = update(v);
	}
	else
	{
		split(t[v].R , T , t[v].R , R);
		L = update(v);
	}
}
int merge(int L , int R)
{
	if(L == -1)
		return R;
	if(R == -1)
		return L;
	if(t[L].y > t[R].y)
	{
		t[L].R = merge(t[L].R , R);
		return update(L);
	}
	else
	{
		t[R].L = merge(L , t[R].L);
		return update(R);
	}
}
double getAns(int noda)
{
	if(v == 0)
		return l;
	//////debug(noda);
	if(noda == -1)
	{
		return -1;
	}

	if(t[noda].mn <= -v)
	{
		if(t[noda].L != -1 && t[t[noda].L].mn <= -v)
		{
			return getAns(t[noda].L);
		}
		LL Res = t[noda].L == -1 ? 0 : t[t[noda].L].res;

		if(t[noda].L != -1)
		{
			if(Res + (t[noda].time - t[t[noda].L].tR) * t[t[noda].L].speedR <= -v)
			{
				v += Res;
				//debug("Tut1");
				return t[t[noda].L].tR + (v * 1.0) / abs(t[t[noda].L].speedR);
			}
			Res += (t[noda].time - t[t[noda].L].tR) * t[t[noda].L].speedR;
		}

		if(t[noda].R != -1)
		{
			////debug(t[t[noda].R].tL);
			////debug(t[noda].speed);
			////debug(Res + (t[t[noda].R].tL - t[noda].time) * t[noda].speed);
			if(Res + (t[t[noda].R].tL - t[noda].time) * t[noda].speed <= -v)
			{
				v += Res;
				//debug("Tut2");
				return t[noda].time + (v * 1.0) / abs(t[noda].speed);
			}
			Res += (t[t[noda].R].tL - t[noda].time) * t[noda].speed;
			v += Res;
			return getAns(t[noda].R);
		}
		assert(false);
	}
	else
	{
		LL val = t[noda].res + (r - t[noda].tR) * (LL)t[noda].speedR;
		//if(Q == 100)
		//	debug(val);
		if(val <= -v)
		{
				//debug("Tut3");
				//debug(t[noda].tR);
				//debug(t[noda].res);
				//debug(t[noda].speedR);

				v += t[noda].res;
				//debug(v);
				return t[noda].tR + ((v * 1.0) / abs(t[noda].speedR));
		}
		return -1;
	}
}
int main()
{
	ios_base::sync_with_stdio(0);
	int q;
	cin >> q;
	Q = q;
	int root = -1;
	while(q--)
	{
		//debug(root);
		int type;
		cin >> type;
		if(type == 1)
		{
			int T , s;
			cin >> T >> s;
			int newNode = getNode();
			//////debug(newNode);
			t[newNode].time = T;
			t[newNode].speed = s;
			update(newNode);
			int L , R;
			split(root , T , L , R);
			root = merge(L , newNode);
			root = merge(root , R);
			//////debug(t[root].speedR);
		}
		else if(type == 2)
		{
			int t;
			cin >> t;
			int L , R;
			split(root , t - 1 , L , R);
			int L1 , R1;
			split(R , t , L1 , R1);
			root = merge(L , R1);
		}
		else
		{
			cin >> l >> r >> v;
			int L , M , M1 , R;
			split(root , l - 1 , L , M);
			split(M , r , M1 , R);
			cout << fixed << setprecision(10) << getAns(M1) << '\n';
			root = merge(L , M1);
			root = merge(root , R);
		}
	}
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y0998244353
#define y1 y1998244353
#define die(cond) if (cond) for (;;) {}
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acosl(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct vertex {
	ll time, speed;
	ll tl, tr, speedR;
	ll res = 0, minn = 0;
	ll l = -1, r = -1;
	ll prior = rand();
	ll par = -1;
};
struct treap {
	vector<vertex> t;
	treap() {}
	ll newv(ll t_, ll s_) {
		vertex v;
		v.time = t_, v.speed = s_;
		t.pb(v);
		upd(sz(t) - 1);
		return sz(t) - 1;
	}
	void setpar(ll v, ll p) {
		if (v == -1) {
			return;
		}
		t[v].par = p;
	}
	void $upd(ll v) {
		if (v == -1) {
			return;
		}
		ll& time = t[v].time;
		ll& speed = t[v].speed;
		ll& res = t[v].res;
		ll& minn = t[v].minn;
		ll l = t[v].l, r = t[v].r;
		res = 0, minn = 0;
		if (l != -1) {
			mineq(minn, t[l].minn);
			res += t[l].res;
			res += t[l].speedR * (time - t[l].tr);
			mineq(minn, res);
			t[v].tl = t[l].tl;
		} else {
			t[v].tl = time;
		}
		if (r != -1) {
			res += speed * (t[r].tl - time);
			mineq(minn, res + t[r].minn);
			res += t[r].res;
			mineq(minn, res);
			t[v].tr = t[r].tr;
			t[v].speedR = t[r].speedR;
		} else {
			t[v].tr = time;
			t[v].speedR = speed;
		}
	}
	void upd(ll v) {
		if (v == -1) {
			return;
		}
		$upd(v);
		setpar(t[v].l, v);
		setpar(t[v].r, v);
	}
	void rotate(ll v) {
		ll p = t[v].par;
		ll gp = t[p].par;
		if (gp != -1) {
			if (t[gp].l == p) {
				t[gp].l = v;
			} else {
				t[gp].r = v;
			}
		}
		if (t[p].l == v) {
			t[p].l = t[v].r;
			t[v].r = p;
		} else {
			t[p].r = t[v].l;
			t[v].l = p;
		}
		setpar(v, gp);
		upd(v), upd(p);
	}
	ll splay(ll v) {
		if (v == -1) {
			return -1;
		}
		while (t[v].par != -1) {
			rotate(v);
		}
		return v;
	}
	ll find(ll v, ll k) {
		if (v == -1) {
			return -1;
		}
		if (t[v].time == k) {
			return splay(v);
		}
		if (t[v].time > k && t[v].l != -1) {
			return find(t[v].l, k);
		}
		if (t[v].time < k && t[v].r != -1) {
			return find(t[v].r, k);
		}
		return splay(v);
	}
	pll split(ll v, ll k) {
		if (v == -1) {
			return { -1, -1 };
		}
		v = find(v, k);
		if (t[v].time < k) {
			ll r = t[v].r;
			t[v].r = -1;
			setpar(r, -1);
			upd(v), upd(t[v].l), upd(r);
			return { v, r };
		} else {
			ll l = t[v].l;
			t[v].l = -1;
			setpar(l, -1);
			upd(v), upd(l),	upd(t[v].r);
			return { l, v };
		}
	}
	ll merge(ll f, ll s) {
		if (f == -1) {
			return s;
		}
		if (s == -1) {
			return f;
		}
		s = find(s, t[f].time);
		t[s].l = f;
		setpar(f, s);
		upd(s), upd(f);
		return s;
	}
	void add(ll& root, ll t_, ll s) {
		ll a, b;
		tie(a, b) = split(root, t_);
		root = newv(t_, s);
		t[root].l = a, t[root].r = b;
		upd(root);
	}
	void del(ll& root, ll t_) {
		ll v = find(root, t_);
		setpar(t[v].l, -1);
		setpar(t[v].r, -1);
		root = merge(t[v].l, t[v].r);
	}
	ld down(ll v, ll V, ll R) {
		if (v == -1) {
			return -1;
		}
		ll lres = 0;
		if (t[v].l != -1) {
			ll minn = t[t[v].l].minn;
			lres += t[t[v].l].res + t[t[v].l].speedR * (t[v].time - t[t[v].l].tr);
			mineq(minn, lres);
			if (V + minn <= 0) {
				return down(t[v].l, V, t[v].time);
			}
		}
		V += lres;
		ll tr = R;
		if (t[v].r != -1) {
			tr = t[t[v].r].tl;
		}
		if (V + t[v].speed * (tr - t[v].time) <= 0) {
			ld ans = t[v].time - ld(V) / ld(t[v].speed);
			return ans;
		}
		if (t[v].r != -1) {
			V += t[v].speed * (t[t[v].r].tl - t[v].time);
			return down(t[v].r, V, R);
		}
		return -1;
	}
	ld getans(ll& root, ll l, ll r, ll v) {
		if (v == 0) {
			return l;
		}
		ll a, b, c;
		tie(a, b) = split(root, l);
		tie(b, c) = split(b, r + 1);
		ld ans = down(b, v, r);
		root = merge(merge(a, b), c);
		return ans;
	}
};

ll q;
treap tr;

inline void solve() {
	cout << setprecision(7) << fixed;
	ll root = -1;
	for (ll i = 0; i < q; i++) {
		ll t;
		cin >> t;
		if (t == 1) {
			ll time, s;
			cin >> time >> s;
			tr.add(root, time, s);
		} else if (t == 2) {
			ll time;
			cin >> time;
			tr.del(root, time);
		} else if (t == 3) {
			ll l, r, v;
			cin >> l >> r >> v;
			ld ans = tr.getans(root, l, r, v);
			cout << ans << endl;
		}
	}
}

inline void read() {
	cin >> q;
}

    #include <bits/stdc++.h>

    #define f first
    #define s second
    #define pb push_back
    #define mp make_pair

    #define pitem item*
    #define tam 1023456
    #define tamN 12345
    using namespace std;
    typedef long long ll;

    typedef pair<ll,ll> ii;
    typedef pair<int,ii> iii;
    const ll INF=2e18;
    struct item
    {
        int prior,cnt;
        ll pos,speed,minn,tot;
        ii pos_viz;
        ii pos_vder;
        pitem l;
        pitem r;
        item(){}
        item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
        {
            prior=rand();
            minn=INF;
            pos_viz=pos_vder=ii(pos,speed);
        }

    };
    int cnt(pitem t){return t?t->cnt:0;}
    ll gtot(pitem t){return t?t->tot:0;}
    ll gmin(pitem t){return t?t->minn:INF;}

    ll gextraiz(pitem t){
        if (!t|| (!(t->l)))
            return 0;
        else
            return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
    }
    ll gextrader(pitem t){
        if (!t|| !(t->r))
            return 0;
        return  (t->r->pos_viz.f-t->pos)*(t->speed);
    }
    void upd_cnt(pitem t)
    {
        if (t)
        {
            t->cnt=cnt(t->l)+cnt(t->r)+1;
            ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
            t->tot=totiz;
            t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
            if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
            if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
            t->tot+=gtot(t->r);
            t->minn=gmin(t->l);
            t->minn=min(t->minn,totiz);
            t->minn=min(t->minn,totiz+extraiz);
            t->minn=min(t->minn,totiz+extraiz+extrader);
            t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
            t->minn=min(t->minn,t->tot);
        }
    }
    void split(pitem t,pitem &l,pitem &r,int key)
    {
        if (!t)
            return void(l=r=0);
        if (t->pos>key)
            split(t->l,l,t->l,key),r=t;
        else
            split(t->r,t->r,r,key),l=t;
        upd_cnt(t);
    }
    void merge(pitem &t,pitem l,pitem r)
    {
        if (!l||!r)
            t=l?l:r;
        else if (r->prior>l->prior)
            merge(l->r,l->r,r),t=l;
        else
            merge(r->l,l,r->l),t=r;
        upd_cnt(t);
    }
    ll auxresp;
    double respf;ll iz,der;
    pitem ant_t;
    bool print=false;
    void query(pitem t,ll inival)
    {

        if (t==0)
        {
            if (!ant_t)
                return void(auxresp=-1);

            // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
            ll extra;
            extra=(der-ant_t->pos)*(ant_t->speed);
            if (inival+extra<=0)
            {
                if (ant_t->speed==0)
                return void(auxresp=-1);
                auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
                respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
                return;
            }
            else
                return void(auxresp=-1);
        }
        ant_t=t;
        ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
        if (gmin(t->l)+inival<=0)
        {
            query(t->l,inival);
            // cout<<"go left\n";
        }
        else
        {
            ll extraiz,extrader,totiz;
            extraiz=(t->l)?gextraiz(t):0;
            extrader=(t->r)?gextrader(t):0;
            totiz=gtot(t->l);
            ll auxini=totiz+extraiz+extrader;
            // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
            if (totiz+extraiz+inival<=0)
            {
                inival+=totiz;
                if ((t->l->pos_vder.s)==0)
                    cout<<"watizquierda: ";
                auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
                respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
            }
            else if (totiz+extraiz+extrader+inival<=0)
            {
                inival+=totiz+extraiz;
                if (t->speed==0)
                    cout<<"watderecha: ";
                auxresp=(t->pos)-(inival)/(t->speed);//-.-

                respf=-(double)(inival%t->speed)/(t->speed);//-.-

            }
            else
                {

                    // cout<<"go right\n";
                    query(t->r,auxini+inival);
                }

        }
    }

    int main()
    {
        int casos;
        scanf("%d",&casos);
        int tipo;
        pitem t1;pitem t2;pitem t3;
        pitem s;
        pitem tree=new item(2e9,1);
        ll val,pos;
        double auxrespf;
        while(casos--)
        {
            scanf("%d",&tipo);
            if (tipo==1)
            {
                scanf("%lld %lld",&pos,&val);
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                s=new item(pos,val);
                merge(tree,t1,s);
                merge(tree,tree,t3);
            }
            else if (tipo==2)
            {
                scanf("%lld",&pos);
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
            }
            else if (tipo==3)
            {
                scanf("%lld %lld %lld",&iz,&der,&val);
                if (val==0)
                {
                    printf("%lld.0\n",iz);
                    continue;
                }
                split(tree,t1,t3,der);
                split(t1,t1,t2,iz-1);
                ant_t=NULL;
                query(t2,val);
                if (auxresp==-1)
                    printf("-1\n");
                else
                {
                    auxrespf=auxresp+respf;
                    printf("%.9lf\n",auxrespf);
                }
                merge(tree,t1,t2);
                merge(tree,tree,t3);
            }
         //   inorder(tree);
            //// cout<<endl;
        }
    }

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAXN = 100005;

#define fi first
#define se second

#define SZ(x) (x ? x->size : 0)

struct Node
{
	int t, s, tL, tR, sR, h, size;
	ll mn, res;
	Node *lc, *rc;

	Node() {}
	Node(int _t, int _s) : t(_t), tL(_t), tR(_t), s(_s), sR(_s), h(rand()), size(1), res(0), lc(NULL), rc(NULL) {}

	void update()
	{
		size = 1 + SZ(lc) + SZ(rc);
		mn = 0, res = 0, tL = t, tR = t, sR = s;
		if (lc)
			tL = lc->tL, res = lc->res + (ll)(t - lc->tR) * lc->sR, mn = min(lc->mn, res);
		if (rc)
		{
			ll d = res + (ll)(rc->tL - t) * s;
			tR = rc->tR, sR = rc->sR, res = d + rc->res, mn = min(mn, rc->mn + d);
		}
	}
}pool[MAXN], *root = 0;

typedef pair<Node*, Node*> pNN;

inline Node *node(int t, int s)
{
	static int x = 0;
	pool[x] = Node(t, s);
	return pool + x++;
}

pNN split(Node *p, int t)
{
	if (!p)
		return (pNN){NULL, NULL};
	if (p->t <= t)
	{
		pNN y = split(p->rc, t);
		p->rc = y.fi, p->update();
		return (pNN){p, y.se};
	}
	else
	{
		pNN y = split(p->lc, t);
		p->lc = y.se, p->update();
		return (pNN){y.fi, p};
	}
}

Node *merge(Node *a, Node *b)
{
	if (!a) return b;
	if (!b) return a;
	if (a->h < b->h)
	{
		a->rc = merge(a->rc, b), a->update();
		return a;
	}
	else
	{
		b->lc = merge(a, b->lc), b->update();
		return b;
	}
}

void insert(int t, int s)
{
	pNN y = split(root, t);
	root = merge(merge(y.fi, node(t, s)), y.se);
}

void erase(int t)
{
	pNN x = split(root, t - 1);
	pNN y = split(x.se, t);
	root = merge(x.fi, y.se);
}

double query(Node *p, ll v)
{
	if (p->lc && p->lc->mn + v <= 0)
		return query(p->lc, v);
	if (p->lc && v + p->lc->res + (ll)(p->t - p->lc->tR) * p->lc->sR <= 0)
		return p->lc->tR + (v + p->lc->res) / fabs(p->lc->sR);
	ll d = v + (p->lc ? p->lc->res + (ll)(p->t - p->lc->tR) * p->lc->sR : 0);
	if (d + (ll)(p->rc->tL - p->t) * p->s <= 0)
		return p->t + d / fabs(p->s);
	return query(p->rc, d + (ll)(p->rc->tL - p->t) * p->s);
}

double query(int l, int r, int v)
{
	if (v == 0)
		return l;
	pNN x = split(root, l - 1);
	pNN y = split(x.se, r);
	Node *p = y.fi;
//	if (p)
//		cerr << "{" << p->mn << "," << p->res << "}" << endl;
	double ret;
	if (!p)
		ret = -1;
	else if (v + p->mn > 0)
	{
		if (p->sR >= 0)
			ret = -1;
		else
			ret = p->tR + (v + p->res) / fabs(p->sR);
	}
	else
		ret = query(p, v);
	root = merge(x.fi, merge(y.fi, y.se));
	if (ret > r)
		ret = -1;
	return ret;
}

int q, id, t, s, l, r, v;

int main()
{
	ios::sync_with_stdio(false); cin.tie(0);
	cin >> q;
	while (q--)
	{
		cin >> id;
		if (id == 1)
		{
			cin >> t >> s;
			insert(t, s);
		}
		else if (id == 2)
		{
			cin >> t;
			erase(t);
		}
		else
		{
			cin >> l >> r >> v;
			cout << setprecision(9) << query(l, r, v) << endl;
		}
	}
	return 0;
}

#include <bits/stdc++.h>
using std::cin;
using std::cout;

typedef long long ll;
typedef std::pair <int, int> pr;
typedef std::map <int, int> map;
const int N = 100054;

struct request {
	int op, arg[3];
	friend std::istream & operator >> (std::istream &in, request &B) {
		switch (in >> B.op, B.op) {
			case 1: return in >> B.arg[0] >> B.arg[1];
			case 2: return in >> B.arg[0];
			case 3: return in >> B.arg[0] >> B.arg[1] >> B.arg[2];
			default: return in;
		}
	}
} qry[N];

int n;
int left[N];
map C;

inline int min(const int x, const int y) {return x < y ? x : y;}
inline ll min(const ll x, const ll y) {return x < y ? x : y;}

namespace DC {
	int F[N]; pr D[N];

	int Discretize(int n) {
		int i, cnt = 0; std::sort(D, D + n);
		for (i = 0; i < n; ++i)
			F[D[i].second] = (i && D[i].first == D[i - 1].first ? cnt - 1 : (D[cnt] = D[i], cnt++));
		return cnt;
	}
}

namespace ST {
	#define segc int M = (L + R - 1) >> 1, lc = id << 1, rc = lc | 1
	#define exist_pd if (x[id].tag) push_down(x[id], x[lc], x[rc], L, M, R)
	struct node {int v; bool tag; ll s, m;} x[265000];

	inline void update(node &ret, const node &l, const node &r) {ret.s = l.s + r.s, ret.m = min(l.m, l.s + r.m);}
	inline void cover(node &ret, int L, int R, int v) {ret.v = v, ret.tag = true, ret.s = ll(left[R + 1] - left[L]) * v, ret.m = min(ret.s, 0ll);}
	inline void push_down(node &ret, node &l, node &r, int L, int M, int R) {cover(l, L, M, ret.v), cover(r, M + 1, R, ret.v), ret.v = 0, ret.tag = false;}

	void adj(int id, int L, int R, int ql, int qr, int v) {
		if (ql <= L && R <= qr) return cover(x[id], L, R, v);
		segc; exist_pd;
		if (ql <= M) adj(lc, L, M, ql, qr, v);
		if (qr > M) adj(rc, M + 1, R, ql, qr, v);
		update(x[id], x[lc], x[rc]);
	}

	int integral, extraB;
	ll extraA;
	bool succ;

	ll query(int id, int L, int R, int h, ll v) {
		if (h <= L) {
			if (v + x[id].m > 0) return x[id].s;
			if (L == R) return assert(x[id].v < 0), integral = left[L], extraA = v, extraB = -x[id].v, succ = true;
		}
		segc; exist_pd;
		if (h > M) return query(rc, M + 1, R, h, v);
		ll ls = query(lc, L, M, h, v), rs;
		if (succ) return 0;
		rs = query(rc, M + 1, R, h, v + ls);
		return ls + rs;
	}
}

int main() {
	int i, j, q, t, u, v, dur; ll w; map::iterator it;
	std::ios::sync_with_stdio(false), cin.tie(NULL);
	cin >> q, cout << std::setprecision(12);
	for (i = 0; i < q; ++i) if (cin >> qry[i], qry[i].op != 3) DC::D[i] = pr(qry[i].arg[0], i);
	DC::D[q] = pr(0, q), DC::D[q + 1] = pr(1000000001, q + 1);
	n = DC::Discretize(q + 2);
	for (i = 0; i < n; ++i) left[i] = DC::D[i].first;
	for (i = 0; i < q; ++i) if (qry[i].op != 3) qry[i].arg[0] = DC::F[i];
	C.emplace(0, 0), C.emplace(n - 1, 0);
	for (i = 0; i < q; ++i)
		switch (qry[i].op) {
			case 1:
				t = qry[i].arg[0], it = C.emplace(t, v = qry[i].arg[1]).first, u = (++it)->first,
				ST::adj(1, 0, n - 2, t, u - 1, v); break;
			case 2:
				t = qry[i].arg[0], it = C.find(t), u = std::next(it)->first;
				ST::adj(1, 0, n - 2, t, u - 1, std::prev(it)->second), C.erase(it); break;
			case 3:
				t = qry[i].arg[0], u = qry[i].arg[1], w = qry[i].arg[2];
				if (!w) {cout << t << '\n'; continue;}
				j = std::lower_bound(left, left + n, t) - left;
				dur = left[j] - t, v = (--C.lower_bound(j))->second;
				if (dur >= u) {cout << (w + v * ll(u - t) <= 0 ? t - (double)w / v : -1.) << '\n'; continue;}
				if (w + (ll)v * dur <= 0) {cout << t - (double)w / v << '\n'; continue;}
				if (ST::succ = false, j < n - 1) ST::query(1, 0, n - 2, j, w + (ll)v * dur);
				cout << (ST::succ && ST::extraA <= ST::extraB * ll(u - ST::integral) ? ST::integral + (double)ST::extraA / ST::extraB : -1.) << '\n'; break;
		}
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;

#define pb push_back
#define forn(i, n) for (int i = 0; i < (int)(n); i++)
#define forrn(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define PYMOD(a, m) ((((a) % (m)) + (m)) % (m))
#define all(v) v.begin(), v.end()
#define mp make_pair
#define ff first
#define ss second

const int mod = 1e9 + 7;

mt19937 rnd(179);

template<class T>
class treap {
    struct node {
        T info;
        node *L, *R;
        int y;

        node(T value, int y)
            : info(value)
            , L(nullptr)
            , R(nullptr)
            , y(y)
        {}

        void update() {
            info.update(L ? &L->info : nullptr, R ? &R->info : nullptr);
        }
    };

    void update(node *v) {
        if (v)
            v->update();
    }

    void splitL(node *v, T x, node *&left, node *&right) {
        if (!v) {
            left = right = nullptr;
            return;
        }

        if (x < v->info) {
            splitL(v->L, x, left, v->L);
            update(v);
            right = v;
        } else {
            splitL(v->R, x, v->R, right);
            update(v);
            left = v;
        }
    }

    void splitR(node *v, T x, node *&left, node *&right) {
        if (!v) {
            left = right = nullptr;
            return;
        }

        if (v->info < x) {
            splitR(v->R, x, v->R, right);
            update(v);
            left = v;
        } else {
            splitR(v->L, x, left, v->L);
            update(v);
            right = v;
        }
    }

    node *merge(node *left, node *right) {
        if (!left)
            return right;
        if (!right)
            return left;
        if (left->y < right->y) {
            left->R = merge(left->R, right);
            update(left);
            return left;
        } else {
            right->L = merge(left, right->L);
            update(right);
            return right;
        }
    }

    node *root;

    treap(node *v)
        : root(v)
    {}
public:
    treap()
        : root(nullptr)
    {}

    void insert(T value) {
        node *lt, *rt;
        splitL(root, value, lt, rt);
        lt = merge(lt, new node(value, rnd()));
        root = merge(lt, rt);
    }

    void erase(T value) {
        node *lt, *mid, *rt;
        splitR(root, value, lt, rt);
        splitL(rt, value, mid, rt);
        if (mid != nullptr)
            delete mid;
        root = merge(lt, rt);
    }

    pair<treap, treap> splitL(T value) {
        node *lt, *rt;
        splitL(root, value, lt, rt);
        root = nullptr;
        return make_pair<treap, treap>(lt, rt);
    }

    pair<treap<T>, treap<T>> splitR(T value) {
        node *lt, *rt;
        splitR(root, value, lt, rt);
        root = nullptr;
        return make_pair<treap<T>, treap<T>>(lt, rt);
    }

    void mergeTo(treap<T> right) {
        root = merge(root, right.root);
        right.root = nullptr;
    }

    T rootEvent(T orElse) {
        if (!root)
            return orElse;
        return root->info;
    }

    struct iterator {
        node *v;

        T& operator*() {
            return v->info;
        }

        T* operator->() {
            return &v->info;
        }

        bool hasLeft() {
            return v->L;
        }

        iterator left() {
            return { v-> L };
        }

        bool hasRight() {
            return v->R;
        }

        bool isLeaf() {
            return !(hasLeft() || hasRight());
        }

        iterator right() {
            return { v-> R };
        }
    };

    iterator rootIterator() {
        return { root };
    }
};

struct event {
    ll time, speed;
    ll tL, tR;
    ll speedR;
    ll res;
    ll mn;

    event(int time)
        : time(time)
    {}

    event(ll time, ll speed)
        : time(time)
        , speed(speed)
        , tL(time)
        , tR(time)
        , speedR(speed)
        , res(0)
        , mn(0)
    {}

    void update(event* L, event* R) {
        mn = 0, res = 0;
        if (L) {
            mn = min(mn, L->mn);
            res += L->res + L->speedR * (time - L->tR);
        }
        mn = min(mn, res);
        if (R) {
            res += speed * (R->tL - time);
            mn = min(mn, res + R->mn);
            res += R->res;
        }
        mn = min(mn, res);

        tL = time;
        if (L) tL = L->tL;
        tR = time;
        if (R) tR = R->tR;
        speedR = speed;
        if (R) speedR = R->speedR;
    }

    bool operator<(const event& other) const {
        return time < other.time;
    }
};

void print(treap<event>::iterator it) {
    if (it.hasLeft())
        print(it.left());
    cerr << it->time << " " << it->speed << endl;
    if (it.hasRight())
        print(it.right());
}

int main() {
    cout.precision(10);
    // Code here:

    treap<event> tr;
    tr.insert(event(0, 0));

    int q;
    cin >> q;

    forn(i, q) {
        int type;
        cin >> type;
        if (type == 1) {
            ll t, s;
            cin >> t >> s;
            tr.erase(event(t));
            tr.insert(event(t, s));
        } else if (type == 2) {
            ll t;
            cin >> t;
            tr.erase(event(t));
        } else {
            ll l, r; ll s;
            cin >> l >> r >> s;
            auto p = tr.splitL(event(l));
            auto q = p.ss.splitL(event(r));
            bool printT = false;

            event prev = p.ff.rootEvent(event(0, 0));
            if (q.ff.rootEvent(event(-1)).time == -1) {
                if (s == 0) {
                    cout << l << endl;
                } /*else if (s + (r - l) * prev.speed <= 0) {
                    printT = true;
                    cout << l + (ld)s / (-prev.speed) << endl;
                }*/ else {
                    cout << -1 << endl;
                }
            } else {
                event first = q.ff.rootEvent(event(-1));
                if (s == 0) {
                    cout << l << endl;
                } else if (s + (first.tL - l) * prev.speed <= 0) {
                    cout << l + (ld)s / (-prev.speed) << endl;
                } else {
                    s += (first.tL - l) * prev.speed;
                    if (first.mn + s <= 0) {
                        ll ctime = l;
                        auto it = q.ff.rootIterator();
                        while (true) {
                            assert(it.hasLeft() || it.hasRight());
                            if (it.hasLeft()) {
                                if (s + it.left()->mn <= 0) {
                                    it = it.left();
                                    continue;
                                }
                                s += it.left()->res;
                                ctime = it.left()->tR;
                                if (s + (it->time - ctime) * it.left()->speedR <= 0) {
                                    cout << ctime + (ld)s / (-it.left()->speedR) << endl;
                                    break;
                                }
                            }
                            ctime = it->time;
                            if (it.hasRight()) {
                                if (s + (it.right()->tL - ctime) * it->speed <= 0) {
                                    cout << ctime + (ld)s / (-it->speed) << endl;
                                    break;
                                }
                                s += (it.right()->tL - ctime) * it->speed;
                                ctime = it.right()->tL;
                                it = it.right();
                            }
                        }
                    } else {
                        s += first.res;
                        if (s + (r - first.tR) * first.speedR <= 0) {
                            cout << first.tR + (ld)s / (-first.speedR) << endl;
                        } else {
                            cout << -1 << endl;
                        }
                    }
                }
            }

            p.ff.mergeTo(std::move(q.ff));
            p.ff.mergeTo(std::move(q.ss));
            tr = std::move(p.ff);

            if (printT) {
                print(tr.rootIterator());
            }
        }
    }

    return 0;
}

#include<bits/stdc++.h>
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
using namespace std;

template<class T>inline void rd(T & x){ int f = 1;x = 0;char ch = getchar();for(;!isdigit(ch);ch = getchar()) if(ch == '-') f = -1; for(;isdigit(ch);ch = getchar()) x = x * 10 + ch - '0';x *= f;}

const int maxn = 1e5 + 10;

struct op{
	int type;
	int t,l,r,v,s;
} querys[maxn];

int times[maxn],n;
inline int upper(double time){
	int l = 1,r = n,ans = n + 1;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] >= time){
			ans = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	return ans;
}
inline int lower(double time){
	int l = 1,r = n,ans = 0;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] <= time){
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return ans;
}

int mark[maxn];
namespace Fenwick{
	int tr[maxn];
	inline void update(int x,int v){ for(;x < maxn;x += x & (-x)) tr[x] += v;}
	inline int query(int x){ int ans = 0; for(;x;x ^= x & (-x)) ans += tr[x]; return ans;}
	inline int val(int x) { return query(x) - query(x - 1);}
	inline int bs(int x){ // min query(ans) >= x
		int l = 0,r = n,ans = 0;
		while(l <= r){
			int mid = l + r >> 1;
			if(query(mid) >= x) {
				ans = mid;
				r = mid - 1;
			} else {
				l = mid + 1;
			}
		}
		return ans;
	}
	inline int pre(int x){
		int d = query(x - 1);
		return bs(d);
	}
	inline int suc(int x){
		return bs(query(x) + 1);
	}
}
double cur[maxn];
const double inf = 2e20;
namespace Segment{
	double tra[maxn << 2],tri[maxn << 2];
	double lazy[maxn << 2];
	int mk[maxn << 2];

	inline void pushup(int rt){
		tra[rt] = max(tra[rt << 1],tra[rt << 1 | 1]);
		tri[rt] = min(tri[rt << 1],tri[rt << 1 | 1]);
	}
	inline void pushdown(int rt){
		if(!mk[rt]) return;
		mk[rt] = 0;
		mk[rt << 1] = 1;
		mk[rt << 1 | 1] = 1;
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		tra[rt << 1] += lazy[rt];
		tri[rt << 1] += lazy[rt];
		tra[rt << 1 | 1] += lazy[rt];
		tri[rt << 1 | 1] += lazy[rt];
		lazy[rt] = 0;
	}
	void _update(double * target,int pos,double v,int l,int r,int rt){
		if(l == r){
			target[rt] = v;
			return;
		}
		int mid = l + r >> 1;
		if(pos <= mid) _update(target,pos,v,lson);
		else _update(target,pos,v,rson);
		pushup(rt);
	}
	void setVoid(int pos){
		_update(tra,pos,-inf,1,n,1);
		_update(tri,pos,inf,1,n,1);
	}
	void setZero(int pos){
		_update(tra,pos,0,1,n,1);
		_update(tri,pos,0,1,n,1);
	}
	void build(int l,int r,int rt){
		if(l == r){
			tra[rt] = -inf;
			tri[rt] = inf;
			return;
		}
		int mid = l + r >> 1;
		build(lson);
		build(rson);
		pushup(rt);
	}
	void update(int L,int R,double v,int l,int r,int rt){
		if(L <= l && r <= R){
			lazy[rt] += v;
			tra[rt] += v;
			tri[rt] += v;
			mk[rt] = 1;
			return;
		}
		pushdown(rt);
		int mid = l + r >> 1;
		if(L <= mid) update(L,R,v,lson);
		if(R > mid) update(L,R,v,rson);
		pushup(rt);
	}
	double querya(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tra[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = -inf;
		if(L <= mid) ans = max(ans,querya(L,R,lson));
		if(R > mid)ans = max(ans,querya(L,R,rson));
		return ans;
	}
	double queryi(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tri[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = inf;
		if(L <= mid) ans = min(ans,queryi(L,R,lson));
		if(R > mid) ans = min(ans,queryi(L,R,rson));
		return ans;
	}

}
double calc(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return (l - times[x]) * cur[x] + Segment::querya(x,x,1,n,1);
}
const double eps = 1e-9;
bool check(double l,double r,double c){
	double qa = -inf,qi = inf;
	if(l == r) return abs(calc(l) - c) <= eps;
	qa = max(calc(l),qa);
	qi = min(calc(l),qi);
	qa = max(calc(r),qa);
	qi = min(calc(r),qi);
	int lx = upper(l),rx = lower(r);
	if(lx <= rx && lx != 0 && rx != 0){
		qa = max(qa,Segment::querya(lx,rx,1,n,1));
		qi = min(qi,Segment::queryi(lx,rx,1,n,1));
	}
	return qa >= c && qi <= c;
}

int main(){
	int TAT;
	rd(TAT);
	for(int i = 1;i <= TAT;i++){
		int type,t,l,r,v,s;
		rd(type);
		if(type == 1){ // add
			rd(t); rd(v);
			times[++n] = t;
			querys[i].type = 1;
			querys[i].t = t;
			querys[i].v = v;
		} else if(type == 2){
			rd(t);
			querys[i].type = 2;
			querys[i].t = t;
		} else {
			rd(l); rd(r); rd(s);
			querys[i].type = 3;
			querys[i].l = l;
			querys[i].r = r;
			querys[i].s = s;
		}
	}
	sort(times + 1,times + n + 1);
	n = unique(times + 1,times + n + 1) - times - 1;

	if(n!=0)Segment::build(1,n,1);
	for(int i = 1;i <= TAT;i++){
		int type = querys[i].type;
		if(type == 1){
			int t = querys[i].t, v = querys[i].v;
			int pos = upper(t);
			Fenwick::update(pos,1);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			cur[pos] = v;
			Segment::setZero(pos);
			if(pre){
				double delta = (double)cur[pre] * (times[pos] - times[pre]) + Segment::querya(pre,pre,1,n,1);
				Segment::update(pos,pos,delta,1,n,1);
			}
			if(pre && suc){
				double delta = (double)(v - cur[pre]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
		} else if(type == 2){
			int t = querys[i].t;
			int pos = upper(t);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			Fenwick::update(pos,-1);
			if(suc){
				double delta = (double)(cur[pre] - cur[pos]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
			Segment::setVoid(pos);
			cur[pos] = 0;
		} else {
			double l = querys[i].l , r = querys[i].r , s = -querys[i].s;
			if(s == 0) {
				printf("%.9f\n",l);
				continue;
			}
			bool ok = 0;
			if(check(r,r,s) || check(l,l,s)) ok = 1;
			for(int k = 0;k < 100;k++){
				double mid = (l + r) / 2;
				if(check(l,mid,s)){
					r = mid;
					ok = 1;
				} else {
					l = mid;
				}
			}
			if(ok)printf("%.9f\n",r);
			else printf("-1\n");
		}
	}
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q,st,tcnt,jeste,tip2c;
ll inf=3e18;
mt19937 gen(500);
map<ll,ll> mapa;
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void upd(pnode x){
    if(x==NULL)return;
    x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
}
void ispis(pnode x,int &ct){

    if(ct<1)return;
    if(x==NULL)return;
    push(x);

    ispis(x->l,ct);
    ct--;
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r,ct);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_mn(x->l)<=val)qry(x->l,val,tm);
    else if(x->val<=val){
        tm=x->t;
        if(jeste)cout<<x->val<<" "<<val<<" "<<x->t<<" EVEGGAA\n";
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    if(midtree==NULL){ret=-1;}
    else{

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*if(jeste){
            printf("\n\nISPIS A\n");
            int pm=12;
            ispis(midtree,pm);
            printf("\n");
        }*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
        if(jeste)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;

            last_node(midtree,lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            ////printf("%d TMTM\n",tm);

            pnode lst=NULL;
            last_node(pom1,lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            if(jeste)cout<<zero<<" "<<lst->val<<" "<<lst->s<<" "<<lst->t<<" "<<l<<" "<<r<<" EVOGA\n";

            mrg(midtree,pom1,pom2);
        }
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
ll nadji(pnode x,ll val){

    if(x==NULL)return inf;
    push(x);

    if(val==x->t)return x->val;
    else if(val<x->t)return nadji(x->l,val);
    else return nadji(x->r,val);
}
bool check(){

    ll curr=0;
    ll t,s;
    int br=0;
    for(map<ll,ll>::iterator it=mapa.begin();it!=mapa.end();){

        t=it->ff;
        s=it->ss;

        br++;

        ll pom=nadji(root,t);
        if(pom!=curr){
            printf("%lld %lld | %lld %d %d\n",pom,curr,t,br,tip2c);
            return false;
        }

        it++;

        if(it==mapa.end())break;
        curr=curr+(it->ff-t)*s;
    }

    return true;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    st=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(st==0)st=t;
            ///if(sq==100000 && st==940132043)if(mapa.find(t)!=mapa.end())continue;
            ins(t,s);

           /* if(sq==100000 && st==940132043){\
                int csap=100000;
                ispis(root,csap);
                if(!check())break;
            }

            if(sq==100000 && st==940132043)printf("PROSAO\n");*/

            mapa[t]=s;
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            ///if(sq==100000 && st==940132043)continue;
            del(t);

            tip2c++;
            mapa.erase(t);
        }
        else{
            int l,r,v;
            tcnt++;
            scanf("%d %d %d",&l,&r,&v);
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            if(sq==100000 && st==940132043){

             if(tcnt==2846){
                jeste=1;

                check();

                printf("NASAO\n");
                cout<<fixed;
                cout<<setprecision(6);
                cout<<query(l,r,v)<<endl;
             }
            }
            else{
                cout<<fixed;
                cout<<setprecision(6);
                cout<<query(l,r,v)<<endl;
            }
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#define int long long
#define pii pair<int, int>
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define endl "\n"
//#pragma GCC optimize ("O3")

using namespace std;

const int N = 1e6 + 10;
const int inf = 2e18;
const int mod = 1e9 + 7;
const int eps = 1e-9;
const char spc = 29;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

struct node {
	int key = 0;
	int prir = rnd();
	int speed = 0;
	int mxt = -inf;
	int mnt = inf;
	int mxtspeed = 0;
	int res = 0;
	int mn = 0;
	int l = -1, r = -1;
};

node t[N];
int top = 0;
int rt = -1;

void upd(int nd)
{
	if (nd == -1)
		return;

	node l;
	node r;

	if (t[nd].l != -1)
		l = t[t[nd].l];

	if (t[nd].r != -1)
		r = t[t[nd].r];

	t[nd].mxt = max(t[nd].key, r.mxt);
	t[nd].mnt = min(t[nd].key, l.mnt);

	if (r.mxt > t[nd].key)
		t[nd].mxtspeed = r.mxtspeed;
	else
		t[nd].mxtspeed = t[nd].speed;

	t[nd].res = l.res + r.res;

	if (l.mxt != -inf)
		t[nd].res += (t[nd].key - l.mxt) * l.mxtspeed;

	if (r.mnt != inf)
		t[nd].res += (r.mnt - t[nd].key) * t[nd].speed;

	t[nd].mn = min(l.mn, r.mn);

	if (l.mxt != -inf)
		t[nd].mn = min(t[nd].mn, l.res + (t[nd].key - l.mxt) * l.mxtspeed);

	if (r.mnt != inf)
		t[nd].mn = min(t[nd].mn, t[nd].res - r.res);
}

int merge(int l, int r)
{
	if (l == -1) return r;
	if (r == -1) return l;

	if (t[l].prir > t[r].prir)
	{
		t[l].r = merge(t[l].r, r);
		upd(l);
		return l;
	}
	else
	{
		t[r].l = merge(l, t[r].l);
		upd(r);
		return r;
	}
}

pii split(int nd, int key)
{
	if (nd == -1)
		return make_pair(-1, -1);

	if (t[nd].key <= key)
	{
		pii p = split(t[nd].r, key);

		t[nd].r = p.x;
		upd(nd);

		return make_pair(nd, p.y);
	}
	else
	{
		pii p = split(t[nd].l, key);

		t[nd].l = p.y;
		upd(nd);

		return make_pair(p.x, nd);
	}
}

void init(node &nd, int key, int speed)
{
	nd.key = key;
	nd.prir = rnd();
	nd.speed = speed;
	nd.mxt = key;
	nd.mnt = key;
	nd.mxtspeed = speed;
	nd.l = -1;
	nd.r = -1;
	nd.res = 0;
	nd.mn = 0;
}

void add(int pos, int val)
{
	init(t[top], pos, val);

	pii p = split(rt, pos);

	rt = merge(merge(p.x, top), p.y);

	++top;
}

void del(int pos)
{
	pii p1 = split(rt, pos);
	pii p2 = split(p1.x, pos - 1);

	rt = merge(p2.x, p1.y);
}

double rec(int nd, int have)
{
	if (nd == -1)
		return -1;

	if (t[nd].mn + have > 0)
		return -1;

	double res = rec(t[nd].l, have);

	if (res > -0.5)
		return res;

	if (t[nd].l != -1)
		have += t[t[nd].l].res;

	if (t[nd].l != -1)
	{
		if (have + (t[nd].key - t[t[nd].l].mxt) * t[t[nd].l].mxtspeed <= 0)
			return (double)t[t[nd].l].mxt + abs((double)have / t[t[nd].l].mxtspeed);

		have += (t[nd].key - t[t[nd].l].mxt) * t[t[nd].l].mxtspeed;
	}

	if (t[nd].r != -1)
	{
		if (have + t[nd].speed * (t[t[nd].r].mnt - t[nd].key) <= 0)
			return (double)t[nd].key + abs((double)have / t[nd].speed);

		have += t[nd].speed * (t[t[nd].r].mnt - t[nd].key);
	}

	return rec(t[nd].r, have);
}

double get(int l, int r, int have)
{
	pii p1 = split(rt, l - 1);
	pii p2 = split(p1.y, r);
	int seg = p2.x;

	int cur = have;

	if (have == 0)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return l;
	}

	if (seg == -1)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return -1;
	}

	double res = rec(seg, cur);

	if (res > -0.5)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return res;
	}

	if (t[seg].mxt == -inf)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return -1;
	}

	cur += t[seg].res;

	int add = (r - t[seg].mxt) * t[seg].mxtspeed;

	if (cur + add <= 0)
	{
		double res = (double)t[seg].mxt + abs((double)cur / (double)t[seg].mxtspeed);
		rt = merge(p1.x, merge(p2.x, p2.y));

		return res;
	}

	rt = merge(p1.x, merge(p2.x, p2.y));
	return -1;
}

int q;

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cout.precision(30);

	cin >> q;

	while (q--)
	{
		int tp;

		cin >> tp;

		if (tp == 1)
		{
			int tm, speed;

			cin >> tm >> speed;

			add(tm, speed);
		}
		else if (tp == 2)
		{
			int tm;

			cin >> tm;

			del(tm);
		}
		else
		{
			int l, r, have;

			cin >> l >> r >> have;

			cout << get(l, r, have) << endl;
		}
	}
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y0998244353
#define y1 y1998244353
#define die(cond) if (cond) for (;;) {}
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acosl(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct vertex {
	ll time, speed;
	ll tl, tr, speedR;
	ll res = 0, minn = 0;
	ll l = -1, r = -1;
	ll prior = rand();
	ll par = -1;
};
struct treap {
	vector<vertex> t;
	treap() {}
	ll newv(ll t_, ll s_) {
		vertex v;
		v.time = t_, v.speed = s_;
		t.pb(v);
		upd(sz(t) - 1);
		return sz(t) - 1;
	}
	void setpar(ll v, ll p) {
		if (v == -1) {
			return;
		}
		t[v].par = p;
	}
	void $upd(ll v) {
		if (v == -1) {
			return;
		}
		ll& time = t[v].time;
		ll& speed = t[v].speed;
		ll& res = t[v].res;
		ll& minn = t[v].minn;
		ll l = t[v].l, r = t[v].r;
		res = 0, minn = 0;
		if (l != -1) {
			mineq(minn, t[l].minn);
			res += t[l].res;
			res += t[l].speedR * (time - t[l].tr);
			mineq(minn, res);
			t[v].tl = t[l].tl;
		} else {
			t[v].tl = time;
		}
		if (r != -1) {
			res += speed * (t[r].tl - time);
			mineq(minn, res + t[r].minn);
			res += t[r].res;
			mineq(minn, res);
			t[v].tr = t[r].tr;
			t[v].speedR = t[r].speedR;
		} else {
			t[v].tr = time;
			t[v].speedR = speed;
		}
	}
	void upd(ll v) {
		if (v == -1) {
			return;
		}
		$upd(v);
		setpar(t[v].l, v);
		setpar(t[v].r, v);
	}
	void rotate(ll v) {
		ll p = t[v].par;
		ll gp = t[p].par;
		if (gp != -1) {
			if (t[gp].l == p) {
				t[gp].l = v;
			} else {
				t[gp].r = v;
			}
		}
		if (t[p].l == v) {
			t[p].l = t[v].r;
			t[v].r = p;
		} else {
			t[p].r = t[v].l;
			t[v].l = p;
		}
		t[v].par = gp;
		upd(v), upd(p), upd(gp);
	}
	ll splay(ll v) {
		if (v == -1) {
			return -1;
		}
		while (t[v].par != -1) {
			rotate(v);
		}
		return v;
	}
	ll find(ll v, ll k) {
		if (v == -1) {
			return -1;
		}
		if (t[v].time == k) {
			return splay(v);
		}
		if (t[v].time > k && t[v].l != -1) {
			return find(t[v].l, k);
		}
		if (t[v].time < k && t[v].r != -1) {
			return find(t[v].r, k);
		}
		return splay(v);
	}
	pll split(ll v, ll k) {
		if (v == -1) {
			return { -1, -1 };
		}
		v = find(v, k);
		if (t[v].time < k) {
			ll r = t[v].r;
			t[v].r = -1;
			setpar(r, -1);
			upd(v);
			return { v, r };
		} else {
			ll l = t[v].l;
			t[v].l = -1;
			setpar(l, -1);
			upd(v);
			return { l, v };
		}
		//pll p;
		//if (t[v].time < k) {
		//	p = split(t[v].r, k);
		//	t[v].r = p.ft;
		//	p.ft = v;
		//} else {
		//	p = split(t[v].l, k);
		//	t[v].l = p.sd;
		//	p.sd = v;
		//}
		//upd(v);
		//return p;
	}
	ll merge(ll f, ll s) {
		if (f == -1) {
			return s;
		}
		if (s == -1) {
			return f;
		}
		s = find(s, t[f].time);
		t[s].l = f;
		upd(s);
		return s;
		/*if (t[f].prior > t[s].prior) {
			t[f].r = merge(t[f].r, s);
			upd(f);
			return f;
		} else {
			t[s].l = merge(f, t[s].l);
			upd(s);
			return s;
		}*/
	}
	ll add(ll root, ll t_, ll s) {
		ll a, b;
		tie(a, b) = split(root, t_);
		ll v = newv(t_, s);
		t[v].l = a, t[v].r = b;
		upd(v);
		return v;
	}
	ll del(ll root, ll t_) {
		ll a, b, c;
		tie(a, b) = split(root, t_);
		tie(b, c) = split(b, t_ + 1);
		root = merge(a, c);
		return root;
	}
	ld down(ll v, ll V, ll R) {
		if (v == -1) {
			return -1;
		}
		ll lres = 0;
		if (t[v].l != -1) {
			ll minn = t[t[v].l].minn;
			lres += t[t[v].l].res + t[t[v].l].speedR * (t[v].time - t[t[v].l].tr);
			mineq(minn, lres);
			if (V + minn <= 0) {
				return down(t[v].l, V, t[v].time);
			}
		}
		V += lres;
		ll tr = R;
		if (t[v].r != -1) {
			tr = t[t[v].r].tl;
		}
		if (V + t[v].speed * (tr - t[v].time) <= 0) {
			ld ans = t[v].time - ld(V) / ld(t[v].speed);
			return ans;
		}
		if (t[v].r != -1) {
			V += t[v].speed * (t[t[v].r].tl - t[v].time);
			return down(t[v].r, V, R);
		}
		return -1;
	}
	ld getans(ll root, ll l, ll r, ll v) {
		if (v == 0) {
			return l;
		}
		ll a, b, c;
		tie(a, b) = split(root, l);
		tie(b, c) = split(b, r + 1);
		ld ans = down(b, v, r);
		root = merge(merge(a, b), c);
		return ans;
	}
};

ll q;
treap tr;

inline void solve() {
	cout << setprecision(7) << fixed;
	ll root = -1;
	for (ll i = 0; i < q; i++) {
		ll t;
		cin >> t;
		if (t == 1) {
			ll time, s;
			cin >> time >> s;
			root = tr.add(root, time, s);
		} else if (t == 2) {
			ll time;
			cin >> time;
			root = tr.del(root, time);
		} else if (t == 3) {
			ll l, r, v;
			cin >> l >> r >> v;
			ld ans = tr.getans(root, l, r, v);
			cout << ans << endl;
		}
	}
}

inline void read() {
	cin >> q;
}

#include <bits/stdc++.h>
#define watch(x) std::cout << "$ LINE @" << __LINE__ << " FUNC @" << __FUNCTION__ << "\n$ " \
                           << (#x) << ": " << x << std::endl

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

template <typename Tp>
inline void read(Tp &x)
{
    static char c;
    static bool neg;
    x = 0, c = getchar(), neg = false;
    for (; !isdigit(c); c = getchar())
    {
        if (c == '-')
        {
            neg = true;
        }
    }
    for (; isdigit(c); c = getchar())
    {
        x = x * 10 + c - '0';
    }
    if (neg)
    {
        x = -x;
    }
}

typedef pair<double, ll> pdl;

const int INF = 1e9 + 5;
const int N = 1e5 + 5;

int q;

namespace Seg
{
#define lson son[0]
#define rson son[1]

    struct Node
    {
        Node *son[2];
        bool flag;
        int set;
        ll sum, lsum;
        inline void pushUp();
        inline void pushDown(int, int);
        inline void setVal(int);
        inline void ensureLeft();
        inline void ensureRight();
        inline void ensureBoth();
    };

    inline Node *newNode()
    {
        Node *res = new Node();
        res->son[0] = res->son[1] = nullptr;
        res->flag = false;
        res->set = 0;
        res->sum = res->lsum = 0LL;
        return res;
    }
    inline void Node::pushUp()
    {
        ensureBoth();
        sum = lson->sum + rson->sum;
        lsum = std::min(lson->lsum, lson->sum + rson->lsum);
    }
    inline void Node::pushDown(int l, int r)
    {
        if (flag)
        {
            int mid = (l + r) >> 1;
            ensureBoth();
            lson->flag = rson->flag = true;
            lson->set = rson->set = set;
            lson->sum = (ll)(mid - l + 1) * set;
            lson->lsum = set >= 0 ? 0 : lson->sum;
            rson->sum = (ll)(r - mid) * set;
            rson->lsum = set >= 0 ? 0 : rson->sum;
            flag = false;
        }
    }
    inline void Node::ensureLeft()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
    }
    inline void Node::ensureRight()
    {
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    inline void Node::ensureBoth()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    void update(Node *u, int l, int r, int ul, int ur, int x)
    {
        if (ul <= l && r <= ur)
        {
            u->flag = true;
            u->set = x;
            u->sum = (ll)(r - l + 1) * x;
            u->lsum = x >= 0 ? 0 : u->sum;
            return;
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        if (ul <= mid)
        {
            u->ensureLeft();
            update(u->lson, l, mid, ul, ur, x);
        }
        if (mid < ur)
        {
            u->ensureRight();
            update(u->rson, mid + 1, r, ul, ur, x);
        }
        u->pushUp();
    }
    pdl query(Node *u, int l, int r, int ql, int qr, ll x)
    {
        if (ql <= l && r <= qr)
        {
            if (u->lsum + x > 0)
            {
                return (pdl){-1.0, u->sum};
            }
            if (l == r)
            {
                return (pdl){(double)l - (double)x / (double)u->sum, u->sum};
            }
            if (u->flag)
            {
                return (pdl){(double)l - (double)x / (u->sum / (ll)(r - l + 1)), u->sum};
            }
            int mid = (l + r) >> 1;
            u->ensureBoth();
            pdl res = query(u->lson, l, mid, ql, qr, x);
            if (res.first > 0)
            {
                return res;
            }
            else
            {
                pdl pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
                return (pdl){pir.second, res.second + pir.second};
            }
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        pdl res = (pdl){-1.0, 0}, pir;
        if (ql <= mid)
        {
            u->ensureLeft();
            res = query(u->lson, l, mid, ql, qr, x);
        }
        if (mid < qr)
        {
            if (res.first > 0)
            {
                return res;
            }
            u->ensureRight();
            pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
            res = (pdl){pir.first, res.second + pir.second};
        }
        return res;
    }

#undef lson
#undef rson
} // namespace Seg

int main()
{
    read(q);
    map<int, int> timeline;
    int L = 1, R = INF;
    timeline[L - 1] = timeline[R + 1] = 0;
    auto root = Seg::newNode();
    for (int i = 0, op, x, y, z; i < q; ++i)
    {
        read(op);
        if (op == 1)
        {
            read(x), read(y);
            timeline[x] = y;
            Seg::update(root, L, R - 1, x, std::min(next(timeline.find(x))->first, R) - 1, y);
        }
        else if (op == 2)
        {
            read(x);
            auto iter = timeline.find(x);
            Seg::update(root, L, R - 1, x, std::min(next(iter)->first, R) - 1, prev(iter)->second);
            timeline.erase(iter);
        }
        else
        {
            read(x), read(y), read(z);
            if (z == 0)
            {
                printf("%d\n", x);
            }
            else
            {
                x = timeline.lower_bound(x)->first;
                if (x >= y)
                {
                    puts("-1");
                }
                else
                {
                    auto ans = Seg::query(root, L, R - 1, x, y - 1, z);
                    if (ans.first < 0)
                    {
                        puts("-1");
                    }
                    else
                    {
                        printf("%.8f\n", ans.first);
                    }
                }
            }
        }
    }
}

#include <sstream>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
#include <cassert>
#include <bitset>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)

#define DEBUG
#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define deputs(str) fprintf(stderr, "%s\n",str)
#else
#define debug(...)
#define deputs(str)
#endif // DEBUG
typedef unsigned long long ULL;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long long LL;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e5+107;
const double pi=acos(-1.0);
const double eps=0.0000000001;
LL gcd(LL a, LL b) {return b?gcd(b,a%b):a;}
template<typename T>inline void pr2(T x,int k=64) {ll i; REP(i,k) debug("%d",(x>>i)&1); putchar(' ');}
template<typename T>inline void add_(T &A,int B,ll MOD=M) {A+=B; (A>=MOD) &&(A-=MOD);}
template<typename T>inline void mul_(T &A,ll B,ll MOD=M) {A=(A*B)%MOD;}
template<typename T>inline void mod_(T &A,ll MOD=M) {A%=MOD; A+=MOD; A%=MOD;}
template<typename T>inline void max_(T &A,T B) {(A<B) &&(A=B);}
template<typename T>inline void min_(T &A,T B) {(A>B) &&(A=B);}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a, T b) {
	T ret=1;
	for (; b; b>>=1ll,a=(LL)a*a%M)
		if (b&1) ret=(LL)ret*a%M;
	return ret;
}
int startTime;
void startTimer() {startTime=clock();}
void printTimer() {debug("/--- Time: %ld milliseconds ---/\n",clock()-startTime);}

struct node {
	int l,r;
	int lpos,rm,value;//rm:maxi
	ll maxused,used;//lpos+(v-used)/value
	node():lpos(0),rm(0),value(0),maxused(0),used(0) {l=r=0;};
} T[maxn*50]; int tot;
void merge(node &ret,node A,node B) {//避免l,r被改
	if (!A.lpos) {
		ret.lpos=B.lpos; ret.rm=B.rm;
		ret.value=B.value;
		ret.maxused=B.maxused; ret.used=B.used;
		return;
	} if (!B.lpos) {
		ret.lpos=A.lpos; ret.rm=A.rm;
		ret.value=A.value;
		ret.maxused=A.maxused; ret.used=A.used;
		return;
	} ret.maxused=max(A.maxused,A.used+(ll)(B.rm-A.lpos)*A.value+B.maxused);
	ret.lpos=B.lpos; ret.value=B.value; ret.rm=A.rm;
	ret.used=A.used+(ll)(B.rm-A.lpos)*A.value+B.used;
} int root;
int op,t,s,l,r,v;
void update(int &x,int L,int R) {//starttime
	if (!x) x=++tot;
	if (L==R) {//lpos:start_time(position)
		if (op==1) T[x].lpos=T[x].rm=t,T[x].value=s;
		else T[x].lpos=T[x].rm=0,T[x].value=0;
		return;
	} int mid=(L+R)/2;
	if (t<=mid) update(T[x].l,L,mid);
	else update(T[x].r,mid+1,R);
	merge(T[x],T[T[x].l],T[T[x].r]);
	// printf("update : %d %d   %d %d %lld %lld _l=%d %d; used=%lld\n"
	// 	,L,R,T[x].lpos,T[x].value,T[x].maxused,T[x].used,T[T[x].l].lpos,T[T[x].r].lpos,T[T[x].l].used);
} double ans;
node now;
void query(int x,int L,int R) {//(l,R]时间段内
	if (ans>=0) return;
	if (l<=L&&R<=r) {
		if (x) {
			if (now.used+(ll)(T[x].rm-now.lpos)*now.value>=v) { //merge_R
				if (now.value<=0) ans=now.lpos;
				else ans=now.lpos+1.*(v-now.used)/now.value;
				return;
			}
			node tmp;
			merge(tmp,now,T[x]);
			// printf("check: (%d-%d) now=%d %d %lld %lld; chk=%lld: v=%d\n",
			//        L,R,tmp.lpos,tmp.value,tmp.maxused,tmp.used,tmp.used+(ll)(R-tmp.lpos)*tmp.value,v);
			if (tmp.maxused>=v) {//not
				// printf("query: %d %d: okay\n",L,R);
				int mid=(L+R)/2;
				query(T[x].l,L,mid);
				query(T[x].r,mid+1,R);
				if (ans>=0) return;
				puts("-100");
			} else {
				now=tmp;
			}
		}
		if (now.used+(ll)(R-now.lpos)*now.value>=v) { //last=R
			if (now.value<=0) ans=now.lpos;
			else ans=now.lpos+1.*(v-now.used)/now.value;
		} return;
	} int mid=(L+R)/2;
	if (l<=mid) query(T[x].l,L,mid);
	if (mid<r) query(T[x].r,mid+1,R);
}
int main() {
	int q,i;
	scanf("%d",&q);
	FOR(i,1,q) {
		scanf("%d",&op);
		if (op==1) {
			scanf("%d%d",&t,&s); s=-s;
			update(root,1,1000000000);
		} else if (op==2) {
			scanf("%d",&t);
			update(root,1,1000000000);
		} else {
			scanf("%d%d%d",&l,&r,&v);
			ans=-1; now=node(); now.lpos=l;
			query(root,1,1000000000);
			if (ans>r) puts("-10000");
			// printf("query %d %d %lld %lld\n",now.lpos,now.value,now.maxused,now.used);
			printf("%.10f\n",ans);
		}
		// now=T[1];
		// printf("_i: %d %d %lld %lld\n",now.lpos,now.value,now.maxused,now.used);
	}

}
/*
10
1 1 1000000000
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 500 1000000000
1 322 1000000000
1 500000000 -1000000000
3 1 1000000000 1
3 1 1000000000 1000000000
3 100 1000000000 1
*/

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

class node {
 public:
  node* l;
  node* r;
  node* p;
  int time, ltime, rtime, speed, rspeed;
  long long sum, lsum;

  node(int time, int speed): time(time), speed(speed) {
    l = r = p = NULL;
    ltime = rtime = time;
    rspeed = speed;
    sum = lsum = 0;
  }

  void pull() {
    ltime = rtime = time;
    rspeed = speed;
    sum = lsum = 0;
    if (l != NULL) {
      l->p = this;
      ltime = l->ltime;
      lsum = min(lsum, sum + l->lsum);
      sum += l->sum + (long long) l->rspeed * (time - l->rtime);
    }
    if (r != NULL) {
      r->p = this;
      rtime = r->rtime;
      rspeed = r->rspeed;
      sum += (long long) speed * (r->ltime - time);
      lsum = min(lsum, sum + r->lsum);
      sum += r->sum;
    }
  }
};

void rotate(node* v) {
  node* u = v->p;
  v->p = u->p;
  if (v->p != NULL) {
    if (v->p->l == u) {
      v->p->l = v;
    }
    if (v->p->r == u) {
      v->p->r = v;
    }
  }
  if (v == u->l) {
    u->l = v->r;
    v->r = u;
  } else {
    u->r = v->l;
    v->l = u;
  }
  u->pull();
  v->pull();
}

void splay(node* v, node* aim = NULL) {
  while (v->p != aim) {
    node* u = v->p;
    if (u->p != aim) {
      if ((u->l == v) ^ (u->p->l == u)) {
        rotate(v);
      } else {
        rotate(u);
      }
    }
    rotate(v);
  }
}

node* insert(node* v, node* u) {
  while (true) {
    if (u->time > v->time) {
      if (v->r == NULL) {
        v->r = u;
        u->p = v;
        break;
      } else {
        v = v->r;
      }
    } else {
      if (v->l == NULL) {
        v->l = u;
        u->p = v;
        break;
      } else {
        v = v->l;
      }
    }
  }
  splay(u);
  return u;
}

node* find(node* v, int time) {
  while (true) {
    if (time == v->time) {
      break;
    } else if (time > v->time) {
      v = v->r;
    } else {
      v = v->l;
    }
  }
  splay(v);
  return v;
}

node* find_less(node* v, int time) {
  node* res = NULL;
  node* from = NULL;
  while (v != NULL) {
    from = v;
    if (v->time < time) {
      res = v;
      v = v->r;
    } else {
      v = v->l;
    }
  }
  splay(from);
  splay(res);
  return res;
}

node* find_greater(node* v, int time) {
  node* res = NULL;
  node* from = NULL;
  while (v != NULL) {
    from = v;
    if (v->time > time) {
      res = v;
      v = v->l;
    } else {
      v = v->r;
    }
  }
  splay(from);
  splay(res);
  return res;
}

node* get_rightmost(node* v) {
  while (v->r != NULL) {
    v = v->r;
  }
  splay(v);
  return v;
}

node* merge(node* v, node* u) {
  v = get_rightmost(v);
  splay(u);
  v->r = u;
  v->pull();
  return v;
}

node* erase(node* v) {
  splay(v);
  v->l->p = v->r->p = NULL;
  return merge(v->l, v->r);
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
  node* lmost = new node(0, 0);
  node* rmost = new node(inf, 0);
  lmost->r = rmost;
  lmost->pull();
  node* root = lmost;
  int tt;
  cin >> tt;
  while (tt--) {
    int type;
    cin >> type;
    if (type == 1) {
      int time, speed;
      cin >> time >> speed;
      root = insert(root, new node(time, speed));
    } else if (type == 2) {
      int time;
      cin >> time;
      root = erase(find(root, time));
    } else {
      int l, r;
      long long x;
      cin >> l >> r >> x;
      if (!x) {
        cout << l << "\n";
        continue;
      }
      root = find_less(root, l);
      node* left = root;
      root = find_greater(root, r);
      node* right = root;
      splay(left, right);
      node* v = left->r;
      if (v == NULL) {
        cout << -1 << "\n";
      } else {
        if (x + v->lsum <= 0) {
          while (true) {
            if (v->l != NULL) {
              if (x + v->l->lsum <= 0) {
                v = v->l;
              } else {
                x += v->l->sum;
                if (x + (long long) v->l->rspeed * (v->time - v->l->rtime) <= 0) {
                  cout << v->l->rtime - (double) x / v->l->rspeed << "\n";
                  break;
                } else {
                  x += (long long) v->l->rspeed * (v->time - v->l->rtime);
                  if (x + (long long) v->speed * (v->r->ltime - v->time) <= 0) {
                    cout << v->time - (double) x / v->speed << "\n";
                    break;
                  } else {
                    x += (long long) v->speed * (v->r->ltime - v->time);
                    v = v->r;
                  }
                }
              }
            } else {
              if (x + (long long) v->speed * (v->r->ltime - v->time) <= 0) {
                cout << v->time - (double) x / v->speed << "\n";
                break;
              } else {
                x += (long long) v->speed * (v->r->ltime - v->time);
                v = v->r;
              }
            }
          }
          splay(v);
          root = v;
        } else if (x + v->sum + (long long) v->rspeed * (r - v->rtime) <= 0) {
          cout << v->rtime - (double) (x + v->sum) / v->rspeed << "\n";
        } else {
          cout << -1 << "\n";
        }
      }
    }
  }
  return 0;
}

//时间节点离散化，用线段树维护时间区间上的二次函数，最终线段树上应当存了一些互不相交的函数区间。
//修改操作：modify 更改一段区间上的二次函数，如果破坏了原有的函数区间，需要将原有的函数pushdown
//修改操作：cover 直接重置一段区间上的二次函数，不管有没有原有的函数
//查询操作：query 应当先查询左子树，再查询右子树。一旦有了答案就停止查询。对于每个线段树区间维护增量的min和sum，查询完左子树之后要加上sum。如果min值带入计算仍大于等于0则提前返回。如果当前到达的区间是一个整块的函数区间，无论是否完全被查询区间包含，都只在当前区间查询并且停止递归

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int maxt=(1<<18)+10;
int n;
ll datk[maxt],datb[maxt],sum[maxt],mn[maxt];
int id[maxt];
int read_tl[maxn],read_tr[maxn],read_tval[maxn],cal_tl[maxn],cal_tr[maxn],tp[maxn],covr[maxn];
vector<int> lsh;
map<int,int> ttoi;
set<int> st;
set<int>::iterator it;
int pred,curd;
double ans;
ll preval;
void modify(int x,int l,int r,int tl,int tr,ll k,ll b,int ii)
{
	if(l>tr||r<tl)return;
	if(tl<=l&&r<=tr){id[x]=ii;datk[x]=k;datb[x]=b;sum[x]=k*(lsh[r]-lsh[l]+1);mn[x]=min(0ll,sum[x]);return;}
	id[x]=-1;datk[x]=datb[x]=0;
	int mid=(l+r)/2;modify(x*2,l,mid,tl,tr,k,b,ii);modify(x*2+1,mid+1,r,tl,tr,k,b,ii);
	sum[x]=sum[x*2]+sum[x*2+1];
	mn[x]=min(mn[x*2],sum[x*2]+mn[x*2+1]);
}
void query(int x,int l,int r,int tl,int tr)
{
	if(l>tr||r<tl||!(ans<0))return;
	if(tl<=l&&r<=tr)
	{
		if(preval+mn[x]>0){preval+=sum[x];return;}
		if(id[x]==-1)
		{if(l==r)return;int mid=(l+r)/2;if(mn[x*2]+preval<=0){query(x*2,l,mid,tl,tr);return;}else{preval+=sum[x*2];query(x*2+1,mid+1,r,tl,tr);return;}}
		else//preval+kx+b=0
		{
			double pos=1.0*(-preval)/datk[x]+lsh[l]-1;
			if((lsh[l]-1.0)<=pos&&pos<=1.0*lsh[r]&&lsh[tl]*1.0<=pos){ans=pos;return;}
		}
		preval+=sum[x];return;
	}
	else
	{
		if(id[x]==-1)
		{int mid=(l+r)/2;query(x*2,l,mid,tl,tr);if(!(ans<0))return;query(x*2+1,mid+1,r,tl,tr);return;}
		else
		{
			if(tl>=cal_tl[id[x]])return;
			double pos=1.0*(-preval)/datk[x]+lsh[l]-1;
			if((lsh[l]-1.0)<=pos&&pos<=1.0*lsh[r]&&lsh[tl]*1.0<=pos){ans=pos;return;}
		}
		preval+=sum[x];return;
	}
}
int main()
{
	int q;scanf("%d",&q);for(int i=0;i<q;i++){scanf("%d",&tp[i]);if(tp[i]==1){scanf("%d%d",&read_tl[i],&read_tval[i]);lsh.push_back(read_tl[i]);lsh.push_back(read_tl[i]+1);}else if(tp[i]==2){scanf("%d",&read_tl[i]);}else{scanf("%d%d%d",&read_tl[i],&read_tr[i],&read_tval[i]);lsh.push_back(read_tl[i]);lsh.push_back(read_tr[i]);}}

	sort(lsh.begin(),lsh.end());lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end());n=lsh.size();
	modify(1,0,n-1,0,n-1,0,0,-1);memset(id,-1,sizeof(id));
	for(int i=0;i<q;i++)
	{
		if(tp[i]==1)
		{
	cal_tl[i]=lower_bound(lsh.begin(),lsh.end(),read_tl[i]+1)-lsh.begin();it=st.lower_bound(read_tl[i]);covr[i]=(it==st.end()?n:cal_tl[ttoi[*it]])-1;modify(1,0,n-1,cal_tl[i],covr[i],read_tval[i],-read_tval[i]*1ll*read_tl[i],i);if(it!=st.begin()){--it;pred=ttoi[*it];covr[pred]=cal_tl[i]-1;modify(1,0,n-1,cal_tl[pred],covr[pred],read_tval[pred],-read_tval[pred]*1ll*read_tl[pred],pred);}st.insert(read_tl[i]);ttoi[read_tl[i]]=i;}

		else if(tp[i]==2)
		{
	it=st.lower_bound(read_tl[i]);curd=ttoi[read_tl[i]];if(it!=st.begin()){--it;pred=ttoi[*it];covr[pred]=covr[curd];modify(1,0,n-1,cal_tl[pred],covr[pred],read_tval[pred],-read_tval[pred]*1ll*read_tl[pred],pred);}else{modify(1,0,n-1,0,covr[curd],0,0,-1);}st.erase(read_tl[i]);
}
		else{cal_tl[i]=lower_bound(lsh.begin(),lsh.end(),read_tl[i])-lsh.begin();cal_tr[i]=lower_bound(lsh.begin(),lsh.end(),read_tr[i])-lsh.begin();ans=-1;preval=read_tval[i];query(1,0,n-1,cal_tl[i],cal_tr[i]);printf("%.10lf\n",ans);}
	}
	return 0;
}

#include <map>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define Maxn 200000
#define Inf 1000000001
struct Segment_Node{
	int left,right;
	int lc,rc;
	ll lsum,sum;
	bool lazy;
	int v;
}seg[Maxn*20+5];
int root,id_tot;
int new_node(int left,int right){
	seg[++id_tot].lazy=0;
	seg[id_tot].v=0;
	seg[id_tot].left=left;
	seg[id_tot].right=right;
	seg[id_tot].lc=seg[id_tot].rc=0;
	seg[id_tot].lsum=seg[id_tot].sum=0;
	return id_tot;
}
ll mn(ll a,ll b){
	return a<b?a:b;
}
void push_up(int root){
	seg[root].sum=seg[seg[root].lc].sum+seg[seg[root].rc].sum;
	seg[root].lsum=mn(seg[seg[root].lc].lsum,seg[seg[root].lc].sum+seg[seg[root].rc].lsum);
}
void update_node(int root,int v){
	seg[root].sum=1ll*(seg[root].right-seg[root].left+1)*v;
	seg[root].lsum=mn(0,seg[root].sum);
	seg[root].lazy=1;
	seg[root].v=v;
}
void push_down(int root){
	if(seg[root].lazy){
		int mid=(seg[root].left+seg[root].right)>>1;
		if(!seg[root].lc){
			seg[root].lc=new_node(seg[root].left,mid);
		}
		if(!seg[root].rc){
			seg[root].rc=new_node(mid+1,seg[root].right);
		}
		update_node(seg[root].lc,seg[root].v);
		update_node(seg[root].rc,seg[root].v);
		seg[root].lazy=0;
	}
}
void update(int root,int left,int right,int v){
	if(seg[root].left==left&&seg[root].right==right){
		update_node(root,v);
		return;
	}
	push_down(root);
	int mid=(seg[root].left+seg[root].right)>>1;
	if(left<=mid){
		if(!seg[root].lc){
			seg[root].lc=new_node(seg[root].left,mid);
		}
		if(right<=mid){
			update(seg[root].lc,left,right,v);
		}
		else{
			update(seg[root].lc,left,mid,v);
		}
	}
	if(right>=mid+1){
		if(!seg[root].rc){
			seg[root].rc=new_node(mid+1,seg[root].right);
		}
		if(left>=mid+1){
			update(seg[root].rc,left,right,v);
		}
		else{
			update(seg[root].rc,mid+1,right,v);
		}
	}
	push_up(root);
}
pair<ll,ll> query(int root,int left,int right){
	if(seg[root].left==left&&seg[root].right==right){
		return make_pair(seg[root].sum,seg[root].lsum);
	}
	push_down(root);
	int mid=(seg[root].left+seg[root].right)>>1;
	if(left<=mid){
		if(!seg[root].lc){
			seg[root].lc=new_node(seg[root].left,mid);
		}
		if(right<=mid){
			return query(seg[root].lc,left,right);
		}
	}
	if(right>=mid+1){
		if(!seg[root].rc){
			seg[root].rc=new_node(mid+1,seg[root].right);
		}
		if(left>=mid+1){
			return query(seg[root].rc,left,right);
		}
	}
	pair<ll,ll> l=query(seg[root].lc,left,mid),r=query(seg[root].rc,mid+1,right);
	return make_pair(l.first+r.first,mn(l.second,l.first+r.second));
}
map<int,int> mp;
int main(){
	seg[0].sum=seg[0].lsum=0;
	root=new_node(1,Inf);
	int q;
	scanf("%d",&q);
	int op,l,r,v;
	mp[0]=mp[Inf+1]=0;
	map<int,int>::iterator it_1,it_2;
	int left,right,mid;
	ll sum;
	while(q--){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d",&l,&v);
			l++;
			mp[l]=v;
			it_1=mp.find(l);
			it_1++;
			update(1,l,(it_1->first)-1,v);
		}
		else if(op==2){
			scanf("%d",&l);
			l++;
			it_1=mp.find(l);
			it_2=it_1;
			it_1--;
			it_2++;
			mp.erase(l);
			update(1,l,(it_2->first)-1,(it_1->second));
		}
		else{
			scanf("%d%d%d",&l,&r,&v);
			if(v==0){
				printf("%d\n",l);
				continue;
			}
			it_1=mp.lower_bound(l);
			l=it_1->first;
			if(l>=r){
				puts("-1");
				continue;
			}
			left=l,right=r;
			while(left<right){
				mid=(left+right)>>1;
				if(query(1,l,mid).second+v<=0){
					right=mid;
				}
				else{
					left=mid+1;
				}
			}
			if((sum=query(1,l,left).second)+v>0){
				puts("-1");
				continue;
			}
			it_2=mp.upper_bound(left);
			it_2--;
			printf("%.7lf\n",left-(sum+v)*1.0/(it_2->second));
		}
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
vector <int> tree;
vector <int> upd;
void push(int v, int l, int r)
{
	tree[v * 2] += upd[v];
	tree[v * 2 + 1] += upd[v];
	upd[v * 2] += upd[v];
	upd[v * 2 + 1] += upd[v];
	upd[v] = 0;
}
void update(int v, int l, int r, int al, int ar, int val)
{
	if(l >= al && r <= ar)
	{
		tree[v] += val;
		upd[v] += val;
	}
	else if(l  <= ar && r >= al)
	{
		push(v, l, r);
		update(v * 2, l, (r + l) / 2, al, ar, val);
		update(v * 2 + 1, (r + l) / 2 + 1, r, al, ar, val);
		tree[v] = min(tree[v * 2], tree[v * 2 + 1]);
	}
}
int ans(int v, int l, int r, int ind)
{
	if(l == r)
	{
		return tree[v];
	}
	else if(ind <= (r + l) / 2)
	{
		push(v, l, r);
		return ans(v * 2, l, (r + l) / 2, ind);
	}
	else
	{
		push(v, l, r);
		return ans(v * 2 + 1, (r + l) / 2 + 1, r, ind);
	}
}
int ans1(int v, int l, int r, int al, int ar, int val)
{
	if(l >= al && r <= ar)
	{
		if(tree[v] + val < 0)
		{
			if(l == r)
			{
				return l;
			}
			push(v, l, r);
			if(tree[v * 2] + val < 0)
			{
				return ans1(v * 2, l, (r + l) / 2 , al, ar, val);
			}
			return ans1(v * 2 + 1, (r + l) / 2 + 1, r, al, ar, val);
		}
		else
		{
			return -1;
		}
	}
	else if(l <= ar && r >= al)
	{
		push(v, l, r);
		int t = ans1(v * 2, l, (r + l) / 2, al, ar, val);
		if(t == -1)
		{
			return ans1(v * 2 + 1, (r + l) / 2 + 1, r, al, ar, val);
		}
		return t;
	}
	else
	{
		return -1;
	}
}
signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int q;
	cin >> q;
	vector <int> type(q);
	vector <pair <pair <int, int>, int> > query(q);
	vector <int> uniq;
	for(int i = 0; i < q; i++)
	{
		cin >> type[i];
		if(type[i] == 1)
		{
			int t, s;
			cin >> t >> s;
			query[i] = {{t, s}, -1};
			uniq.push_back(t);
		}
		else if(type[i] == 2)
		{
			int t;
			cin >> t;
			query[i] = {{t, -1}, -1};
			uniq.push_back(t);
		}
		else
		{
			int l, r, v;
			cin >> l >> r >> v;
			query[i] = {{l, r}, v};
		}
	}
	int m = unique(uniq.begin(), uniq.end()) - uniq.begin();
	tree.resize(4 * m);
	upd.resize(4 * m);
	set <int> timer;
	vector <int> up(m);
	for(int i = 0; i < type.size(); i++)
	{
		if(type[i] == 1)
		{
			int t = query[i].first.first;
			set <int> :: iterator r = timer.lower_bound(t);
			set <int> :: iterator p;
			p = r;
			up[lower_bound(uniq.begin(), uniq.end(), t) - uniq.begin()] = query[i].first.second;
			if(p != timer.begin())
			{
				p--;
				if(r != timer.end())
				{
					int delta = *r - *p;
					int iter = lower_bound(uniq.begin(), uniq.end(), *p) - uniq.begin();
					delta *= up[iter];
					update(1, 0, m - 1, iter + 1, m - 1, -delta);
					delta = *r - t;
					delta *= query[i].first.second;
					update(1, 0, m - 1, iter + 1, m - 1, delta);
				}
			}
			p = r;
			if(p != timer.begin())
			{
				p--;
				int delta = t - *p;
				int iter = lower_bound(uniq.begin(), uniq.end(), *p) - uniq.begin();
				delta *= up[iter];
				update(1, 0, m - 1, lower_bound(uniq.begin(), uniq.end(), t) - uniq.begin(), m - 1, delta);
			}
			timer.insert(t);
		}
		else if(type[i] == 2){
			int t = query[i].first.first;
			int iter = lower_bound(uniq.begin(), uniq.end(), t) - uniq.begin();
			set <int> :: iterator r = timer.upper_bound(t);
			set <int> :: iterator p = timer.lower_bound(t);
			if(r != timer.end())
			{
				int iter1 = lower_bound(uniq.begin(), uniq.end(), *r) - uniq.begin();
				update(1, 0, m - 1, iter1, m - 1, -(*r - t) * up[iter]);
			}
			if(p != timer.begin())
			{
				p--;
				int iter1 = lower_bound(uniq.begin(), uniq.end(), *p) - uniq.begin();
				update(1, 0, m - 1, iter, m - 1, -(t - *p) * up[iter1]);
				if(r != timer.end())
				{
					update(1,  0, m - 1, iter, m - 1, (*r - *p) * up[iter1]);
				}
			}
			timer.erase(t);
		}
		else
		{
			int l = query[i].first.first;
			int r = query[i].first.second;
			int v = query[i].second;
			set <int> :: iterator it;
			it = timer.upper_bound(l);
			if(timer.size() == 0)
			{
				cout << -1 << "\n";
				continue;
			}
			if(it == timer.begin())
			{
				int u = ans1(1, 0, m - 1, 0, m - 1, v);
				int e = *timer.rbegin();
				if(u == -1 && up[lower_bound(uniq.begin(), uniq.end(), e) - uniq.begin()] >= 0)
				{
					cout << -1 << "\n";
				}
				else if(u == -1)
				{
					int delta = ans(1, 0, m - 1, m - 1) - ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.end(), *it) - uniq.begin());
					v += delta;
					double x = v * 1.0 / (-up[lower_bound(uniq.begin(), uniq.end(), e) - uniq.begin()]);
					x += e;
					if(x > r)
					{
						cout << -1 << "\n";
						continue;
					}
					cout << fixed << setprecision(10) << x << "\n";
				}
				else
				{
					set <int> :: iterator it1;
					it1 = timer.lower_bound(u);
					it1--;
					int delta = ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.end(), *it1) - uniq.begin()) - ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.end(), *it) - uniq.begin());
					v += delta;
					double x =v * 1.0 / (-up[lower_bound(uniq.begin(), uniq.end(), *it1) - uniq.begin()]);
					x += *it1;
					if(x > r)
					{
						cout << -1 << "\n";
						continue;
					}
					cout << fixed << setprecision(10) << x << "\n";
				}
			}
			else if(v == 0)
			{
				cout << l << "\n";
			}
			else
			{
				set <int> :: iterator it1;
				it1 = it;
				it1--;
				int iter1 = lower_bound(uniq.begin(), uniq.end(), *it1) - uniq.begin();
				v -= ans(1, 0, m - 1, iter1);
				v -= up[iter1] * (l - *it1);
				if(up[iter1] * (*it - l) + v + ans(1, 0, m - 1, iter1) + up[iter1] * (l - *it1)<= 0)
				{
					double x = l + (v + ans(1, 0, m - 1, iter1) + up[iter1] * (l - *it1)) / (-up[iter1]);
					if(x > r)
					{
						cout << -1 << "\n";
						continue;
					}
					cout << fixed << setprecision(10) << x << "\n";
				}
				else
				{
					int  u = ans1(1, 0, m - 1, iter1 + 1, m - 1, v);
					int e = *timer.rbegin();
					int riter = lower_bound(uniq.begin(), uniq.end(), e) - uniq.begin();
					if(u == -1 && up[riter] >= 0)
					{
						cout << -1 << "\n";
					}
					else if(u == -1)
					{
						v += ans(1, 0, m - 1, m - 1);
						double x = v * 1.0 / (-up[riter]);
						x += e;
						if(x > r)
						{
							cout << -1 << "\n";
							continue;
						}
						cout << fixed << setprecision(10) << x << "\n";
					}
					else
					{
						set <int> :: iterator it1;
						it1 = timer.lower_bound(uniq[u]);
						it1--;
						int delta = ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.end(), *it1) - uniq.begin()) - ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.end(), *it) - uniq.begin());
						v += delta;
						double x =v * 1.0 / (-up[lower_bound(uniq.begin(), uniq.end(), *it1) - uniq.begin()]);
						x += *it1;
						if(x > r)
						{
							cout << -1 << "\n";
							continue;
						}
						cout << fixed << setprecision(10) << x << "\n";
					}
				}
			}
		}
	}
    return 0;
}

#include<bits/stdc++.h>
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
using namespace std;

template<class T>inline void rd(T & x){ int f = 1;x = 0;char ch = getchar();for(;!isdigit(ch);ch = getchar()) if(ch == '-') f = -1; for(;isdigit(ch);ch = getchar()) x = x * 10 + ch - '0';x *= f;}

const int maxn = 1e5 + 10;

struct op{
	int type;
	int t,l,r,v,s;
} querys[maxn];

int times[maxn],n;
inline int upper(double time){
	int l = 1,r = n,ans = n + 1;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] >= time){
			ans = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	return ans;
}
inline int lower(double time){
	int l = 1,r = n,ans = 0;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] <= time){
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return ans;
}

int mark[maxn];
namespace Fenwick{
	int tr[maxn];
	inline void update(int x,int v){ for(;x < maxn;x += x & (-x)) tr[x] += v;}
	inline int query(int x){ int ans = 0; for(;x;x ^= x & (-x)) ans += tr[x]; return ans;}
	inline int val(int x) { return query(x) - query(x - 1);}
	inline int bs(int x){ // min query(ans) >= x
		int l = 0,r = n,ans = 0;
		while(l <= r){
			int mid = l + r >> 1;
			if(query(mid) >= x) {
				ans = mid;
				r = mid - 1;
			} else {
				l = mid + 1;
			}
		}
		return ans;
	}
	inline int pre(int x){
		int d = query(x - 1);
		return bs(d);
	}
	inline int suc(int x){
		return bs(query(x) + 1);
	}
}
double cur[maxn];
const double inf = 2e20;
namespace Segment{
	double tra[maxn << 2],tri[maxn << 2];
	double lazy[maxn << 2];
	int mk[maxn << 2];

	inline void pushup(int rt){
		tra[rt] = max(tra[rt << 1],tra[rt << 1 | 1]);
		tri[rt] = min(tri[rt << 1],tri[rt << 1 | 1]);
	}
	inline void pushdown(int rt){
		if(!mk[rt]) return;
		mk[rt] = 0;
		mk[rt << 1] = 1;
		mk[rt << 1 | 1] = 1;
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		tra[rt << 1] += lazy[rt];
		tri[rt << 1] += lazy[rt];
		tra[rt << 1 | 1] += lazy[rt];
		tri[rt << 1 | 1] += lazy[rt];
		lazy[rt] = 0;
	}
	void _update(double * target,int pos,double v,int l,int r,int rt){
		if(l == r){
			target[rt] = v;
			return;
		}
		int mid = l + r >> 1;
		if(pos <= mid) _update(target,pos,v,lson);
		else _update(target,pos,v,rson);
		pushup(rt);
	}
	void setVoid(int pos){
		_update(tra,pos,-inf,1,n,1);
		_update(tri,pos,inf,1,n,1);
	}
	void setZero(int pos){
		_update(tra,pos,0,1,n,1);
		_update(tri,pos,0,1,n,1);
	}
	void build(int l,int r,int rt){
		if(l == r){
			tra[rt] = -inf;
			tri[rt] = inf;
			return;
		}
		int mid = l + r >> 1;
		build(lson);
		build(rson);
		pushup(rt);
	}
	void update(int L,int R,double v,int l,int r,int rt){
		if(L <= l && r <= R){
			lazy[rt] += v;
			tra[rt] += v;
			tri[rt] += v;
			mk[rt] = 1;
			return;
		}
		pushdown(rt);
		int mid = l + r >> 1;
		if(L <= mid) update(L,R,v,lson);
		if(R > mid) update(L,R,v,rson);
		pushup(rt);
	}
	double querya(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tra[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = -inf;
		if(L <= mid) ans = max(ans,querya(L,R,lson));
		if(R > mid)ans = max(ans,querya(L,R,rson));
		return ans;
	}
	double queryi(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tri[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = inf;
		if(L <= mid) ans = min(ans,queryi(L,R,lson));
		if(R > mid) ans = min(ans,queryi(L,R,rson));
		return ans;
	}

}
double getV(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return cur[x];
}
double calc(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
//	if(l == 24) printf("CCC :%.9f\n",Segment::querya(x,x,1,n,1));
	if(x == 0) return 0;
	return (double)(l - times[x]) * cur[x] + Segment::querya(x,x,1,n,1);
}
const double eps = 1e-15;
bool check(double l,double r,double c){
	double qa = -inf,qi = inf;
	if(l == r) return abs(calc(l) - c) <= eps;
	qa = max(calc(l),qa);
	qi = min(calc(l),qi);
	qa = max(calc(r),qa);
	qi = min(calc(r),qi);
	int lx = upper(l),rx = lower(r);
	if(lx <= rx && lx != 0 && rx != 0){
		qa = max(qa,Segment::querya(lx,rx,1,n,1));
		qi = min(qi,Segment::queryi(lx,rx,1,n,1));
	}
	return qa - c >= 0 && qi - c <= 0;
}

int main(){
	int TAT;
	rd(TAT);
	for(int i = 1;i <= TAT;i++){
		int type,t,l,r,v,s;
		rd(type);
		if(type == 1){ // add
			rd(t); rd(v);
			times[++n] = t;
			querys[i].type = 1;
			querys[i].t = t;
			querys[i].v = v;
		} else if(type == 2){
			rd(t);
			querys[i].type = 2;
			querys[i].t = t;
		} else {
			rd(l); rd(r); rd(s);
			querys[i].type = 3;
			querys[i].l = l;
			querys[i].r = r;
			querys[i].s = s;
		}
	}
	sort(times + 1,times + n + 1);
	n = unique(times + 1,times + n + 1) - times - 1;

	if(n!=0)Segment::build(1,n,1);
	for(int i = 1;i <= TAT;i++){
		int type = querys[i].type;
		if(type == 1){
			int t = querys[i].t, v = querys[i].v;
			int pos = upper(t);
			Fenwick::update(pos,1);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			cur[pos] = v;
			Segment::setZero(pos);
			if(pre){
				double delta = (double)cur[pre] * (times[pos] - times[pre]) + Segment::querya(pre,pre,1,n,1);
				Segment::update(pos,pos,delta,1,n,1);
			}
			if(suc){
				double delta = (double)(v - cur[pre]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
		} else if(type == 2){
			int t = querys[i].t;
			int pos = upper(t);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			Fenwick::update(pos,-1);
			if(suc){
				double delta = (double)(cur[pre] - cur[pos]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
			Segment::setVoid(pos);
			cur[pos] = 0;
		} else {
			double l = querys[i].l , r = querys[i].r , s = -querys[i].s;
			int lx = upper(l);
			l = times[lx];
			if(s == 0) {
				printf("%d\n",querys[i].l);
				continue;
			}
			s += Segment::querya(lx,lx,1,n,1);

			bool ok = 0;
			if(check(r,r,s) || check(l,l,s)) ok = 1;
			for(int k = 0;k < 1000;k++){
				double mid = (l + r) / 2;
				if(check(l,mid,s)){
					r = mid;
					ok = 1;
				} else {
					l = mid;
				}
			}
			if(ok)printf("%.9f\n",r);
			else printf("-1\n");
		}
	}
}

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <set>
#include <utility>
#include <vector>
using namespace std;

const int Q = 1e5;

int q, real_t[Q], n = 0;
struct query {int type, t, s, r, v, old_t;};
query queries[Q];

//c*t+d
bool is_lazy[Q];
int a[2*Q], b[2*Q];
long long f[2*Q], c[2*Q], d[2*Q], l[Q], r[Q], s[Q];

set<int> active_nxt;
set<int, greater<int>> active_prv;

void init(int k, int x, int y) {
    a[k] = x; b[k] = y;
    if(x == y) return;
    int m = (x+y)/2;
    init(2*k, x, m);
    init(2*k+1, m+1, y);
}

//c[t] * real_t[t] + d[t]
void push_down(int k) {
    if(!is_lazy[k]) return; is_lazy[k] = false;
    int m = (a[k]+b[k])/2;
    l[2*k]   += c[k]*real_t[a[k]] + d[k];
    r[2*k]   += c[k]*real_t[m]    + d[k];
    l[2*k+1] += c[k]*real_t[m+1]  + d[k];
    r[2*k+1] += c[k]*real_t[b[k]] + d[k];

    c[2*k]   += c[k]; d[2*k]   += d[k]; if(a[k] != m)   is_lazy[2*k] = true;
    c[2*k+1] += c[k]; d[2*k+1] += d[k]; if(m+1 != b[k]) is_lazy[2*k+1] = true;

    if(c[k] != 0) {
        f[2*k] =   min(l[2*k],   r[2*k]);
        f[2*k+1] = min(l[2*k+1], r[2*k+1]);
    }
    else {
        f[2*k]   += d[k];
        f[2*k+1] += d[k];
    }

    c[k] = d[k] = 0;
}

void range_add(int k, int x, int y, long long plus_c, long long plus_d) {
    if(a[k] == x && b[k] == y) {
        c[k] += plus_c; d[k] += plus_d;
        l[k] += plus_c*real_t[a[k]] + plus_d;
        r[k] += plus_c*real_t[b[k]] + plus_d;
        if(plus_c != 0) f[k] = min(l[k], r[k]);
        else f[k] += plus_d;
        if(a[k] != b[k]) is_lazy[k] = true;
        return;
    }
    push_down(k);
    int m = (a[k]+b[k])/2;
    if(y <= m) range_add(2*k, x, y, plus_c, plus_d);
    else if(m+1 <= x) range_add(2*k+1, x, y, plus_c, plus_d);
    else {
        range_add(2*k,   x,   m, plus_c, plus_d);
        range_add(2*k+1, m+1, y, plus_c, plus_d);
    }
    l[k] = l[2*k];
    r[k] = r[2*k+1];
    f[k] = min(f[2*k], f[2*k+1]);
}

bool tcomp(int i, int j) {
    if(queries[i].t != queries[j].t) return (queries[i].t < queries[j].t);
    return queries[i].type > queries[j].type;
}

vector<int> sorted;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    cin >> q;
    for (int i = 0; i < q; i++) {
        cin >> queries[i].type;
        if(queries[i].type == 1) cin >> queries[i].t >> queries[i].s;
        else if(queries[i].type == 2) cin >> queries[i].t;
        else cin >> queries[i].t >> queries[i].r >> queries[i].v;
        queries[i].old_t = queries[i].t;
    }

    for (int i = 0; i < q; i++) sorted.push_back(i);
    sort(sorted.begin(), sorted.end(), tcomp);

    int act_time = -1;
    for (int i: sorted) {
        if(queries[i].type == 3) queries[i].t = n;
        else {
            if(queries[i].t != act_time) {
                n++;
                act_time = real_t[n-1] = queries[i].t;
            }
            queries[i].t = n-1;
        }
    }

    if (n == 0) {
        for (int i = 0; i < q; i++) cout << (queries[i].v == 0 ? queries[i].old_t : -1) << "\n";
        return 0;
    }

    init(1, 0, n-1);

    //!note thet for late type3 events .t = n
    for (int i = 0; i < q; i++) {
        if(queries[i].type == 1) {
            long long c = queries[i].s;
            set<int>::iterator it = active_prv.upper_bound(queries[i].t);
            if(it != active_prv.end()) c -= s[*it];
            active_prv.insert(queries[i].t);

            it = active_nxt.upper_bound(queries[i].t);
            if(it != active_nxt.end()) {
                range_add(1, queries[i].t, (*it)-1, c, -c*real_t[queries[i].t]);
                range_add(1, (*it), n-1, 0, c*(real_t[*it]-real_t[queries[i].t]));
            }
            else range_add(1, queries[i].t, n-1, c, -c*real_t[queries[i].t]);
            active_nxt.insert(queries[i].t);

            s[queries[i].t] = queries[i].s;
        }
        else if(queries[i].type == 2) {
            long long c = -s[queries[i].t];
            set<int>::iterator it = active_prv.upper_bound(queries[i].t);
            if(it != active_prv.end()) c += s[*it];
            active_prv.erase(queries[i].t);

            it = active_nxt.upper_bound(queries[i].t);
            if(it != active_nxt.end()) {
                range_add(1, queries[i].t, (*it)-1, c, -c*real_t[queries[i].t]);
                range_add(1, (*it), n-1, 0, c*(real_t[*it]-real_t[queries[i].t]));
            }
            else range_add(1, queries[i].t, n-1, c, -c*real_t[queries[i].t]);
            active_nxt.erase(queries[i].t);
        }
        else {
            if(queries[i].t == n) cout << "-1\n";
            else if(queries[i].v == 0) cout << queries[i].old_t << "\n";
            else if(active_nxt.empty()) cout << "-1\n";
            else {
                int x = queries[i].t;
                int k = 1;
                while(a[k] < b[k]) {
                    push_down(k);
                    k = (x <= b[2*k] ? 2*k : 2*k+1);
                }
                long long v = f[k] - queries[i].v;
                //need: first <= v

                bool found = false;
                while(1 < k && !found) {
                    if(k%2 == 0 && f[k+1] <= v) {
                        found = true;
                        k++;
                    }
                    else k /= 2;
                }

                long long act_s, act_val;

                if(!found) {
                    set<int>::iterator it = active_nxt.end(); --it;
                    act_s = s[*it];
                    act_val = r[1];
                    k = n-1;

                    if(act_s >= 0) {cout << "-1\n"; continue;}
                }
                else {
                    while(a[k] != b[k]) {
                        push_down(k);
                        k = (f[2*k] <= v ? 2*k : 2*k+1);
                    }
                    act_s = s[*active_prv.upper_bound(k-n)];
                    act_val = f[k]-(real_t[k-n]-real_t[k-1-n])*act_s;
                    k -= n+1;
                }

                if(act_val + (queries[i].r -real_t[k]) * act_s > v) cout << "-1\n";
                else cout << setprecision(9) << real_t[k] + (act_val-v+0.0)/(-act_s) << "\n";
            }

        }
    }

    return 0;
}

#include <map>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define Maxn 200000
#define Inf 1000000001
struct Segment_Node{
	int left,right;
	int lc,rc;
	ll lsum,sum;
	bool lazy;
	int v;
}seg[Maxn*20+5];
int root,id_tot;
int new_node(int left,int right){
	seg[++id_tot].lazy=0;
	seg[id_tot].v=0;
	seg[id_tot].left=left;
	seg[id_tot].right=right;
	seg[id_tot].lc=seg[id_tot].rc=0;
	seg[id_tot].lsum=seg[id_tot].sum=0;
	return id_tot;
}
ll mn(ll a,ll b){
	return a<b?a:b;
}
void push_up(int root){
	seg[root].sum=seg[seg[root].lc].sum+seg[seg[root].rc].sum;
	seg[root].lsum=mn(seg[seg[root].lc].lsum,seg[seg[root].lc].sum+seg[seg[root].rc].lsum);
}
void update_node(int root,int v){
	seg[root].sum=1ll*(seg[root].right-seg[root].left+1)*v;
	seg[root].lsum=mn(0ll,seg[root].sum);
	seg[root].lazy=1;
	seg[root].v=v;
}
void push_down(int root){
	if(seg[root].lazy){
		int mid=(seg[root].left+seg[root].right)>>1;
		if(!seg[root].lc){
			seg[root].lc=new_node(seg[root].left,mid);
		}
		if(!seg[root].rc){
			seg[root].rc=new_node(mid+1,seg[root].right);
		}
		update_node(seg[root].lc,seg[root].v);
		update_node(seg[root].rc,seg[root].v);
		seg[root].lazy=0;
	}
}
void update(int root,int left,int right,int v){
	if(seg[root].left==left&&seg[root].right==right){
		update_node(root,v);
		return;
	}
	push_down(root);
	int mid=(seg[root].left+seg[root].right)>>1;
	if(left<=mid){
		if(!seg[root].lc){
			seg[root].lc=new_node(seg[root].left,mid);
		}
		if(right<=mid){
			update(seg[root].lc,left,right,v);
		}
		else{
			update(seg[root].lc,left,mid,v);
		}
	}
	if(right>=mid+1){
		if(!seg[root].rc){
			seg[root].rc=new_node(mid+1,seg[root].right);
		}
		if(left>=mid+1){
			update(seg[root].rc,left,right,v);
		}
		else{
			update(seg[root].rc,mid+1,right,v);
		}
	}
	push_up(root);
}
pair<ll,ll> query(int root,int left,int right){
	if(seg[root].left==left&&seg[root].right==right){
		return make_pair(seg[root].sum,seg[root].lsum);
	}
	push_down(root);
	int mid=(seg[root].left+seg[root].right)>>1;
	if(left<=mid){
		if(!seg[root].lc){
			seg[root].lc=new_node(seg[root].left,mid);
		}
		if(right<=mid){
			return query(seg[root].lc,left,right);
		}
	}
	if(right>=mid+1){
		if(!seg[root].rc){
			seg[root].rc=new_node(mid+1,seg[root].right);
		}
		if(left>=mid+1){
			return query(seg[root].rc,left,right);
		}
	}
	pair<ll,ll> l=query(seg[root].lc,left,mid),r=query(seg[root].rc,mid+1,right);
	return make_pair(l.first+r.first,mn(l.second,l.first+r.second));
}
map<int,int> mp;
int main(){
	seg[0].sum=seg[0].lsum=0;
	root=new_node(1,Inf);
	int q;
	scanf("%d",&q);
	int op,l,r,v;
	mp[0]=mp[Inf+1]=0;
	map<int,int>::iterator it_1,it_2;
	int left,right,mid;
	ll sum;
	while(q--){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d",&l,&v);
			l++;
			mp[l]=v;
			it_1=mp.find(l);
			it_1++;
			update(1,l,(it_1->first)-1,v);
		}
		else if(op==2){
			scanf("%d",&l);
			l++;
			it_1=mp.find(l);
			it_2=it_1;
			it_1--;
			it_2++;
			mp.erase(l);
			update(1,l,(it_2->first)-1,(it_1->second));
		}
		else{
			scanf("%d%d%d",&l,&r,&v);
			if(v==0){
				printf("%d\n",l);
				continue;
			}
			it_1=mp.lower_bound(l);
			l=it_1->first;
			if(l>r){
				puts("-1");
				continue;
			}
			left=l,right=r;
			while(left<right){
				mid=(left+right)>>1;
				if(query(1,l,mid).second+v<=0){
					right=mid;
				}
				else{
					left=mid+1;
				}
			}
			if((sum=query(1,l,left).first)+v>0){
				puts("-1");
				continue;
			}
			it_2=mp.upper_bound(left);
			it_2--;
			printf("%.7lf\n",left-(sum+v)*1.0/(it_2->second));
		}
	}
	return 0;
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y0998244353
#define y1 y1998244353
#define die(cond) if (cond) for (;;) {}
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acosl(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct vertex {
	ll time, speed;
	ll tl, tr, speedR;
	ll res = 0, minn = 0;
	ll l = -1, r = -1;
	ll prior = rand();
};
struct treap {
	vector<vertex> t;
	treap() {}
	void upd(ll v) {
		if (v == -1) {
			return;
		}
		ll& time = t[v].time;
		ll& speed = t[v].speed;
		ll& res = t[v].res;
		ll& minn = t[v].minn;
		ll l = t[v].l, r = t[v].r;
		res = 0, minn = 0;
		if (l != -1) {
			mineq(minn, t[l].minn);
			res += t[l].res;
			res += t[l].speedR * (time - t[l].tr);
			mineq(minn, res);
			t[v].tl = t[l].tl;
		} else {
			t[v].tl = time;
		}
		if (r != -1) {
			res += speed * (t[r].tl - time);
			mineq(minn, res + t[r].minn);
			res += t[r].res;
			mineq(minn, res);
			t[v].tr = t[r].tr;
			t[v].speedR = t[r].speedR;
		} else {
			t[v].tr = time;
			t[v].speedR = speed;
		}
	}
	ll newv(ll t_, ll s_) {
		vertex v;
		v.time = t_, v.speed = s_;
		t.pb(v);
		upd(sz(t) - 1);
		return sz(t) - 1;
	}
	pll split(ll v, ll k) {
		if (v == -1) {
			return { -1, -1 };
		}
		pll p;
		if (t[v].time < k) {
			p = split(t[v].r, k);
			t[v].r = p.ft;
			p.ft = v;
		} else {
			p = split(t[v].l, k);
			t[v].l = p.sd;
			p.sd = v;
		}
		upd(v);
		return p;
	}
	ll merge(ll f, ll s) {
		if (f == -1) {
			return s;
		}
		if (s == -1) {
			return f;
		}
		if (t[f].prior > t[s].prior) {
			t[f].r = merge(t[f].r, s);
			upd(f);
			return f;
		} else {
			t[s].l = merge(f, t[s].l);
			upd(s);
			return s;
		}
	}
	ll add(ll root, ll t_, ll s) {
		ll a, b;
		tie(a, b) = split(root, t_);
		ll v = newv(t_, s);
		root = merge(merge(a, v), b);
		return root;
	}
	ll del(ll root, ll t_) {
		ll a, b, c;
		tie(a, b) = split(root, t_);
		tie(b, c) = split(b, t_ + 1);
		root = merge(a, c);
		return root;
	}
	ld down(ll v, ll V, ll R) {
		if (v == -1) {
			return -1;
		}
		if (V + t[v].minn > 0) {
			if (t[v].tr >= R) {
				return -1;
			}
			if (V + t[v].res + t[v].speedR * (R - t[v].tr) > 0) {
				return -1;
			}
		}
		ll v1 = down(t[v].l, V, R);
		if (v1 != -1) {
			return v1;
		}
		if (t[v].r != -1) {
			if (t[v].l != -1) {
				V += t[t[v].l].res;
				V += t[t[v].l].speedR  * (t[v].time - t[t[v].l].tr);
			}
			if (V + t[v].speed * (t[t[v].r].tl - t[v].time) > 0) {
				return down(t[v].r, V + t[v].speed * (t[t[v].r].tl - t[v].time), R);
			}
			ld ans = t[v].time - ld(V) / ld(t[v].speed);
			return ans;
		}
		V += t[v].res;
		ld ans = t[v].tr - ld(V) / ld(t[v].speed);
		return ans;
	}
	ld getans(ll root, ll l, ll r, ll v) {
		if (v == 0) {
			return l;
		}
		ll a, b, c;
		tie(a, b) = split(root, l);
		tie(b, c) = split(b, r + 1);
		ld ans = down(b, v, r + 1);
		root = merge(merge(a, b), c);
		return ans;
	}
};

ll q;
treap tr;

inline void solve() {
	cout << setprecision(40) << fixed;
	ll root = -1;
	for (ll i = 0; i < q; i++) {
		ll t;
		cin >> t;
		if (t == 1) {
			ll time, s;
			cin >> time >> s;
			root = tr.add(root, time, s);
		} else if (t == 2) {
			ll time;
			cin >> time;
			root = tr.del(root, time);
		} else if (t == 3) {
			ll l, r, v;
			cin >> l >> r >> v;
			ld ans = tr.getans(root, l, r, v);
			cout << ans << endl;
		}
	}
}

inline void read() {
	cin >> q;
}

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod7=1000000007LL;
inline ll getint() {
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add(ll _x, ll _y, ll _mod=mod7) {
  _x+=_y;
  return _x>=_mod ? _x-_mod : _x;
}
inline ll sub(ll _x, ll _y, ll _mod=mod7) {
  _x-=_y;
  return _x<0 ? _x+_mod : _x;
}
inline ll mul(ll _x, ll _y ,ll _mod=mod7) {
  _x*=_y;
  return _x>=_mod ? _x%_mod : _x;
}
ll mypow(ll _a, ll _x, ll _mod) {
  if(_x == 0) return 1ll;
  ll _ret = mypow(mul(_a, _a, _mod), _x>>1, _mod);
  if(_x & 1) _ret=mul(_ret, _a, _mod);
  return _ret;
}
ll mymul(ll _a, ll _x, ll _mod) {
  if(_x == 0) return 0ll;
  ll _ret = mymul(add(_a, _a, _mod), _x>>1, _mod);
  if(_x & 1) _ret=add(_ret, _a, _mod);
  return _ret;
}
void sleep(double sec = 1021) {
	clock_t s = clock();
	while(clock() - s < CLOCKS_PER_SEC * sec);
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/

const int mxN=1e5+5, bs=200, bc=(mxN-1)/bs+1;
int nq, n;
array<int, 4> q[mxN];
vector<int> v;
ll s[mxN], ms[bc], ts[bc], lz2[bc];
bool lz1[bc];

void pb(int i) {
	if(lz1[i]) {
		for(int l=i*bs; l<min(n, (i+1)*bs); ++l)
			s[l]=lz2[i];
		lz1[i]=0;
	}
}
void ub(int i) {
	ts[i]=ms[i]=0;
	for(int l=i*bs; l<min(n, (i+1)*bs); ++l) {
		ts[i]+=s[l];
		ms[i]=min(ts[i], ms[i]);
	}
}

//[l, r]
void upd(int l, int r, ll x) {
	//cout << "upd " << l << " " << r << " " << x << endl;
	int bi=l/bs;
	pb(bi);
	for(; l<(bi+1)*bs&&l<=r; ++l)
		s[l]=x;
	//cout << s[3] << " " << s[4] << endl;
	ub(bi++);
	if(l>r)
		return;
	for(; l+bs<=r; l+=bs, ++bi) {
		lz1[bi]=1;
		lz2[bi]=x;
		ts[bi]=(v[l+bs]-v[l])*x;
		if(x>0)
			ms[bi]=0;
		else
			ms[bi]=ts[bi];
	}
	pb(bi);
	for(; l<=r; ++l) {
		s[l]=x;
	}
	ub(bi);
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);

	v.push_back(0);
	v.push_back(1e9+1);
	cin >> nq;
	for(int i=0; i<nq; ++i) {
		cin >> q[i][0] >> q[i][1];
		if(q[i][0]!=2)
			cin >> q[i][2];
		if(q[i][0]==3)
			cin >> q[i][3];
		if(q[i][0]==1)
			v.push_back(q[i][1]);
	}
	sort(v.begin(), v.end());
	v.resize(unique(v.begin(), v.end())-v.begin());
	n=v.size();
	for(int i=0; i<nq; ++i) {
		if(q[i][0]!=3)
			q[i][1]=lower_bound(v.begin(), v.end(), q[i][1])-v.begin();
		//if(q[i][0]==3)
			//q[i][2]=lower_bound(v.begin(), v.end(), q[i][2])-v.begin()-1;
	}
	cout << fixed << setprecision(9);
	//cout << n << endl;
	map<int, int> m{{0, 0}, {n-1, 0}};
	for(int qi=0; qi<nq; ++qi) {
		if(q[qi][0]==1) {
			auto it=m.lower_bound(q[qi][1]);
			upd(q[qi][1], it->first-1, q[qi][2]);
			m[q[qi][1]]=q[qi][2];
		} else if(q[qi][0]==2) {
			m.erase(q[qi][1]);
			auto it1=m.lower_bound(q[qi][1]), it2=it1--;
			upd(it1->first, it2->first-1, it1->second);
		} else {
			int li=lower_bound(v.begin(), v.end(), q[qi][1])-v.begin(), ri=lower_bound(v.begin(), v.end(), q[qi][2])-v.begin()-1;
			li=m.lower_bound(li)->first;
			int bi=li/bs;
			ll c=q[qi][3];
			if(c<=0) {
				cout << q[qi][1] << "\n";
				continue;
			}
			if(li>ri) {
				if(n>1e3)
					cout << "a";
				cout << "-1\n";
				continue;
			}
			bool sc=0;
			pb(bi);
			for(; li<(bi+1)*bs&&li<=ri&&!sc; ++li) {
				//cout << li << " " << s[li] << " " << endl;
				int df=min(q[qi][2], v[li+1])-v[li];
				if(c+df*s[li]<=0) {
					cout << (long double)-c/s[li]+v[li] << "\n";
					sc=1;
				}
				c+=df*s[li];
			}
			if(sc)
				continue;
			++bi;
			for(; li+bs<=ri; li+=bs, ++bi) {
				if(c+ms[bi]<=0)
					break;
				c+=ts[bi];
			}
			pb(bi);
			for(; li<=ri&&!sc; ++li) {
				int df=min(q[qi][2], v[li+1])-v[li];
				if(c+df*s[li]<=0) {
					cout << (long double)-c/s[li]+v[li] << "\n";
					sc=1;
				}
				c+=df*s[li];
			}
			if(sc)
				continue;
			cout << "-1\n";
		}
	}
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define mp(a, b) make_pair(a, b)
#define x first
#define y second

#define N 100555
#define L 1000000009

struct Range {
	int l, r, f, c;
	LL low, su;
	bool has;
	Range() {}
	Range(int v) {
		l = 0, r = 0;
		f = r + 1, c = 0;
		low = su = v;
		has = 0;
	}
	Range(int a, int b) {
		l = a, r = b;
		f = r + 1, c = 0;
		low = su = 0;
		has = 0;
	}
	Range(int a, int b, int v) {
		l = a, r = b;
		f = l, c = v;
		low = su = v;
		has = 1;
	}
} qq;

Range operator + (const Range &a, const Range &b) {
	Range ret;
	ret.l = a.l;
	ret.r = b.r;
	ret.f = a.has ? a.f : b.f;
	ret.c = b.has ? b.c : a.c;
	LL mid = LL(b.f - b.l) * a.c;
	ret.low = min(a.low, a.su + mid + min(b.low, 0ll));
	ret.su = a.su + mid + b.su;
	ret.has = a.has | b.has;
	return ret;
}

struct Node {
	int l, r;
	Range v;
} t[N * 40];

int rt = 0, tcnt = 0;

int newNode(int l, int r) {
	t[++tcnt].v = Range(l, r);
	t[tcnt].l = t[tcnt].r = 0;
	return tcnt;
}

void upd(int &x, int l, int r, int p, int v) {
	if (!x) x = newNode(l, r);
	if (l < r) {
		int mid = (l + r) >> 1;
		if (p <= mid) upd(t[x].l, l, mid, p, v);
		else 		  upd(t[x].r, mid + 1, r, p, v);
		t[x].v = (t[x].l ? t[t[x].l].v : Range(l, mid)) + (t[x].r ? t[t[x].r].v : Range(mid + 1, r));
	}
	else {
		t[x].v = Range(p, p, v);
	}
}

void clr(int &x, int l, int r, int p) {
	if (!x) x = newNode(l, r);
	if (l < r) {
		int mid = (l + r) >> 1;
		if (p <= mid) clr(t[x].l, l, mid, p);
		else 		  clr(t[x].r, mid + 1, r, p);
		t[x].v = (t[x].l ? t[t[x].l].v : Range(l, mid)) + (t[x].r ? t[t[x].r].v : Range(mid + 1, r));
	}
	else {
		t[x].v = Range(p, p);
	}
}

bool ok;
double ans;

void solve(int x, int l, int r) {
	if (!t[x].v.has) {
		LL su = qq.su, vv = qq.c, tt = r - l + 1;
		if (su + vv * tt <= 0) {
			ok = 1;
			ans = l + double(su) / -vv;
		}
		else qq = qq + Range(l, r);
		return;
	}
	LL ins = qq.c * (t[x].v.f - t[x].l);
	if (qq.su + ins <= 0) {
		ok = 1;
		ans = l + double(qq.su) / -qq.c;
		return;
	}
	if (qq.su + ins + min(t[x].v.low, 0ll) > 0) {
		qq = qq + t[x].v;
		return;
	}
	if (l == r) {
		ok = 1;
		ans = l + double(qq.su) / -t[x].v.c;
	}
	else {
		int mid = (l + r) >> 1;
		solve(t[x].l, l, mid);
		if (ok) return;
		solve(t[x].r, mid + 1, r);
	}
	//assert ok
}

void qry(int x, int l, int r, int ql, int qr) {
	if (ok) return;
	if (!x || (l == ql && r == qr)) {
		solve(x, ql, qr);
		return;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid) qry(t[x].l, l, mid, ql, min(mid, qr));
	if (qr >  mid) qry(t[x].r, mid + 1, r, max(mid + 1, ql), qr);
}

int Q;

const double eps = 1e-8;

int main() {
	cin >> Q;
	while (Q--) {
		int op, t, s, l, r, v;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &t, &s);
			upd(rt, -L, L, t, s);
		}
		else if (op == 2) {
			scanf("%d", &t);
			clr(rt, -L, L, t);
		}
		else {
			scanf("%d%d%d", &l, &r, &v);
			if (v == 0) {
				printf("%d\n", l);
				continue;
			}
			qq = v;
			ok = 0;
			qry(rt, -L, L, l, r);
			if (ok && ans + eps >= l && ans - eps <= r) printf("%.6lf\n", ans);
			else puts("-1");
		}
	}
	return 0;
}

    #include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

#define pitem item*
#define tam 1023456
#define tamN 12345
using namespace std;
typedef long long ll;

typedef pair<ll,ll> ii;
typedef pair<int,ii> iii;
const ll INF=1e18;
struct item
{
    int prior,cnt;
    ll pos,speed,minn,tot;
    ii pos_viz;
    ii pos_vder;
    pitem l;
    pitem r;
    item(){}
    item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
    {
        prior=rand();
        minn=INF;
        pos_viz=pos_vder=ii(pos,speed);
    }

};
int cnt(pitem t){return t?t->cnt:0;}
ll gtot(pitem t){return t?t->tot:0;}
ll gmin(pitem t){return t?t->minn:INF;}

ll gextraiz(pitem t){
    if (!t|| (!(t->l)))
        return INF;
    else
        return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
}
ll gextrader(pitem t){
    if (!t|| !(t->r))
        return INF;
    return  (t->r->pos_viz.f-t->pos)*(t->speed);
}
void upd_cnt(pitem t)
{
    if (t)
    {
        t->cnt=cnt(t->l)+cnt(t->r)+1;
        ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
        t->tot=totiz;
        t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
        if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
        if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
        t->tot+=gtot(t->r);
        t->minn=gmin(t->l);
        t->minn=min(t->minn,totiz+extraiz);
        t->minn=min(t->minn,totiz+extraiz+extrader);
        t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
        if (t->tot!=0)
        t->minn=min(t->minn,t->tot);
    }
}
void split(pitem t,pitem &l,pitem &r,int key)
{
    if (!t)
        return void(l=r=0);
    if (t->pos>key)
        split(t->l,l,t->l,key),r=t;
    else
        split(t->r,t->r,r,key),l=t;
    upd_cnt(t);
}
void merge(pitem &t,pitem l,pitem r)
{
    if (!l||!r)
        t=l?l:r;
    else if (r->prior>l->prior)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd_cnt(t);
}
ll auxresp;
double respf;ll iz,der;
pitem ant_t;
bool print=false;
void query(pitem t,ll inival)
{

    if (t==0)
    {
        if (!ant_t)
            return void(auxresp=-1);

        // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
        ll extra;
        extra=(der-ant_t->pos)*(ant_t->speed);
        if (inival+extra<=0)
        {
            auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
            respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
            return;
        }
        else
            return void(auxresp=-1);
    }
    ant_t=t;
    ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
    if (gmin(t->l)+inival<=0)
    {
        query(t->l,inival);
        // cout<<"go left\n";
    }
    else
    {
        ll extraiz,extrader,totiz;
        extraiz=(t->l)?gextraiz(t):0;
        extrader=(t->r)?gextrader(t):0;
        totiz=gtot(t->l);
        ll auxini=totiz+extraiz+extrader;
        // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
        if (totiz+extraiz+inival<=0)
        {
            inival+=totiz;
            auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
            respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
        }
        else if (totiz+extraiz+extrader+inival<=0)
        {
            inival+=totiz+extraiz;
            auxresp=(t->pos)-(inival)/(t->speed);//-.-
            respf=-(double)(inival%t->speed)/(t->speed);//-.-

        }
        else
            {

                // cout<<"go right\n";
                query(t->r,auxini+inival);
            }

    }
}

int main()
{
    int casos;
    scanf("%d",&casos);
    if (casos==100)
        print=1;
    int tipo;
    pitem t1;pitem t2;pitem t3;
    pitem s;
    pitem tree=new item(2e9,1);
    ll val,pos;
    double auxrespf;
    while(casos--)
    {
        scanf("%d",&tipo);
        if (tipo==1)
        {
            scanf("%lld %lld",&pos,&val);
            if (val==0)
            {
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
                continue;
            }
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            s=new item(pos,val);
            merge(tree,t1,s);
            merge(tree,tree,t3);
        }
        else if (tipo==2)
        {
            scanf("%lld",&pos);
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            merge(tree,t1,t3);
        }
        else if (tipo==3)
        {
            scanf("%lld %lld %lld",&iz,&der,&val);
            if (val==0)
            {
                printf("%lld.0\n",iz);
                continue;
            }
            split(tree,t1,t3,der);
            split(t1,t1,t2,iz-1);
            ant_t=NULL;
            query(t2,val);
            if (auxresp==-1)
                printf("-1\n");
            else
            {
                auxrespf=auxresp+respf;
                if (respf<1e-9)
                    cout<<"wat\n";
                printf("%.9lf\n",auxrespf);
            }
            merge(tree,t1,t2);
            merge(tree,tree,t3);
        }
     //   inorder(tree);
        //// cout<<endl;
    }
}

#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using ll = long long;

const int INF = 1e9 + 5;

struct S {
    ll start, speed, min_volume, delta;
    // delta - total change of volume
    // min_volume - lowest point reached in the process
    void merge(const S& a, const S& b) {
        if(a.is_fake()) {
            *this = b;
        }
        else if(b.is_fake()) {
            *this = a;
        }
        else {
            min_volume = min(a.min_volume, a.delta + b.min_volume);
            delta = a.delta + b.delta;
        }
    }
    void init(int t0, int t1, int _speed) {
        speed = _speed;
        delta = (ll) (t1 - t0) * speed;
        min_volume = min(0LL, delta);
        start = t0;
    }
    bool is_fake() const {
        return start == -1;
    }
    double find_exact_point(ll v0) {
        assert(!is_fake());
        assert(speed < 0);
        return start + v0 / (double) -speed;
    }
};

debug& operator << (debug& dd, S s) {
    dd << imie(s.start) imie(s.speed) imie(s.min_volume) imie(s.delta);
    return dd;
}

int main() {
    int q;
    scanf("%d", &q);
    vector<vector<int>> queries;
    vector<int> values;
    for(int i = 0; i < q; ++i) {
        int type;
        scanf("%d", &type);
        if(type == 1) {
            int t, s;
            scanf("%d%d", &t, &s);
            queries.push_back({type, t, s});
            values.push_back(t);
        }
        else if(type == 2) {
            int t;
            scanf("%d", &t);
            queries.push_back({type, t});
            values.push_back(t);
        }
        else if(type == 3) {
            int l, r, v;
            scanf("%d%d%d", &l, &r, &v);
            queries.push_back({type, l, r, v});
            values.push_back(l);
            values.push_back(r);
        }
        else {
            assert(false);
        }
    }

    map<int,int> speeds;
    speeds[0] = 0;
    speeds[INF] = 0;

    values.push_back(0);
    values.push_back(INF);

    debug() << imie(values);
    sort(values.begin(), values.end());
    values.resize( unique(values.begin(), values.end()) - values.begin() );
    debug() << imie(values);

    auto get_id = [&](int x) {
        return lower_bound(values.begin(), values.end(), x) - values.begin();
    };

    int base = 1;
    while(base < (int) values.size()) {
        base *= 2;
    }
    vector<S> tree(2 * base, S{-1});

    auto init_leaf = [&](int id, int t0, int t1, int speed) {
        tree[base+id].init(t0, t1, speed);
        for(int x = (base + id) / 2; x >= 1; x /= 2) {
            tree[x].merge(tree[2*x], tree[2*x+1]);
        }
    };

    init_leaf(0, 0, INF, 0);

    for(vector<int> query : queries) {
        int type = query[0];
        debug() << imie(type) imie(query);
        for(int i = 1; i < 2 * base; ++i) {
            debug() << imie(i) << tree[i];
        }
        if(type == 1) {
            int t = query[1];
            int s = query[2];
            auto it = speeds.lower_bound(t);
            assert(it != speeds.begin());
            --it;
            int t_previous = it -> first;
            //~ int id_leaf = base + get_id(t_previous);
            init_leaf(get_id(t_previous), t_previous, t, it -> second);
            //~ tree[id_leaf].init(t_previous, t, it -> second);
            ++it;
            init_leaf(get_id(t), t, it -> first, s);
            speeds[t] = s;
        }
        else if(type == 2) {
            int t = query[1];
            auto it = speeds.find(t);
            assert(it -> first == t);
            assert(it != speeds.begin());
            --it;
            int t_previous = it -> first;
            int s_previous = it -> second;
            ++it;
            ++it;
            int t_next = it -> first;
            init_leaf(get_id(t), -1, -1, -1);
            init_leaf(get_id(t_previous), t_previous, t_next, s_previous);
            speeds.erase(t);
        }
        else if(type == 3) {
            int L = query[1];
            L = speeds.lower_bound(L)->first;
            ll v0 = query[3];
            if(L == INF) {
                puts("-1");
                continue;
            }
            if(v0 == 0) {
                printf("%d\n", L);
                continue;
            }

            //~ auto it = speeds.lower_bound(L);
            //~ bool special_split = it->first != L;
            //~ if(special_split) {
                //~ int t_next = it -> first;
                //~ assert(it != speeds.begin());
                //~ --it;
                //~ int t_previous = it -> first;
                //~ int s_previous = it -> second;
                //~ init_leaf(get_id(t_previous), t_previous, L, s_previous);
                //~ init_leaf(get_id(L), L, t_next, s_previous);
                //~ speeds[L] = s_previous;
            //~ }
            //~ auto fix = [&]() {
                //~ if(special_split) {
                    //~ L = query[1];
                    //~ it = speeds.find(L);
                    //~ assert(it != speeds.end());
                    //~ assert(it->first == L);
                    //~ assert(it != speeds.begin());
                    //~ --it;
                    //~ int t_previous = it->first;
                    //~ int s_previous = it->second;
                    //~ ++it;
                    //~ ++it;
                    //~ assert(it != speeds.end());
                    //~ init_leaf(get_id(t_previous), t_previous, it->first, s_previous);
                    //~ init_leaf(get_id(L), -1, -1, -1);
                //~ }
            //~ };

            L = get_id(L);

            L += base;
            vector<int> left;
            left.push_back(L);
            for(; L > 1; L /= 2) {
                if(L % 2 == 0) {
                    left.push_back(L + 1);
                }
            }
            //~ reverse(right.begin(), right.end());
            //~ for(auto x : right) {
                //~ left.push_back(x);
            //~ }
            int found = -1;
            assert(v0 >= 0);
            for(int id : left) {
                if(tree[id].is_fake()) {
                    continue;
                }
                if(tree[id].min_volume <= -v0) {
                    found = id;
                    break;
                }
                else {
                    assert(tree[id].min_volume <= tree[id].delta);
                    debug() << imie(v0) imie(tree[id]);
                    v0 += tree[id].delta;
                    assert(v0 >= 0);
                }
            }
            if(found == -1) {
                puts("-1");
                //~ fix();
                continue;
            }
            int id = found;
            while(id < base) { // not a leaf
                if(!tree[2*id].is_fake() && tree[2*id].min_volume <= -v0) {
                    id = 2 * id;
                }
                else {
                    if(!tree[2*id].is_fake()) {
                        assert(tree[2*id].min_volume <= tree[2*id].delta);
                        v0 += tree[2*id].delta;
                        assert(v0 >= 0);
                    }
                    id = 2 * id + 1;
                }
            }
            assert(!tree[id].is_fake());
            debug() << imie(id) imie(tree[id]) imie(v0);
            double answer = tree[id].find_exact_point(v0);
            if(answer <= query[2] + 1e-12) {
                printf("%.10lf\n", answer);
            }
            else {
                puts("-1");
            }
            //~ fix();
        }
        else {
            assert(false); // invalid type
        }
    }
}

#include <iostream>
#include <cmath>
#include <map>

using namespace std;

typedef long long int ll;

const int infinite=1000000005;

struct elem {
  ll s,hs,posle,posri;
  ll minimum,hri,marginle;
  elem() {
    s=hs=minimum=hri=marginle=0;
    posle=posri=infinite;
  }
};

const int tope=1<<20;
const int first=1<<19;

elem v[tope];
map<int,int> mapa;

void insert(int posreal,int s,int hs)
{
  int pos=mapa[posreal];
  pos+=first;
  {
    elem &e=v[pos];
    e.posle=e.posri=posreal;
    e.s=s;
    e.hs=hs;
  }
  while (pos>1) {
    pos/=2;
    elem &e=v[pos];
    elem &e0=v[2*pos];
    elem &e1=v[2*pos+1];
    e.posle=e0.posle;
    e.posri=e1.posri;
    e.hs=e0.hs or e1.hs;
    e.s=e1.hs?e1.s:e0.s;
    if (e0.hs && e1.hs) {
      e.marginle=e0.marginle;
      e.minimum=min(e0.minimum,e0.hri+e0.s*(e1.marginle+e1.posle-e0.posri)+e1.minimum);
      e.hri=e0.hri+e0.s*(e1.marginle+e1.posle-e0.posri)+e1.hri;
    } else if (e0.hs) {
      e.marginle=e0.marginle;
      e.minimum=min(e0.minimum,e0.hri+e0.s*(e1.posri-e0.posri));
      e.hri=e0.hri+e0.s*(e1.posri-e0.posri);
    } else if (e1.hs) {
      e.marginle=e1.posle-e0.posle+e1.marginle;
      e.minimum=e1.minimum;
      e.hri=e1.hri;
    }
  }
}

double simulate(int pos,ll s,ll hri,int posrealr)
{
  if (posrealr<v[pos].posle) return -1;
  if (first<=pos) return v[pos].posle;
  int pos0=2*pos;
  int pos1=2*pos+1;
  elem &e0=v[pos0];
  elem &e1=v[pos1];
  int posle=e0.posle;
  if (e0.hs) {
    if (hri+s*e0.marginle+e0.minimum<=0) return simulate(pos0,s,hri,posrealr);
    hri+=s*e0.marginle+e0.hri;
    s=e0.s;
    posle=e0.posri;
  }
  if (hri+s*(e1.posle-posle)<=0) {
    if (hri<=-s*(posrealr-posle))
      return posle+double(hri)/(-s);
    return -1;
  }
  hri+=s*(e1.posle-posle);
  return simulate(pos1,s,hri,posrealr);
}

double simulate(int posreall,int posrealr,int hri)
{
  if (hri<=0) return posreall;
  if (posreall==posrealr) return -1;
  int pos0=mapa[posreall];
  pos0+=first;
  ll s=v[pos0].s;
  while (pos0>1) {
    if (posrealr<v[pos0].posri) return -1;
    if (pos0%2==0) {
      elem &e0=v[pos0];
      int pos1=pos0+1;
      elem &e1=v[pos1];
      if (hri+s*(e1.posle-e0.posri)<=0) {
	if (hri<=-s*(posrealr-e0.posri))
	  return e0.posri+double(hri)/(-s);
	return -1;
      }
      hri+=s*(e1.posle-e0.posri);
      if (e1.hs) {
	if (hri+s*e1.marginle+e1.minimum<=0)
	  return simulate(pos1,s,hri,posrealr);
	hri+=s*e1.marginle+e1.hri;
	s=e1.s;
      } else {
	if (hri+s*(e1.posri-e1.posle)<=0)
	  return simulate(pos1,s,hri,posrealr);
	hri+=s*(e1.posri-e1.posle);
      }
    }
    pos0/=2;
  }
  return -1;
}

const int limit=1000000;
int cases;
int kind[limit];
int le[limit],ri[limit],H[limit],t[limit],s[limit];

int main()
{
  cout.setf(ios::fixed);
  cout.precision(10);
  ios::sync_with_stdio(false);
  cin>>cases;
  for (int cas=1;cas<=cases;cas++) {
    cin>>kind[cas];
    if (kind[cas]==1) {
      cin>>t[cas]>>s[cas];
      mapa[t[cas]];
    } else if (kind[cas]==2) {
      cin>>t[cas];
    } else {
      cin>>le[cas]>>ri[cas]>>H[cas];
      mapa[le[cas]];
      mapa[ri[cas]];
    }
  }
  {
    int n=0;
    for (map<int,int>::iterator it=mapa.begin();it!=mapa.end();it++,n++)
      it->second=n;
    for (map<int,int>::iterator it=mapa.begin();it!=mapa.end();it++)
      insert(it->first,0,0);
  }
  for (int cas=1;cas<=cases;cas++) {
    if (kind[cas]==1) {
      insert(t[cas],s[cas],1);
    } else if (kind[cas]==2) {
      insert(t[cas],0,0);
    } else {
      double sol=simulate(le[cas],ri[cas],H[cas]);
      if (sol<0) cout<<-1<<endl;
      else cout<<sol<<endl;
    }
  }
}

#include<bits/stdc++.h>

#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fLL
#define mod 1000000007
#define pb push_back
#define sq(x) ((x)*(x))
#define sz(a) ((int)a.size())
#define eps 1e-8
#define x first
#define y second
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define bit(x, y) (((x)>>(y))&1)
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) ((x) ? (__builtin_clzll(x)) : 0)
#define bctz(x) (__builtin_ctz(x))
#define bctzl(x) (__builtin_ctzll(x))
#define shit(a) (1 << (a))
#define rev(a) (power(a, mod-2, mod))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> ppi;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, U b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, U b) {if(a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}
template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}
template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}
template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
int power(int a, int b, int m, int ans=1) {
	for(; b; b>>=1, a=1LL*a*a%m) if(b&1) ans=1LL*ans*a%m;
	return ans;
}

#define NN 100011

int arr[NN<<1];
int nn;

struct query{
	int tp, t, l, r, v, s;
	void input() {
		gn(tp);
		if(tp==1) {
			gn(t, s);
			arr[nn++] = t;
		}
		if(tp==2) {
			gn(t);
			arr[nn++] = t;
		}
		if(tp==3) {
			gn(l, r, v);
		}
	}
} qu[NN];

set<pii> S;
set<pii> :: iterator nxt, pre, now;
map<int, int> mp;
DO ans;

INT mn[NN<<2];
INT sum[NN<<2];
int vel[NN];

#define ls (u<<1)
#define rs (ls|1)
#define mid (st+ed>>1)

void push_up(int u) {
	sum[u] = sum[ls] + sum[rs];
	mn[u] = mn[ls];
	smin(mn[u], sum[ls]+mn[rs]);
}

void update(int u, int st, int ed, int l, int r, INT d) {
	smax(l, st); smin(r, ed);
	if(l >= r) return ;
	if(l==st and r ==ed){
		mn[u] = d;
		sum[u] = d;
		return ;
	}
	update(ls, st, mid, l, r, d);
	update(rs, mid, ed, l, r, d);
	push_up(u);
}

INT cur;
int calc(int u, int st, int ed, int l, int r) {
	smax(l, st); smin(r, ed);
	if(l >= r) return 0;
	if(l==st and r ==ed){
		if(cur+mn[u]>0) {
			cur+=sum[u];
			return 0;
		}
		if(ed==st+1) {
//			cerr<<st<<' '<<cur<<endl;
			ans = arr[st] - 1.0*cur/vel[st];
			return 1;
		}
		if(cur+mn[ls]>0) return calc(ls, st, mid, l, r);
		cur+=sum[ls];
		return calc(rs, mid, ed, l, r);
	}
	if(calc(ls, st, mid, l, r)) return 1;
	return calc(rs, mid, ed, l, r);
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	int q;
	cin >> q;
	for(int i=0; i<q; i++) {
		qu[i].input();
	}
	arr[nn++]=inf;
	arr[nn++]=0;
	sort(arr, arr+nn);
	nn=unique(arr, arr+nn)-arr;
	for(int i=0; i<nn; i++) mp[arr[i]] = i;

	S.insert(pii(inf, 0));
	S.insert(pii(0, 0));
	for(int i=0; i<q; i++) {
		if(qu[i].tp==1) {
			int t=qu[i].t, s=qu[i].s;
			nxt=pre=S.upper_bound(pii(t, s));
			pre--;
			int nt=nxt->x, pt=pre->x;
			int ns=nxt->y, ps=pre->y;
			int p=mp[pt];
			int c=mp[t];
//			cerr<<p<<' '<<(INT)(t-pt)*ps<<endl;
			vel[c] = s;
			update(1, 0, nn, c, c+1, (INT)(nt-t)*s);
			update(1, 0, nn, p, p+1, (INT)(t-pt)*ps);
			S.insert(pii(t, s));
		}
		if(qu[i].tp==2) {
			int t=qu[i].t;
			now=nxt=pre=S.lower_bound(pii(t, -inf));
			pre--;
			nxt++;
			int nt=nxt->x, pt=pre->x;
			int ns=nxt->y, ps=pre->y;
			int p=mp[pt];
			int c=mp[t];
			update(1, 0, nn, c, c+1, 0);
			update(1, 0, nn, p, p+1, (INT)(nt-pt)*ps);
			S.erase(now);
		}

		if(qu[i].tp==3) {
			int l=qu[i].l, r=qu[i].r, v=qu[i].v;
			if(v==0) {
				println(l);
				continue;
			}
			pre=S.lower_bound(pii(l, -inf));
			nxt=S.upper_bound(pii(r, inf));
			if(pre==nxt) {
				if(v==0) println(l);
				else println(-1);
			}
			else {
				int ed=nxt->x;
				nxt--;
				int nt=nxt->x, ns=nxt->y;
				int c=mp[nt];
//				cerr<<c<<' '<<(INT)(r-nt)*ns<<endl;
				update(1, 0, nn, c, c+1, (INT)(r-nt)*ns);
				cur=v;
				if(calc(1, 0, nn, mp[pre->x], c+1)) printf("%.6lf\n", ans);
				else puts("-1");
				update(1, 0, nn, c, c+1, (INT)(ed-nt)*ns);
			}
		}
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
vector <int> tree;
vector <int> upd;
void push(int v, int l, int r)
{
	tree[v * 2] += upd[v];
	tree[v * 2 + 1] += upd[v];
	upd[v * 2] += upd[v];
	upd[v * 2 + 1] += upd[v];
	upd[v] = 0;
}
void update(int v, int l, int r, int al, int ar, int val)
{
	if(l >= al && r <= ar)
	{
		tree[v] += val;
		upd[v] += val;
	}
	else if(l  <= ar && r >= al)
	{
		push(v, l, r);
		update(v * 2, l, (r + l) / 2, al, ar, val);
		update(v * 2 + 1, (r + l) / 2 + 1, r, al, ar, val);
		tree[v] = min(tree[v * 2], tree[v * 2 + 1]);
	}
}
int ans(int v, int l, int r, int ind)
{
	if(l == r)
	{
		return tree[v];
	}
	else if(ind <= (r + l) / 2)
	{
		push(v, l, r);
		return ans(v * 2, l, (r + l) / 2, ind);
	}
	else
	{
		push(v, l, r);
		return ans(v * 2 + 1, (r + l) / 2 + 1, r, ind);
	}
}
int ans1(int v, int l, int r, int al, int ar, int val)
{
	if(l >= al && r <= ar)
	{
		if(tree[v] + val <= 0)
		{
			if(l == r)
			{
				return l;
			}
			push(v, l, r);
			if(tree[v * 2] + val <= 0)
			{
				return ans1(v * 2, l, (r + l) / 2 , al, ar, val);
			}
			return ans1(v * 2 + 1, (r + l) / 2 + 1, r, al, ar, val);
		}
		else
		{
			return -1;
		}
	}
	else if(l <= ar && r >= al)
	{
		push(v, l, r);
		int t = ans1(v * 2, l, (r + l) / 2, al, ar, val);
		if(t == -1)
		{
			return ans1(v * 2 + 1, (r + l) / 2 + 1, r, al, ar, val);
		}
		return t;
	}
	else
	{
		return -1;
	}
}
signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int q;
	cin >> q;
	vector <int> type(q);
	vector <pair <pair <int, int>, int> > query(q);
	vector <int> uniq;
	for(int i = 0; i < q; i++)
	{
		cin >> type[i];
		if(type[i] == 1)
		{
			int t, s;
			cin >> t >> s;
			query[i] = {{t, s}, -1};
			uniq.push_back(t);
		}
		else if(type[i] == 2)
		{
			int t;
			cin >> t;
			query[i] = {{t, -1}, -1};
			uniq.push_back(t);
		}
		else
		{
			int l, r, v;
			cin >> l >> r >> v;
			query[i] = {{l, r}, v};
		}
	}
	sort(uniq.begin(), uniq.end());
	int m = unique(uniq.begin(), uniq.end()) - uniq.begin();
	tree.resize(4 * m);
	upd.resize(4 * m);
	set <int> timer;
	vector <int> up(m);
	for(int i = 0; i < type.size(); i++)
	{
		if(type[i] == 1)
		{
			int t = query[i].first.first;
			set <int> :: iterator r = timer.lower_bound(t);
			set <int> :: iterator p;
			p = r;
			int it = lower_bound(uniq.begin(), uniq.begin() + m, t) - uniq.begin();
			up[lower_bound(uniq.begin(), uniq.begin() + m, t) - uniq.begin()] = query[i].first.second;
			if(p != timer.begin())
			{
				p--;
				if(r != timer.end())
				{
					int delta = *r - *p;
					int iter = lower_bound(uniq.begin(), uniq.begin() + m, *p) - uniq.begin();
					delta *= up[iter];
					update(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, *r) - uniq.begin(), m - 1, -delta);
				}
			}
			if(r != timer.end()){
				int delta = *r - t;
					delta *= query[i].first.second;
					update(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, *r) - uniq.begin(), m - 1, delta);

			}
			p = r;
			if(p != timer.begin())
			{
				p--;
				int delta = t - *p;
				int iter = lower_bound(uniq.begin(), uniq.begin() + m, *p) - uniq.begin();
				delta *= up[iter];
				update(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, t) - uniq.begin(), m - 1, delta);
			}
			timer.insert(t);
		}
		else if(type[i] == 2){
			int t = query[i].first.first;
			int iter = lower_bound(uniq.begin(), uniq.begin() + m, t) - uniq.begin();
			set <int> :: iterator r = timer.upper_bound(t);
			set <int> :: iterator p = timer.lower_bound(t);
			if(r != timer.end())
			{
				int iter1 = lower_bound(uniq.begin(), uniq.begin() + m, *r) - uniq.begin();
				update(1, 0, m - 1, iter1, m - 1, -(*r - t) * up[iter]);
			}
			if(p != timer.begin())
			{
				p--;
				int iter1 = lower_bound(uniq.begin(), uniq.begin() + m, *p) - uniq.begin();
				update(1, 0, m - 1, iter, m - 1, -(t - *p) * up[iter1]);
				if(r != timer.end())
				{
					update(1,  0, m - 1, iter, m - 1, (*r - *p) * up[iter1]);
				}
			}
			timer.erase(t);
		}
		else
		{
			int l = query[i].first.first;
			int r = query[i].first.second;
			int v = query[i].second;
			set <int> :: iterator it;
			it = timer.lower_bound(l);
			if(timer.size() == 0)
			{
				cout << -1 << "\n";
				continue;
			}
			if(v == 0)
			{
				cout << l << "\n";
			}
			else if(it == timer.begin())
			{
				int u = ans1(1, 0, m - 1, 0, m - 1, v);
				int e = *timer.rbegin();
				if(u == -1 && up[lower_bound(uniq.begin(), uniq.begin() + m, e) - uniq.begin()] >= 0)
				{
					cout << -1 << "\n";
				}
				else if(u == -1)
				{
					int delta = ans(1, 0, m - 1, m - 1) - ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, *it) - uniq.begin());
					v += delta;
					double x = v * 1.0 / (-up[lower_bound(uniq.begin(), uniq.begin() + m, e) - uniq.begin()]);
					x += e;
					if(x > r)
					{
						cout << -1 << "\n";
						continue;
					}
					cout << fixed << setprecision(10) << x << "\n";
				}
				else
				{
					set <int> :: iterator it1;
					it1 = timer.lower_bound(u);
					it1--;
					int delta = ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, *it1) - uniq.begin()) - ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, *it) - uniq.begin());
					v += delta;
					double x =v * 1.0 / (-up[lower_bound(uniq.begin(), uniq.begin() + m, *it1) - uniq.begin()]);
					x += *it1;
					if(x > r)
					{
						cout << -1 << "\n";
						continue;
					}
					cout << fixed << setprecision(10) << x << "\n";
				}
			}
			else if(v == 0)
			{
				cout << l << "\n";
			}
			else if(it == timer.end())
			{
				cout << -1 << "\n";
			}
			else
			{
				set <int> :: iterator it1, it5;
				it1 = it;
				int iter1 = lower_bound(uniq.begin(), uniq.begin() + m, *it) - uniq.begin();
				v -= ans(1, 0, m - 1, iter1);
					int  u = ans1(1, 0, m - 1, iter1, m - 1, v);
					int e = *timer.rbegin();
					int riter = lower_bound(uniq.begin(), uniq.begin() + m, e) - uniq.begin();
					if(u == -1 && up[riter] >= 0)
					{
						cout << -1 << "\n";
					}
					else if(u == -1)
					{
						v += ans(1, 0, m - 1, m - 1);
						double x = v * 1.0 / (-up[riter]);
						x += e;
						if(x > r)
						{
							cout << -1 << "\n";
							continue;
						}
						cout << fixed << setprecision(10) << x << "\n";
					}
					else
					{
						set <int> :: iterator it1;
						it1 = timer.lower_bound(uniq[u]);
						it1--;
						int delta = ans(1, 0, m - 1, lower_bound(uniq.begin(), uniq.begin() + m, *it1) - uniq.begin());
						v += delta;
						double x =v * 1.0 / (-up[lower_bound(uniq.begin(), uniq.begin() + m, *it1) - uniq.begin()]);
						x += *it1;
						if(x > r)
						{
							cout << -1 << "\n";
							continue;
						}
						cout << fixed << setprecision(10) << x << "\n";
					}
			}
		}
	}
    return 0;
}

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
const int inf = 0x3f3f3f3f, N = 6000005;
set<Pii>Set;
ll sum[N],qz[N];int lc[N],rc[N],lzy[N],tot=1;
void init(int k, int v, int L, int R){
	lzy[k]=v;sum[k]=1LL*v*(R-L+1);qz[k]=v>=0?0:sum[k];
}
void upd(int k){
	sum[k]=sum[lc[k]]+sum[rc[k]];
	qz[k]=min(qz[lc[k]],sum[lc[k]]+qz[rc[k]]);
}
void pd(int k, int l, int r){
	if(lzy[k]==inf)return;int mid=(l+r)>>1;
	if(!lc[k])lc[k]=++tot;init(lc[k],lzy[k],l,mid);
	if(!rc[k])rc[k]=++tot;init(rc[k],lzy[k],mid+1,r);
	lzy[k]=inf;
}
void modify(int &k, int l, int r, int v, int L, int R){
	if(!k)k=++tot;
	if(l==L&&r==R){
		init(k,v,L,R);//lzy[k]=v;sum[k]=1LL*v*(R-L+1);qz[k]=v>=0?0:sum[k];
		return;
	}
	pd(k,L,R);
	int mid=(L+R)>>1;
	if(r<=mid)modify(lc[k],l,r,v,L,mid);
	else if(l>mid)modify(rc[k],l,r,v,mid+1,R);
	else modify(lc[k],l,mid,v,L,mid),modify(rc[k],mid+1,r,v,mid+1,R);
	upd(k);
}
ll querysum(int k, int l, int r, int L, int R){
	if(!k)return 0;if(l==L&&r==R)return sum[k];
	int mid=(L+R)>>1;
	pd(k,L,R);
	if(r<=mid)return querysum(lc[k],l,r,L,mid);
	if(l>mid)return querysum(rc[k],l,r,mid+1,R);
	return querysum(lc[k],l,mid,L,mid)+querysum(rc[k],mid+1,r,mid+1,R);
}
int query(int k, int l, int r, ll v, int L, int R){//<=v
	if(!k)return -1;assert(l>=L&&r<=R);
	if(l==L&&r==R){
		if(qz[k]>v)return -1;
		if(L==R)return L;
		int mid=(L+R)>>1;pd(k,L,R);//WA
		if(qz[lc[k]]<=v)return query(lc[k],l,mid,v,L,mid);
		return query(rc[k],mid+1,r,v-sum[lc[k]],mid+1,R);
	}
	int mid=(L+R)>>1;
	pd(k,L,R);
	if(r<=mid)return query(lc[k],l,r,v,L,mid);
	if(l>mid)return query(rc[k],l,r,v,mid+1,R);
	int tmp=query(lc[k],l,mid,v,L,mid);if(tmp>=0)return tmp;
	return query(rc[k],mid+1,r,v-sum[lc[k]],mid+1,R);
}
int main() {//freopen("1.in","r",stdin);freopen("1.ou","w",stdout);
	memset(lzy,inf,sizeof(lzy));qz[0]=1e18;
	int q;read(q);Set.insert(Pii(1,0));Set.insert(Pii(inf,0));
	int rt=1;
	while(q--){
		int op;read(op);
		if(op==1){
			int t,s;read(t);read(s);
			set<Pii>::iterator it=Set.lower_bound(Pii(t,-inf));
			if((*it).fi==t){Set.erase(it);}
			Pii tmp=*Set.upper_bound(Pii(t,inf));
			modify(rt,t,tmp.fi-1,s,1,inf);Set.insert(Pii(t,s));
		}
		else if(op==2){
			int t;read(t);Set.erase(Set.lower_bound(Pii(t,-inf)));//-1 is not small
			set<Pii>::iterator it=Set.upper_bound(Pii(t,inf));
			Pii tmp=*it;it--;int s=(*it).se;//printf("<%d %d %d>\n",t,tmp.fi-1,s);
			modify(rt,t,tmp.fi-1,s,1,inf);
		}
		else{
			int l,r,v;read(l);read(r);read(v);
			if(l==r){
				if(!v)printf("%d\n",l);else puts("-1");
				continue;
			}
			int res=query(rt,l,r-1,-v,1,inf);
			if(res<0)printf("-1\n");
			else{
				ll a=l<=res-1?querysum(rt,l,res-1,1,inf):0,b=querysum(rt,l,res,1,inf);
				//a(res) -v b(res+1)
				printf("%.6lf\n",res+(a==b?0:1.0*(-v-a)/(b-a)));
			//	printf("%d %lld %lld\n",res,a,b);

			}
		}
	}
	return 0;
}

#include <bits/stdc++.h>
#define N 100007
using namespace std;
struct info{int op,t,s,l,r,v;}a[N];
int b[N],s[N],e[N*4],mn[N*4];
long long pre[N*4],sum[N*4],tag[N*4];
int find(int l,int r,int x){
    int res=r;
    while(l<=r){
        int mid=(l+r)>>1;
        if(b[mid]>=x)res=mid,r=mid-1;
        else l=mid+1;
    }
    return res;
}
int lst(int k,int l,int r,int x){
    if(r<=x)
        if(e[k])
            if(l==r)return l;
            else{
                int mid=(l+r)>>1;
                if(e[k*2+1])return lst(k*2+1,mid+1,r,x);
                else return lst(k*2,l,mid,x);
            }
        else return -1;
    int mid=(l+r)>>1;
    if(x>mid){
        int tmp=lst(k*2+1,mid+1,r,x);
        if(tmp!=-1)return tmp;
    }
    return lst(k*2,l,mid,x);
}
int nxt(int k,int l,int r,int x){
    if(x<=l)
        if(e[k])
            if(l==r)return l;
            else{
                int mid=(l+r)>>1;
                if(e[k*2])return nxt(k*2,l,mid,x);
                else return nxt(k*2+1,mid+1,r,x);
            }
        else return -1;
    int mid=(l+r)>>1;
    if(x<=mid){
        int tmp=nxt(k*2,l,mid,x);
        if(tmp!=-1)return tmp;
    }
    return nxt(k*2+1,mid+1,r,x);
}
void put(int k,int l,int r,int x){
    if(l==r){e[k]=x>0;return;}
    int mid=(l+r)>>1;
    if(abs(x)<=mid)put(k*2,l,mid,x);
    else put(k*2+1,mid+1,r,x);
    e[k]=e[k*2]|e[k*2+1];
}
void init(int k,int l,int r){
    mn[k]=l;
    if(l==r)return;
    int mid=(l+r)>>1;
    init(k*2,l,mid);
    init(k*2+1,mid+1,r);
}
void up(int k){
    if(pre[k*2]<sum[k*2]+pre[k*2+1])mn[k]=mn[k*2],pre[k]=pre[k*2];
    else mn[k]=mn[k*2+1],pre[k]=sum[k*2]+pre[k*2+1];
    sum[k]=sum[k*2]+sum[k*2+1];
}
void push(int k,int l,int mid,int r){
    sum[k*2]+=tag[k]*(b[mid+1]-b[l]);
    if(sum[k*2]>0)mn[k*2]=l,pre[k*2]=0;
    else mn[k*2]=mid+1,pre[k*2]=sum[k*2];
    tag[k*2]+=tag[k];
    sum[k*2+1]+=tag[k]*(b[r+1]-b[mid+1]);
    if(sum[k*2+1]>0)mn[k*2+1]=mid+1,pre[k*2+1]=0;
    else mn[k*2+1]=r+1,pre[k*2+1]=sum[k*2+1];
    tag[k*2+1]+=tag[k];
    tag[k]=0;
}
void upd(int k,int l,int r,int L,int R,int delta){
    if(L<=l && r<=R){
        sum[k]+=1LL*delta*(b[r+1]-b[l]);
        if(sum[k]>0)mn[k]=l,pre[k]=0;
        else mn[k]=r+1,pre[k]=sum[k];
        tag[k]+=delta;
        return;
    }
    int mid=(l+r)>>1;
    if(tag[k])push(k,l,mid,r);
    if(L<=mid)upd(k*2,l,mid,L,R,delta);
    if(R>mid)upd(k*2+1,mid+1,r,L,R,delta);
    up(k);
}
long long base;
int pos(int k,int l,int r,int L){
    if(L<=l)
        if(pre[k]<=base)return mn[k];
        else{base-=sum[k];return -1;}
    int mid=(l+r)>>1;
    if(tag[k])push(k,l,mid,r);
    if(L<=mid){
        int tmp=pos(k*2,l,mid,L);
        if(tmp!=-1)return tmp;
    }
    return pos(k*2+1,mid+1,r,L);
}
long long get(int k,int l,int r,int L,int R){
    if(L<=l && r<=R)return sum[k];
    int mid=(l+r)>>1;
    if(tag[k])push(k,l,mid,r);
    long long res=0;
    if(L<=mid)res+=get(k*2,l,mid,L,R);
    if(R>mid)res+=get(k*2+1,mid+1,r,L,R);
    return res;
}
int main(){
    int q,n=0;
    scanf("%d",&q);
    b[++n]=0,b[++n]=1000000001;
    for(int i=1;i<=q;++i){
        scanf("%d",&a[i].op);
        if(a[i].op==1)scanf("%d%d",&a[i].t,&a[i].s),b[++n]=a[i].t;
        if(a[i].op==2)scanf("%d",&a[i].t);
        if(a[i].op==3)scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].v);
    }
    sort(b+1,b+n+1);
    n=unique(b+1,b+n+1)-b-1;
    put(1,1,n,1),put(1,1,n,n);
    init(1,1,n-1);
    for(int i=1;i<=q;++i){
        if(a[i].op==1){
            int x=find(1,n,a[i].t);
            int l=lst(1,1,n,x),r=nxt(1,1,n,x+1);
            put(1,1,n,x);
            upd(1,1,n-1,x,r-1,a[i].s-s[l]);
            s[x]=a[i].s;
        }
        if(a[i].op==2){
            int x=find(1,n,a[i].t);
            int l=lst(1,1,n,x-1),r=nxt(1,1,n,x+1);
            put(1,1,n,-x);
            upd(1,1,n-1,x,r-1,s[l]-s[x]);
        }
        if(a[i].op==3)
            if(!a[i].v)printf("%d\n",a[i].l);
            else{
                int x=find(1,n,a[i].l);
                x=nxt(1,1,n,x);
                base=-a[i].v;
                int y=pos(1,1,n-1,x);
                if(y==-1)puts("-1");
                else{
                    int l=lst(1,1,n,y-1);
                    base=a[i].v+get(1,1,n-1,x,l-1);
                    double ans=(double)base/(-s[l])+b[l];
                    if(ans>(double)a[i].r)puts("-1");
                    else printf("%.8f\n",ans);
                }
            }
    }
}

    #include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

#define pitem item*
#define tam 1023456
#define tamN 12345
using namespace std;
typedef long long ll;

typedef pair<ll,ll> ii;
typedef pair<int,ii> iii;
const ll INF=1e18;
struct item
{
    int prior,cnt;
    ll pos,speed,minn,tot;
    ii pos_viz;
    ii pos_vder;
    pitem l;
    pitem r;
    item(){}
    item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
    {
        prior=rand();
        minn=INF;
        pos_viz=pos_vder=ii(pos,speed);
    }

};
int cnt(pitem t){return t?t->cnt:0;}
ll gtot(pitem t){return t?t->tot:0;}
ll gmin(pitem t){return t?t->minn:INF;}

ll gextraiz(pitem t){
    if (!t|| (!(t->l)))
        return INF;
    else
        return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
}
ll gextrader(pitem t){
    if (!t|| !(t->r))
        return INF;
    return  (t->r->pos_viz.f-t->pos)*(t->speed);
}
void upd_cnt(pitem t)
{
    if (t)
    {
        t->cnt=cnt(t->l)+cnt(t->r)+1;
        ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
        t->tot=totiz;
        t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
        if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
        if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
        t->tot+=gtot(t->r);
        t->minn=gmin(t->l);
        t->minn=min(t->minn,totiz+extraiz);
        t->minn=min(t->minn,totiz+extraiz+extrader);
        t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
        if (t->tot!=0)
        t->minn=min(t->minn,t->tot);
    }
}
void split(pitem t,pitem &l,pitem &r,int key)
{
    if (!t)
        return void(l=r=0);
    if (t->pos>key)
        split(t->l,l,t->l,key),r=t;
    else
        split(t->r,t->r,r,key),l=t;
    upd_cnt(t);
}
void merge(pitem &t,pitem l,pitem r)
{
    if (!l||!r)
        t=l?l:r;
    else if (r->prior>l->prior)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd_cnt(t);
}
ll auxresp;
double respf;ll iz,der;
pitem ant_t;
bool print=false;
void query(pitem t,ll inival)
{

    if (t==0)
    {
        if (!ant_t)
            return void(auxresp=-1);

        // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
        ll extra;
        extra=(der-ant_t->pos)*(ant_t->speed);
        if (inival+extra<=0)
        {
            auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
            if ((inival)/(ant_t->speed)>0)
                cout<<"watultimo\n";
            if (print==1)
                cout<<" aca: ";
            respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
            return;
        }
        else
            return void(auxresp=-1);
    }
    ant_t=t;
    ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
    if (gmin(t->l)+inival<=0)
    {
        query(t->l,inival);
        // cout<<"go left\n";
    }
    else
    {
        ll extraiz,extrader,totiz;
        extraiz=(t->l)?gextraiz(t):0;
        extrader=(t->r)?gextrader(t):0;
        totiz=gtot(t->l);
        ll auxini=totiz+extraiz+extrader;
        // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
        if (totiz+extraiz+inival<=0)
        {
            inival+=totiz;
            auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
            if ((inival)/(t->l->pos_vder.s)>0)
                cout<<"watizquierda\n";
            respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
        }
        else if (totiz+extraiz+extrader+inival<=0)
        {
            inival+=totiz+extraiz;
            auxresp=(t->pos)-(inival)/(t->speed);//-.-
            if (inival/t->speed>0)
                cout<<"watderecha\n";
            respf=-(double)(inival%t->speed)/(t->speed);//-.-

        }
        else
            {

                // cout<<"go right\n";
                query(t->r,auxini+inival);
            }

    }
}

int main()
{
    int casos;
    scanf("%d",&casos);
    if (casos>5000)
        print=1;
    if (casos==100)
        print=1;
    int tipo;
    pitem t1;pitem t2;pitem t3;
    pitem s;
    pitem tree=new item(2e9,1);
    ll val,pos;
    double auxrespf;
    while(casos--)
    {
        scanf("%d",&tipo);
        if (tipo==1)
        {
            scanf("%lld %lld",&pos,&val);
            if (val==0)
            {
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
                continue;
            }
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            s=new item(pos,val);
            merge(tree,t1,s);
            merge(tree,tree,t3);
        }
        else if (tipo==2)
        {
            scanf("%lld",&pos);
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            merge(tree,t1,t3);
        }
        else if (tipo==3)
        {
            scanf("%lld %lld %lld",&iz,&der,&val);
            if (val==0)
            {
                printf("%lld.0\n",iz);
                continue;
            }
            split(tree,t1,t3,der);
            split(t1,t1,t2,iz-1);
            ant_t=NULL;
            query(t2,val);
            if (auxresp==-1)
                printf("-1\n");
            else
            {
                auxrespf=auxresp+respf;
                printf("%.9lf\n",auxrespf);
            }
            merge(tree,t1,t2);
            merge(tree,tree,t3);
        }
     //   inorder(tree);
        //// cout<<endl;
    }
}

#include<bits/stdc++.h>
#define ll long long
#define loop int a[n]; for(i=0;i<n;i++)
#define lloop ll a[n]; for(i=0;i<n;i++)
#define tcase int T; cin>>T; for(int t=1;t<=T;t++)
#define pcase cout<<"Case #"<<t<<": "
#define max(a,b) (a>b?a:b)
#define check(a,b) for(int i=0;i<b;i++) cout<<a[i]<<' '; cout<<endl;
#define pb push_back
#define min(a,b) (a<b?a:b)
#define g(a) (a*(a-1))/2
#define fi first
#define se second
#define M 1000000007
#define pi 3.1415926536
using namespace std;

int a[100005][4];
set<int> st;
vector<pair<ll,ll> > v[500];
vector<int> sp;
int d[100005];
ll an[500];
ll mi[500];
int N;
map<int,int> mp;
void calc(int bl) {
  an[bl]=0;
  mi[bl]=0;
  for(int i=0;i+1<int(v[bl].size());i++) {
    an[bl]=an[bl]+(v[bl][i+1].fi-v[bl][i].fi)*v[bl][i].se;
    mi[bl]=min(an[bl],mi[bl]);
  }
}
double query(int l,int r,ll vt,double s) {
  int pl=(lower_bound(sp.begin(),sp.end(),l)-sp.begin());
  int pr=(upper_bound(sp.begin(),sp.end(),r)-sp.begin()-1);
  while(pl<=pr&&pl%N!=0) {
    if(d[pl]!=M) {
      vt+=(sp[pl]-l)*s;
      if(vt<=0) {
        vt-=(sp[pl]-l)*s;
        return l-vt/s;
      }
      l=sp[pl];
      s=d[pl];
    }
    pl++;
  }
  while(pl+N<=pr) {
    if(v[pl/N].empty()==false) {
      if(vt+(v[pl/N][0].fi-l)*s+mi[pl/N]<=0) {
        break;
      }
      else {
        vt+=(v[pl/N][0].fi-l)*s+an[pl/N];
        l=v[pl/N].rbegin()->fi;
        s=v[pl/N].rbegin()->se;
      }
    }
    pl+=N;
  }
  while(pl<=pr) {
    if(d[pl]!=M) {
      vt+=(sp[pl]-l)*s;
      if(vt<=0) {
        vt-=(sp[pl]-l)*s;
        return l-vt/s;
      }
      l=sp[pl];
      s=d[pl];
    }
    pl++;
  }
  if(vt+(r-l)*s<=0)
    return l-vt/s;
  return -1;
}
int main() {
  ios::sync_with_stdio(false);
  // freopen("input.txt","r",stdin);
  // freopen("output.txt","w",stdout);
  int q;
  cin>>q;
  for(int i=0;i<q;i++) {
    cin>>a[i][0]>>a[i][1];
    if(a[i][0]!=2)
      cin>>a[i][2];
    if(a[i][0]==3)
      cin>>a[i][3];
    if(a[i][0]==1)
      st.insert(a[i][1]);
  }
  int i=0;
  for(set<int>:: iterator it=st.begin();it!=st.end();it++) {
    mp[*it]=i;
    sp.pb(*it);
    d[i]=M;
    i++;
  }
  sp.pb(M);
  mp[M]=i;
  d[i]=M;
  N=sqrt(i)+1;
  cout<<fixed;
  cout<<setprecision(10);
  for(int i=0;i<q;i++) {
    if(a[i][0]==1) {
      int bl=mp[a[i][1]]/N;
      v[bl].pb(pair<ll,ll>(0,0));
      int j=0;
      for(j=int(v[bl].size())-1;j>0&&v[bl][j].fi>a[i][1];j--) {
        v[bl][j]=v[bl][j-1];
      }
      d[mp[a[i][1]]]=a[i][2];
      v[bl][j]=pair<ll,ll>(a[i][1],a[i][2]);
      calc(bl);
    }
    else if(a[i][0]==2) {
      int bl=mp[a[i][1]]/N;
      d[mp[a[i][1]]]=M;
      v[bl].erase(lower_bound(v[bl].begin(),v[bl].end(),pair<ll,ll>(a[i][1],-M)));
      calc(bl);
    }
    else {
      if(a[i][3]==0)
        cout<<a[i][1]<<endl;
      else {
        double ck=query(a[i][1],a[i][2],a[i][3],0);
        if(ck-(ll)ck<1e-7)
          cout<<(ll)ck<<endl;
        else
          cout<<ck<<endl;
      }
    }
  }
}

/*----------------by syr----------------*/
/*
  -----  -----  -----
  |   |  |---|    _/
  |   |  | \_    /
  -----  |   \  -----

  |---\  \   /  |\  /|
  |   |   \_/   | \/ |
  |   |   / \   |    |
  |---/  /   \  |    |
*/
#include<bits/stdc++.h>

using namespace std;

#define PH push
#define MP make_pair
#define PB push_back
#define fst first
#define snd second
#define FOR(i,x,y) for(int i=(x);i<(y);++i)
#define REP(i,x,y) for(int i=(x);i<=(y);++i)
#define x0 x0123456789
#define y0 y0123456789
#define x1 x1234567890
#define y1 y1234567890
#define x2 x2345678901
#define y2 y2345678901
typedef double db;
typedef long long ll;
typedef long double ldb;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int INF=1e9+7;
const int maxn=1e5+5;

class Treap{
private:
	class Node{
	public:
		ll s,t;
		ll l,r;
		ll lst;
		ll sum,mns;
		int ls,rs;
		int fix;
		Node(){}
		Node(ll s,ll t):s(s),t(t),l(s),r(s),lst(t),sum(0),mns(0),ls(0),rs(0),fix(1ll*rand()*rand()%INF){}
		void print(){
			printf("s=%lld t=%lld l=%lld r=%lld lst=%lld sum=%lld mns=%lld ls=%lld rs=%lld\n",s,t,l,r,lst,sum,mns,ls,rs);
			return;
		}
    }dat[maxn<<2];
    int tot;
public:
	int rt;
    void init(){
		rt=tot=0;
		dat[rt]=Node(0,0);
		return;
	}
    int buildNode(ll s,ll t){
		++tot;
		dat[tot]=Node(s,t);
		return tot;
	}
	void pushUp(int x){
		//printf("x=%d\n",x);
		int p=dat[x].ls,q=dat[x].rs;
		if(!p&&!q){
			dat[x].l=dat[x].r=dat[x].s;
			dat[x].lst=dat[x].t;
			dat[x].sum=dat[x].mns=0;
		}
		else if(!p){
			ll res=dat[x].t*(dat[q].l-dat[x].s);
			dat[x].l=dat[x].s;
			dat[x].r=dat[q].r;
			dat[x].lst=dat[q].lst;
			dat[x].sum=dat[q].sum+res;
			dat[x].mns=min(res,res+dat[q].mns);
		}
		else if(!q){
			ll res=dat[p].lst*(dat[x].s-dat[p].r);
			dat[x].l=dat[p].l;
			dat[x].r=dat[x].s;
			dat[x].lst=dat[x].t;
			dat[x].sum=dat[p].sum+res;
			dat[x].mns=min(res,dat[p].mns+res);
		}
		else{
			ll res1=dat[p].lst*(dat[x].s-dat[p].r);
			ll res2=dat[x].t*(dat[q].l-dat[x].s);
			dat[x].l=dat[p].l;
			dat[x].r=dat[q].r;
			dat[x].lst=dat[q].lst;
			dat[x].sum=dat[p].sum+res1+res2+dat[q].sum;
			dat[x].mns=min(min(dat[p].mns,dat[p].sum+res1),min(dat[p].sum+res1+res2,dat[p].sum+res1+res2+dat[q].mns));
		}
		dat[x].mns=min(dat[x].mns,0ll);
		return;
	}
	void split(int u,int &x,int &y,int k){
		if(!u){
			x=y=0;
			return;
		}
		if(dat[u].s>k){
			split(dat[u].ls,x,dat[u].ls,k);
			y=u;
		}
		else{
			split(dat[u].rs,dat[u].rs,y,k);
			x=u;
		}
		pushUp(u);
		return;
	}
	void merge(int &u,int x,int y){
		//printf("merge: u=%d x=%d y=%d\n",u,x,y);
		if(!(x&&y)){
			u=(x|y);
			return;
		}
		if(dat[x].fix>dat[y].fix){
			u=y;
			merge(dat[y].ls,x,dat[y].ls);
		}
		else{
			u=x;
			merge(dat[x].rs,dat[x].rs,y);
		}
		pushUp(u);
		return;
	}
	db query(int u,ll k,ll x,ll y){
		if(dat[u].mns>-k) return -1;
		int p=dat[u].ls,q=dat[u].rs;
		ll res1,res2;
		if(p) res1=dat[p].lst*(dat[u].s-dat[p].r);
		else res1=dat[u].t*(dat[u].s-x);
		if(q) res2=dat[u].t*(dat[q].l-dat[u].s);
		else res2=dat[u].t*(y-dat[u].s);
		if(p&&dat[p].mns<=-k) return query(p,k,x,y);
		else if(p&&dat[p].sum+res1<=-k)	return dat[p].r+1.0*(k+dat[p].sum)/(-dat[p].lst);
		else if(dat[p].sum+res1+res2<=-k) return dat[u].s+1.0*(k+dat[p].sum+res1)/(-dat[u].t);
		else return query(q,k-dat[p].sum+res1+res2,x,y);
	}
	db solve(int u,ll k,ll x,ll y){
		ll res=dat[u].lst*(y-dat[u].r);
		//printf("u=%d %lld %lld %lld\n",u,dat[u].mns,res,k);
		//dat[u].print();
		if(dat[u].mns>-k){
			if(dat[u].sum+res<=-k) return dat[u].r+1.0*(k+dat[u].sum)/(-dat[u].lst);
			else return -1;
		}
		else return query(u,k,x,y);
	}
	void print(){
		printf("root=%d\n",rt);
		REP(u,1,tot){
			printf("u=%d\n",u);
			dat[u].print();
		}
		return;
	}
}trp;

int q;

int main(){
	scanf("%d",&q);
	//trp.init();
	FOR(i,0,q){
		int tp,x,y,z;
		scanf("%d",&tp);
		//trp.print();
		if(tp==1){
			scanf("%d%d",&x,&y);
			int tl,tr,v=trp.buildNode(x,y);
			trp.split(trp.rt,tl,tr,x);
			trp.merge(tl,tl,v);
			trp.merge(trp.rt,tl,tr);
		}
		else if(tp==2){
			scanf("%d",&x);
			int tl,tr,v;
			trp.split(trp.rt,tl,tr,x-1);
			trp.split(tr,v,tr,x);
			trp.merge(trp.rt,tl,tr);
		}
		else{
			scanf("%d%d%d",&x,&y,&z);
			int tl,tr,v;
			if(!z){
				printf("%d\n",x);
				continue;
			}
			trp.split(trp.rt,tl,tr,x-1);
			//trp.print();
			trp.split(tr,v,tr,y);
			//printf("tl=%d tr=%d v=%d\n",tl,tr,v);
			//trp.print();
			printf("%.10f\n",trp.solve(v,z,x,y));
			trp.merge(tr,v,tr);
			trp.merge(trp.rt,tl,tr);
		}
	}
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<set>
#define N_ 200100
#define SZ 262144
#define pli pair<long long,double>
#define pii pair<int,int>
using namespace std;
int X[N_ * 2], CX, INF = 2e9;
int n;
set<pii>Set;
struct point {
	int ck, a, b, c;
}w[N_];
struct Tree {
	long long S[SZ + SZ], M[SZ + SZ], K[SZ + SZ];
	void init() {
		for (int i = 0; i < SZ + SZ; i++)K[i] = INF;
	}
	void Put2(int nd, int b, int e, long long x) {
		S[nd] = x * (X[e + 1] - X[b]);
		M[nd] = min(0ll, S[nd]);
		K[nd] = x;
	}
	void Spread(int nd, int b, int e) {
		if (K[nd] == INF)return;
		int m = (b + e) >> 1;
		Put2(nd * 2, b, m, K[nd]);
		Put2(nd * 2 + 1, m + 1, e, K[nd]);
		K[nd] = INF;
	}
	void UDT(int nd) {
		S[nd] = S[nd * 2] + S[nd * 2 + 1];
		M[nd] = min(M[nd * 2], S[nd * 2] + M[nd * 2 + 1]);
		K[nd] = INF;
	}
	void Put(int nd, int b, int e, int s, int l, long long x) {
		if (b == s&&e == l) {
			Put2(nd, b, e, x);
			return;
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (s <= m)Put(nd * 2, b, m, s, min(m, l), x);
		if (l > m)Put(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x);
		UDT(nd);
	}
	double Go(int nd, int b, int e, long long x) {
		if (b == e) {
			auto it = Set.lower_bound({ e + 1,-INF });
			it--;
			return X[b] + ((long double)-x / it->second);
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (M[nd * 2] + x <= 0) {
			return Go(nd * 2, b, m, x);
		}
		else {
			return Go(nd * 2 + 1, m + 1, e, x + S[nd * 2]);
		}
	}
	pli Calc(int nd, int b, int e, int s, int l, long long x) {
		int m = (b + e) >> 1;
		if (b == s && e == l) {
			if (M[nd] + x <= 0) {
				return { S[nd], Go(nd, b, e, x) };
			}
			return { S[nd], -1.0 };
		}
		Spread(nd, b, e);
		long long ss = 0;
		if (s <= m) {
			pli t = Calc(nd * 2, b, m, s, min(m, l), x);
			if (t.second > -0.5)return t;
			ss = t.first;
		}
		if (l > m) {
			pli t = Calc(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x + ss);
			if (t.second > -0.5)return t;
			ss += t.first;
		}
		return { ss,-1.0 };

	}
}T;
void Ins(int t, int c) {
	int x = lower_bound(X, X + CX, t) - X;
	Set.insert({ x,c });
	auto it = Set.find({ x,c });
	auto et = it; et++;
	T.Put(1, 0, CX - 1, x, et->first - 1, c);
}
void Del(int t) {

	int x = lower_bound(X, X + CX, t) - X;
	auto it = Set.lower_bound({ x,-INF });
	auto bt = it; bt--;
	auto et = it; et++;
	Set.erase(it);
	T.Put(1, 0, CX - 1, bt->first, et->first - 1, bt->second);

}
int main() {
	int i, ck, a = 0, b = 0, c = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++) {
		scanf("%d", &ck);
		if (ck == 1) {
			scanf("%d%d", &a, &b);
			X[CX++] = a;
		}
		if (ck == 2) {
			scanf("%d", &a);
		}
		if (ck == 3) {
			scanf("%d%d%d", &a, &b, &c);
			X[CX++] = a;
			X[CX++] = b;
		}
		w[i] = { ck,a,b,c };
	}
	X[CX++] = 0;
	X[CX++] = 2e9;
	sort(X, X + CX);
	CX = unique(X, X + CX) - X;
	CX--;
	T.init();
	Set.insert({ 0,0 });
	Set.insert({ CX,0 });
	for (i = 1; i <= n; i++) {
		if (w[i].ck == 1) {
			Ins(w[i].a, w[i].b);
		}
		if (w[i].ck == 2) {
			Del(w[i].a);
		}
		if (w[i].ck == 3) {
			int b = lower_bound(X, X + CX, w[i].a) - X;
			int e = lower_bound(X, X + CX, w[i].b) - X;
			if (w[i].c == 0) {
				printf("%d\n", w[i].a);
				continue;
			}
			if (b == e) {
				printf("-1\n");
				continue;
			}
			pli tt = T.Calc(1, 0, CX - 1, b, e - 1, w[i].c);
			if (tt.second < 0) {
				printf("-1\n");
			}
			else {
				printf("%.10f\n", tt.second);
			}
		}
	}
}

#include<cstdio>
#include<algorithm>
#include<set>
#define N_ 200100
#define SZ 262144
#define pli pair<long long,double>
#define pii pair<int,int>
using namespace std;
int X[N_ * 2], CX, INF = 2e9;
int n;
set<pii>Set;
struct point {
	int ck, a, b, c;
}w[N_];
struct Tree {
	long long S[SZ + SZ], M[SZ + SZ], K[SZ + SZ];
	void init() {
		for (int i = 0; i < SZ + SZ; i++)K[i] = INF;
	}
	void Put2(int nd, int b, int e, long long x) {
		S[nd] = x * (X[e + 1] - X[b]);
		M[nd] = min(0ll, S[nd]);
		K[nd] = x;
	}
	void Spread(int nd, int b, int e) {
		if (K[nd] == INF)return;
		int m = (b + e) >> 1;
		Put2(nd * 2, b, m, K[nd]);
		Put2(nd * 2 + 1, m + 1, e, K[nd]);
		K[nd] = INF;
	}
	void UDT(int nd) {
		S[nd] = S[nd * 2] + S[nd * 2 + 1];
		M[nd] = min(M[nd * 2], S[nd * 2] + M[nd * 2 + 1]);
		K[nd] = INF;
	}
	void Put(int nd, int b, int e, int s, int l, long long x) {
		if (b == s&&e == l) {
			Put2(nd, b, e, x);
			return;
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (s <= m)Put(nd * 2, b, m, s, min(m, l), x);
		if (l > m)Put(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x);
		UDT(nd);
	}
	double Go(int nd, int b, int e, long long x) {
		if (b == e) {
			auto it = Set.lower_bound({ e + 1,-INF });
			it--;
			if (it->second >= 0) {
				while (1) {}
			}
			return X[b] + ((double)-x / it->second);
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (M[nd * 2] + x <= 0) {
			return Go(nd * 2, b, m, x);
		}
		else {
			return Go(nd * 2 + 1, m + 1, e, x + S[nd * 2]);
		}
	}
	pli Calc(int nd, int b, int e, int s, int l, long long x) {
		int m = (b + e) >> 1;
		if (b == s && e == l) {
			if (M[nd] + x <= 0) {
				return { S[nd], Go(nd, b, e, x) };
			}
			return { S[nd], -1.0 };
		}
		Spread(nd, b, e);
		long long ss = 0;
		if (s <= m) {
			pli t = Calc(nd * 2, b, m, s, min(m, l), x);
			if (t.second > -0.5)return t;
			ss = t.first;
		}
		if (l > m) {
			pli t = Calc(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x + ss);
			if (t.second > -0.5)return t;
			ss += t.first;
		}
		return { ss,-1.0 };

	}
}T;
void Ins(int t, int c) {
	int x = lower_bound(X, X + CX, t) - X;
	auto iit = Set.lower_bound({ x,-INF });
	if (iit->first == x) {
		while (1) {}
	}
	Set.insert({ x,c });
	auto it = Set.find({ x,c });
	auto et = it; et++;
	T.Put(1, 0, CX - 1, x, et->first - 1, c);
}
void Del(int t) {

	int x = lower_bound(X, X + CX, t) - X;
	auto it = Set.lower_bound({ x,-INF });
	auto bt = it; bt--;
	auto et = it; et++;
	if (it->first != x) {
		while (1) {}
	}
	Set.erase(it);
	T.Put(1, 0, CX - 1, bt->first, et->first - 1, bt->second);

}
int main() {
	int i, ck, a = 0, b = 0, c = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++) {
		scanf("%d", &ck);
		if (ck == 1) {
			scanf("%d%d", &a, &b);
			X[CX++] = a;
		}
		if (ck == 2) {
			scanf("%d", &a);
		}
		if (ck == 3) {
			scanf("%d%d%d", &a, &b, &c);
			X[CX++] = a;
			X[CX++] = b;
		}
		w[i] = { ck,a,b,c };
	}
	X[CX++] = 0;
	X[CX++] = 2e9;
	sort(X, X + CX);
	CX = unique(X, X + CX) - X;
	CX--;
	T.init();
	Set.insert({ 0,0 });
	Set.insert({ CX,0 });
	for (i = 1; i <= n; i++) {
		if (w[i].ck == 1) {
			Ins(w[i].a, w[i].b);
		}
		if (w[i].ck == 2) {
			Del(w[i].a);
		}
		if (w[i].ck == 3) {
			int b = lower_bound(X, X + CX, w[i].a) - X;
			int e = lower_bound(X, X + CX, w[i].b) - X;
			if (w[i].c == 0) {
				printf("%d\n", w[i].a);
				continue;
			}
			if (b == e) {
				printf("-1\n");
				continue;
			}
			pli tt = T.Calc(1, 0, CX - 1, b, e - 1, w[i].c);
			if (tt.second < 0) {
				printf("-1\n");
			}
			else {
				printf("%.10f\n", tt.second);
			}
		}
	}
}

#include <sstream>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
#include <cassert>
#include <bitset>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)

#define DEBUG
#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define deputs(str) fprintf(stderr, "%s\n",str)
#else
#define debug(...)
#define deputs(str)
#endif // DEBUG
typedef unsigned long long ULL;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long long LL;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e5+107;
const double pi=acos(-1.0);
const double eps=0.0000000001;
LL gcd(LL a, LL b) {return b?gcd(b,a%b):a;}
template<typename T>inline void pr2(T x,int k=64) {ll i; REP(i,k) debug("%d",(x>>i)&1); putchar(' ');}
template<typename T>inline void add_(T &A,int B,ll MOD=M) {A+=B; (A>=MOD) &&(A-=MOD);}
template<typename T>inline void mul_(T &A,ll B,ll MOD=M) {A=(A*B)%MOD;}
template<typename T>inline void mod_(T &A,ll MOD=M) {A%=MOD; A+=MOD; A%=MOD;}
template<typename T>inline void max_(T &A,T B) {(A<B) &&(A=B);}
template<typename T>inline void min_(T &A,T B) {(A>B) &&(A=B);}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a, T b) {
	T ret=1;
	for (; b; b>>=1ll,a=(LL)a*a%M)
		if (b&1) ret=(LL)ret*a%M;
	return ret;
}
int startTime;
void startTimer() {startTime=clock();}
void printTimer() {debug("/--- Time: %ld milliseconds ---/\n",clock()-startTime);}

struct node{
	int l,r;
	int lpos,rm,value;//rm:maxi
	ll maxused,used;//lpos+(v-used)/value
	node():lpos(0),rm(0),value(0),maxused(0),used(0){l=r=0;};
}T[maxn*50]; int tot;
void merge(node &ret,node A,node B) {//避免l,r被改
	if (!A.lpos) {
		ret.lpos=B.lpos; ret.rm=B.rm;
		ret.value=B.value;
		ret.maxused=B.maxused; ret.used=B.used;
		return;
	} if (!B.lpos) {
		ret.lpos=A.lpos; ret.rm=A.rm;
		ret.value=A.value;
		ret.maxused=A.maxused; ret.used=A.used;
		return;
	} ret.maxused=max(A.maxused,A.used+(ll)(B.rm-A.lpos)*A.value+B.maxused);
	ret.lpos=B.lpos; ret.value=B.value; ret.rm=A.rm;
	ret.used=A.used+(ll)(B.rm-A.lpos)*A.value+B.used;
} int root;
int op,t,s,l,r,v;
void update(int &x,int L,int R) {//starttime
	if (!x) x=++tot;
	if (L==R) {//lpos:start_time(position)
		if (op==1) T[x].lpos=T[x].rm=t,T[x].value=s;
		else T[x].lpos=T[x].rm=0,T[x].value=0;
		return;
	} int mid=(L+R)/2;
	if (t<=mid) update(T[x].l,L,mid);
	else update(T[x].r,mid+1,R);
	merge(T[x],T[T[x].l],T[T[x].r]);
	// printf("update : %d %d   %d %d %lld %lld _l=%d %d; used=%lld\n"
	// 	,L,R,T[x].lpos,T[x].value,T[x].maxused,T[x].used,T[T[x].l].lpos,T[T[x].r].lpos,T[T[x].l].used);
} double ans;
node now;
void query(int x,int L,int R) {//(l,R]时间段内
	if (ans>=0) return;
	if (l<=L&&R<=r) {
		node tmp;
		merge(tmp,now,T[x]);
		if (!x) {
			if (tmp.used+(ll)(R-tmp.lpos)*tmp.value>=v){
				if (tmp.value<=0) ans=L;
				else ans=tmp.lpos+1.*(v-tmp.used)/tmp.value;
			} return;
		}
		// printf("check: (%d-%d) now=%d %d %lld %lld; chk=%lld: v=%d\n",
		// 	L,R,tmp.lpos,tmp.value,tmp.maxused,tmp.used,tmp.used+(ll)(R-tmp.lpos)*tmp.value,v);
		if (tmp.maxused>=v||tmp.used+(ll)(R-tmp.lpos)*tmp.value>=v) {//not
			// printf("query: %d %d: okay\n",L,R);
			if (L==R) {//tmp.maxused=0; must tmp.value>0
				assert(tmp.used+(ll)(R-tmp.lpos)*tmp.value>=v);
				assert(!(!tmp.lpos&&tmp.value));
				if (tmp.value<=0) ans=L;
				else ans=tmp.lpos+1.*(v-tmp.used)/tmp.value;
				ans=max(ans,1.*L);
			} int mid=(L+R)/2;
			query(T[x].l,L,mid);
			query(T[x].r,mid+1,R);
			if (ans>=0) return;
			puts("no way 2");
		} else {
			now=tmp; return;
		}
	} int mid=(L+R)/2;
	if (l<=mid) query(T[x].l,L,mid);
	if (mid<r) query(T[x].r,mid+1,R);
}
int main() {
	int q,i;
	scanf("%d",&q);
	FOR(i,1,q){
		scanf("%d",&op);
		if (op==1) {
			scanf("%d%d",&t,&s); s=-s;
			update(root,1,1000000000);
		} else if (op==2) {
			scanf("%d",&t);
			update(root,1,1000000000);
		} else {
			scanf("%d%d%d",&l,&r,&v);
			ans=-1; now=node();
			query(root,1,1000000000);
			// printf("query %d %d %lld %lld\n",now.lpos,now.value,now.maxused,now.used);
			printf("%.10f\n",ans);
		}
		// now=T[1];
		// printf("_i: %d %d %lld %lld\n",now.lpos,now.value,now.maxused,now.used);
	}

}
/*
10
1 1 1000000000
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 500 1000000000
1 322 1000000000
1 500000000 -1000000000
3 1 1000000000 1
3 1 1000000000 1000000000
3 100 1000000000 1
*/

#include<cstdio>
#include<algorithm>
#include<set>
#define double long double
#define N_ 200100
#define SZ 262144
#define pli pair<long long,double>
#define pii pair<int,int>
using namespace std;
int X[N_*2], CX, INF = 2e9;
int n;
set<pii>Set;
struct point {
	int ck, a, b, c;
}w[N_];
struct Tree{
	long long S[SZ + SZ], M[SZ + SZ], K[SZ + SZ];
	void init() {
		for (int i = 0; i < SZ + SZ; i++)K[i] = INF;
	}
	void Put2(int nd, int b, int e, long long x) {
		S[nd] = x * (X[e + 1] - X[b]);
		M[nd] = min(0ll, S[nd]);
		K[nd] = x;
	}
	void Spread(int nd, int b, int e) {
		if (K[nd] == INF)return;
		int m = (b + e) >> 1;
		Put2(nd * 2, b, m, K[nd]);
		Put2(nd * 2 + 1, m + 1, e, K[nd]);
		K[nd] = INF;
	}
	void UDT(int nd) {
		S[nd] = S[nd * 2] + S[nd * 2 + 1];
		M[nd] = min(M[nd * 2], S[nd * 2] + M[nd * 2 + 1]);
	}
	void Put(int nd, int b, int e, int s, int l, long long x) {
		if (b == s&&e == l) {
			Put2(nd, b, e, x);
			return;
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (s <= m)Put(nd * 2, b, m, s, min(m, l), x);
		if (l > m)Put(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x);
		UDT(nd);
	}
	double Go(int nd, int b, int e, long long x) {
		if (b == e) {
			auto it = Set.lower_bound({ e+1,-INF });
			it--;
			return X[b] + ((double)-x / it->second);
		}
		Spread(nd, b, e);
		int m = (b + e) >> 1;
		if (M[nd * 2] + x <= 0) {
			return Go(nd * 2, b, m, x);
		}
		else {
			return Go(nd * 2 + 1, m + 1, e, x + S[nd * 2]);
		}
	}
	pli Calc(int nd, int b, int e, int s, int l, long long x) {
		int m = (b + e) >> 1;
		if (b == s && e == l) {
			if (M[nd] + x <= 0) {
				return { S[nd], Go(nd, b, e, x) };
			}
			return { S[nd], -1.0 };
		}
		Spread(nd, b, e);
		long long ss = 0;
		if (s <= m) {
			pli t = Calc(nd * 2, b, m, s, min(m, l), x);
			if (t.second > -0.5)return t;
			ss = t.first;
		}
		if (l > m) {
			pli t = Calc(nd * 2 + 1, m + 1, e, max(m + 1, s), l, x+ss);
			if (t.second > -0.5)return t;
			ss += t.first;
		}
		return { ss,-1.0 };

	}
}T;
void Ins(int t, int c) {
	int x = lower_bound(X, X + CX, t) - X;
	Set.insert({ x,c });
	auto it = Set.find({ x,c });
	auto et = it; et++;
	T.Put(1, 0, CX - 1, x, et->first - 1, c);
}
void Del(int t) {

	int x = lower_bound(X, X + CX, t) - X;
	auto it = Set.lower_bound({ x,-INF });
	auto bt = it; bt--;
	auto et = it; et++;
	Set.erase(it);
	T.Put(1, 0, CX - 1, bt->first, et->first - 1, bt->second);

}
int main() {
	int i, ck, a=0, b=0, c=0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++) {
		scanf("%d", &ck);
		if (ck == 1) {
			scanf("%d%d", &a, &b);
			X[CX++] = a;
		}
		if (ck == 2) {
			scanf("%d", &a);
		}
		if (ck == 3) {
			scanf("%d%d%d", &a,&b,&c);
			X[CX++] = a;
			X[CX++] = b;
		}
		w[i] = { ck,a,b,c };
	}
	X[CX++] = 0;
	X[CX++] = 2e9;
	sort(X, X + CX);
	CX = unique(X, X + CX) - X;
	CX--;
	T.init();
	Set.insert({ 0,0 });
	Set.insert({ CX,0 });
	for (i = 1; i <= n; i++) {
		if (w[i].ck == 1) {
			Ins(w[i].a, w[i].b);
		}
		if (w[i].ck == 2) {
			Del(w[i].a);
		}
		if (w[i].ck == 3) {
			int b = lower_bound(X, X + CX, w[i].a) - X;
			int e = lower_bound(X, X + CX, w[i].b) - X;
			if (w[i].c == 0) {
				printf("%d\n", w[i].a);
				continue;
			}
			pli tt = T.Calc(1, 0, CX - 1, b, e - 1, w[i].c);
			if (tt.second < 0) {
				printf("-1\n");
			}
			else {
				printf("%.10Lf\n", tt.second);
			}
		}
	}
}

#include <bits/stdc++.h>
#define watch(x) std::cout << "$ LINE @" << __LINE__ << " FUNC @" << __FUNCTION__ << "\n$ " \
                           << (#x) << ": " << x << std::endl

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

template <typename Tp>
inline void read(Tp &x)
{
    static char c;
    static bool neg;
    x = 0, c = getchar(), neg = false;
    for (; !isdigit(c); c = getchar())
    {
        if (c == '-')
        {
            neg = true;
        }
    }
    for (; isdigit(c); c = getchar())
    {
        x = x * 10 + c - '0';
    }
    if (neg)
    {
        x = -x;
    }
}

typedef pair<double, ll> pdl;

const int INF = 1e9 + 5;
const int N = 1e5 + 5;

int q;

namespace Seg
{
#define lson son[0]
#define rson son[1]

    struct Node
    {
        Node *son[2];
        bool flag;
        int set;
        ll sum, lsum;
        inline void pushUp();
        inline void pushDown(int, int);
        inline void setVal(int);
        inline void ensureLeft();
        inline void ensureRight();
        inline void ensureBoth();
    };

    inline Node *newNode()
    {
        Node *res = new Node();
        res->son[0] = res->son[1] = nullptr;
        res->flag = false;
        res->set = 0;
        res->sum = res->lsum = 0LL;
        return res;
    }
    inline void Node::pushUp()
    {
        ensureBoth();
        sum = lson->sum + rson->sum;
        lsum = std::min(lson->lsum, lson->sum + rson->lsum);
    }
    inline void Node::pushDown(int l, int r)
    {
        if (flag)
        {
            int mid = (l + r) >> 1;
            ensureBoth();
            lson->flag = rson->flag = true;
            lson->set = rson->set = set;
            lson->sum = (ll)(mid - l + 1) * set;
            lson->lsum = set >= 0 ? 0 : lson->sum;
            rson->sum = (ll)(r - mid) * set;
            rson->lsum = set >= 0 ? 0 : rson->sum;
            flag = false;
        }
    }
    inline void Node::ensureLeft()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
    }
    inline void Node::ensureRight()
    {
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    inline void Node::ensureBoth()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    void update(Node *u, int l, int r, int ul, int ur, int x)
    {
        if (ul <= l && r <= ur)
        {
            u->flag = true;
            u->set = x;
            u->sum = (ll)(r - l + 1) * x;
            u->lsum = x >= 0 ? 0 : u->sum;
            return;
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        if (ul <= mid)
        {
            u->ensureLeft();
            update(u->lson, l, mid, ul, ur, x);
        }
        if (mid < ur)
        {
            u->ensureRight();
            update(u->rson, mid + 1, r, ul, ur, x);
        }
        u->pushUp();
    }
    pdl query(Node *u, int l, int r, int ql, int qr, ll x)
    {
        if (ql <= l && r <= qr)
        {
            if (u->lsum + x > 0)
            {
                return (pdl){-1.0, u->sum};
            }
            if (l == r)
            {
                return (pdl){(double)l - (double)x / (double)u->sum, u->sum};
            }
            if (u->flag)
            {
                return (pdl){(double)l - (double)x / (double)(u->sum / (ll)(r - l + 1)), u->sum};
            }
            int mid = (l + r) >> 1;
            u->ensureBoth();
            pdl res = query(u->lson, l, mid, ql, qr, x);
            if (res.first > 0)
            {
                return res;
            }
            else
            {
                pdl pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
                return (pdl){pir.second, res.second + pir.second};
            }
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        pdl res = (pdl){-1.0, 0}, pir;
        bool tag = false;
        if (ql <= mid)
        {
            tag = true;
            u->ensureLeft();
            res = query(u->lson, l, mid, ql, qr, x);
        }
        if (mid < qr)
        {
            if (tag)
            {
                if (res.first > 0)
                {
                    return res;
                }
                else
                {
                    x += res.second;
                }
            }
            u->ensureRight();
            pir = query(u->rson, mid + 1, r, ql, qr, x);
            res = (pdl){pir.first, res.second + pir.second};
        }
        return res;
    }

#undef lson
#undef rson
} // namespace Seg

int main()
{
    read(q);
    map<int, int> timeline;
    int L = 1, R = INF;
    timeline[L - 1] = timeline[R + 1] = 0;
    auto root = Seg::newNode();
    for (int i = 0, op, x, y, z; i < q; ++i)
    {
        read(op);
        if (op == 1)
        {
            read(x), read(y);
            timeline[x] = y;
            Seg::update(root, L, R - 1, x, std::min(next(timeline.find(x))->first, R) - 1, y);
        }
        else if (op == 2)
        {
            read(x);
            auto iter = timeline.find(x);
            Seg::update(root, L, R - 1, x, std::min(next(iter)->first, R) - 1, prev(iter)->second);
            timeline.erase(iter);
        }
        else
        {
            read(x), read(y), read(z);
            if (z == 0)
            {
                printf("%d\n", x);
            }
            else
            {
                x = timeline.lower_bound(x)->first;
                if (x >= y)
                {
                    puts("-1");
                }
                else
                {
                    auto ans = Seg::query(root, L, R - 1, x, y - 1, z);
                    if (ans.first < 0)
                    {
                        puts("-1");
                    }
                    else
                    {
                        printf("%.8f\n", ans.first);
                    }
                }
            }
        }
    }
}

#include<bits/stdc++.h>
using namespace std;

const int maxn = 200010;
const int inf = 1.01e9;

struct segtree{
	segtree *ch[2];
	int l, r, setv;
	long long minv, sumv;

	segtree():minv(0), sumv(0), setv(-inf){
		ch[0] = ch[1] = NULL;
	}

	void pushdown(){
		if (setv == -inf) return;
		minv = sumv = 1ll * setv * (r - l + 1);
		minv = min(minv, 0ll);
		if(l != r){
			assert(ch[0] && ch[1]);
			ch[0]->setv = setv;
			ch[1]->setv = setv;
		}
		setv = -inf;
	}

	void maintain(){
		assert(ch[0] && ch[1]);
		assert(ch[0]->setv == -inf);
		assert(ch[1]->setv == -inf);
		sumv = ch[0]->sumv + ch[1]->sumv;
		minv = min(ch[0]->minv, ch[0]->sumv + ch[1]->minv);
	}
};

segtree *pool;
int nd_rest = 0;

inline segtree* newnode(int l, int r){
	if (!nd_rest) pool = new segtree[50000], nd_rest = 50000;
	segtree *ret = pool + (--nd_rest);
	ret->l = l;
	ret->r = r;
	return ret;
}

int ql, qr, rest, val;
double ans;

void modify(segtree *o){
	int mid = o->l + (o->r - o->l) / 2;
	if (!o->ch[0]) o->ch[0] = newnode(o->l, mid);
	if (!o->ch[1]) o->ch[1] = newnode(mid + 1, o->r);
	o->pushdown();
	if (qr < o->l || o->r < ql) return;
	if (ql <= o->l && o->r <= qr){
		o->setv = val;
		o->pushdown();
		return;
	}
	modify(o->ch[0]);
	modify(o->ch[1]);
	o->maintain();
}

void query(segtree *o){
	int mid = o->l + (o->r - o->l) / 2;
	if (!o->ch[0]) o->ch[0] = newnode(o->l, mid);
	if (!o->ch[1]) o->ch[1] = newnode(mid + 1, o->r);
	o->pushdown();
	if (rest == 0) return;
	if (qr < o->l || o->r < ql) return;
	if (ql <= o->l && o->r <= qr){
		if (o->minv + rest > 0) {
			rest += o->sumv;
			return;
		}
	}
	if (o->l == o->r) {
		//cout << o->l << endl;
		ans = o->l - 1.0 * rest / o->sumv;
		rest = 0;
		return;
	}
	query(o->ch[0]);
	query(o->ch[1]);
	o->maintain();
}

segtree* root;
set <pair<int, int> > event;

void add(int t, int s){
	event.insert(make_pair(t, s));
	auto now = event.lower_bound(make_pair(t, inf));
	ql = t; qr = now->first - 1; val = s;
	//cout << ql << " " << qr << " " << val << "+ " << endl;
	modify(root);
}

void del(int t){
	auto now = event.lower_bound(make_pair(t, -inf));
	auto pre = now; pre --;
	auto nxt = now; nxt ++;
	ql = pre->first; qr = (nxt->first) - 1; val = pre->second;
	//cout << ql << " " << qr << " " << val << "- " << endl;
	modify(root);
	event.erase(now);
}

void query(int l, int r, int v){
	if(!v){
		cout << l << endl;
		return;
	}
	int flag = 0;
	auto now = event.lower_bound(make_pair(l, -inf));
	if (now->first != l){
		flag = 1;
		add(l, 0);
	}
	ans = -1;
	ql = l; qr = r - 1; rest = v;
	//cout << ql << " " << qr << " " << rest << "= " << endl;
	query(root);
	if (ans == -1){
		puts("-1");
	} else {
		printf("%.10f\n", ans);
	}
	if (flag) del(l);
}

int q, opt, t, s, l, r, v;

int main(){
	event.insert(make_pair(0, 0));
	event.insert(make_pair(inf, 0));
	root = newnode(0, 1000000000);
	cin >> q;
	for (int i = 1; i <= q; i ++){
		scanf("%d", &opt);
		if (opt == 1){
			scanf("%d%d", &t, &s);
			add(t, s);
		} else if (opt == 2){
			scanf("%d", &t);
			del(t);
		} else {
			scanf("%d%d%d", &l, &r, &v);
			query(l, r, v);
		}
	}
	return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <random>
#include <climits>
#include <iomanip>
#include <queue>
#include <bitset>
#include <cctype>

using namespace std;

#define forn(i,n) for (int i = 0;i < int(n);i++)
#define ford(i,n) for (int i = n-1;i >=0;i--)
#define fore(i,l,r) for (int i = int(l);i < int(r);i++)
#define forv(a) for(int i = 0;i < (a).size();i++) cin >> a[i]
#define correct(x,n) (((x) >= 0) && ((x) < n))
#define sort_all(a) sort((a).begin(),(a).end())
#define mp(a,b) make_pair((a),(b))
#define all(a) (a).begin(),(a).end()
#define pb(a) push_back(a)
#define rnd() (rand() + (RAND_MAX+1)*rand())
#define fi first
#define se second
#define V(A) vector<A>
//#define DEBUG_

//#define x first
//#define y second

typedef long long li;
typedef vector<int> vi;
typedef vector<li> vli;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<vi> vvi;
typedef vector<vli> vvli;
typedef long double ld;
typedef pair<li, li> Point;

const ld EPS = 1e-9;

class Node
{
public:
	li key,pr,s;
	li mn, mx, smx,d,dmn;//Min t,max t, s of max t,d,and minimum of d in subtree
	Node* l, *r;
	Node() {}

	Node(li key, li s) : key(key), s(s), mn(key), pr(rnd()), mx(key), smx(s),d(0),dmn(0),l(nullptr),r(nullptr) {}
};

typedef Node* DTree;

li getMin(DTree t)
{
	if (!t)
		return 1500000000;
	return t->mn;
}

li getMax(DTree t)
{
	if (!t)
		return 0;
	return t->mx;
}

li getSMax(DTree t)
{
	if (!t)
		return 0;
	return t->smx;
}

li getD(DTree t)
{
	if (!t)
		return 0;
	return t->d;
}

li getDMin(DTree t)
{
	if (!t)
		return 0;
	return t->dmn;
}

void update(DTree t)
{
	if (!t)
		return;

	t->mn = min(t->key, getMin(t->l));
	t->mx = max(t->key, getMax(t->r));

	if (t->key > getMax(t->r))
		t->smx = t->s;
	else
		t->smx = getSMax(t->r);

	li d = 0, dmn = 0;
	dmn = min(dmn, getDMin(t->l));
	d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	dmn = min(dmn, d);
	d += (t->r ? t->s*(getMin(t->r) - t->key) : 0);
	dmn = min(dmn, d + getDMin(t->r));
	d += getD(t->r);
	dmn = min(dmn, d);
	t->d = d;
	t->dmn = dmn;
}

void split(DTree t, DTree &l, DTree &r,li key)
{
	if (!t)
	{
		l = r = nullptr;
		return;
	}
	if (key < t->key)
		split(t->l, l, t->l, key), r = t;
	else
		split(t->r, t->r, r, key), l = t;
	update(t);
}

void merge(DTree &t, DTree l, DTree r)
{
	if (!l || !r)
	{
		t = (l ? l : r);
		return;
	}
	if (l->pr > r->pr)
		merge(l->r, l->r, r), t = l;
	else
		merge(r->l, l, r->l), t = r;
	update(t);
}

void insert(DTree &t,li key,li s)
{
	DTree tl, tm = new Node(key, s), tr;
	split(t, tl, tr, key);
	merge(t, tl, tm);
	merge(t, t, tr);
}

void erase(DTree &t, li key)
{
	DTree tl, tm, tr;
	split(t, tl, tm, key-1);
	split(tm, tm, tr, key);
	merge(t, tl, tr);
}

double getAns(DTree t,li r,li v)
{
	if (!t)
		return -1;

	if (t->dmn + v > 0)
		return (t->smx >= 0 || t->mx * t->smx - (t->d + v) < r * t->smx ? -1 : t->mx - (ld)(t->d + v) / t->smx);

	li dl = getDMin(t->l);
	li d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	li dr = d + (t->r ? t->s*(getMin(t->r) - t->key) : 0);

	if (dl + v <= 0)
		return getAns(t->l, r, v);

	if (d + v <= 0)
		return getMax(t->l) - (ld)(v + dl) / getSMax(t->l);

	if (dr + v <= 0)
		return t->key - (ld)(v + d) / t->s;

	return getAns(t->r, r, v + dr);
}

double getAns(DTree t, li l, li r, li v)
{
	if (!v)
		return l;
	DTree tl, tm,tr;
	split(t, tl, tm, l - 1);
	split(tm, tm, tr, r);
	double ans = getAns(tm, r, v);
	merge(t, tl, tm);
	merge(t, t, tr);
	return ans;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	DTree t = nullptr;

	int n;
	cin >> n;
	forn(i, n)
	{
		int q;
		cin >> q;
		if (q == 1)
		{
			li key, s;
			cin >> key >> s;
			insert(t, key, s);
		}
		if (q == 2)
		{
			li key;
			cin >> key;
			erase(t, key);
		}
		if (q == 3)
		{
			li l, r, v;
			cin >> l >> r >> v;
			cout << setprecision(20) << getAns(t, l, r, v) << '\n';
		}
	}
}

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <cstring>
#include <unordered_map>

using namespace std;

#define double long double
#define ll long long
#define all(aaa) aaa.begin(), aaa.end()
#pragma warning(disable : 4996)

const int N = 2e5 + 5;
ll mn[N * 4], sum[N * 4], wt[N * 4], up[N * 4], t[N * 4];
bool tup[N];
int z[N];
vector<vector<int>> qr;
vector<int> w;
set<int> st;
int n;

void push(int v, int L, int R) {
	if (tup[v]) {
		if (L != R) {
			up[v * 2] = up[v];
			up[v * 2 + 1] = up[v];
			tup[v * 2] = tup[v * 2 + 1] = 1;
		}
		sum[v] = up[v] * (w[R + 1] - w[L]);
		mn[v] = up[v] > 0 ? 0 : sum[v];
		t[v] = up[v];
		tup[v] = 0;
	}
}

ll ques(int l, int r, int v = 1, int L = 0, int R = n - 2) {
	push(v, L, R);
	if (l > r)
		return 0;
	if (l == L && r == R)
		return sum[v];
	int m = (L + R) >> 1;
	return ques(l, min(m, r), v * 2, L, m) +
		ques(max(m + 1, l), r, v * 2 + 1, m + 1, R);
}

double que(int l, int r, ll pref1, ll pref2,
	int v = 1, int L = 0, int R = n - 2) {
	push(v, L, R);
	if (l > r || mn[v] + pref2 - pref1 > 0)
		return -1;
	if (L == R) {
		return w[L] + (pref2 - pref1) * 1.0 / -t[v];
	}
	int m = (L + R) >> 1;
	double x = que(l, min(m, r), pref1, pref2, v * 2, L, m);
	if (x < 0)
		return que(max(m + 1, l), r, pref1, pref2 + sum[v * 2], v * 2 + 1, m + 1, R);
	return x;
}

void upd(int l, int r, int x, int v = 1, int L = 0, int R = n - 2) {
	push(v, L, R);
	if (l > r)
		return;
	if (L == l && r == R) {
		up[v] = x;
		tup[v] = 1;
		push(v, L, R);
	}
	else {
		int m = (L + R) >> 1;
		upd(l, min(m, r), x, v * 2, L, m);
		upd(max(m + 1, l), r, x, v * 2 + 1, m + 1, R);
		mn[v] = min(mn[v * 2], sum[v * 2] + mn[v * 2 + 1]);
		sum[v] = sum[v * 2] + sum[v * 2 + 1];
	}
}

int getIndex(int x) {
	return lower_bound(all(w), x) - w.begin();
}

signed main() {
#ifdef HOME
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int q;
	cin >> q;

	for (int i = 0; i < q; i++) {
		int type;
		cin >> type;
		int t, s;

		if (type == 1) {
			cin >> t >> s;
			w.push_back(t);
			qr.push_back({ type, t, s });
		}
		else if (type == 2) {
			cin >> t;
			qr.push_back({ type, t });
		}
		else {
			int l, r, v;
			cin >> l >> r >> v;
			w.push_back(l);
			w.push_back(r);
			qr.push_back({ type, l, r, v });
		}
	}

	w.push_back(-1);
	w.push_back((int)2e9);
	sort(all(w));
	w.erase(unique(all(w)), w.end());

	n = w.size();

	st.insert(n - 1);
	st.insert(0);

	cout << fixed;
	cout << setprecision(20);

	for (int i = 0; i < q; i++) {
		if (qr[i][0] == 1) {
			int t = qr[i][1], s = qr[i][2];
			t = getIndex(t);
			auto it = st.upper_bound(t);
			upd(t, (*it) - 1, s);
			st.insert(t);
			z[t] = s;
		}
		else if (qr[i][0] == 2) {
			int t = qr[i][1];
			t = getIndex(t);
			st.erase(t);
			auto it = st.upper_bound(t);
			upd(t, (*it) - 1, z[*prev(it)]);
		}
		else {
			int l = *st.lower_bound(getIndex(qr[i][1])),
				r = getIndex(qr[i][2]) - 1,
				v = qr[i][3];
			if (v == 0) {
				cout << (double)qr[i][1] << "\n";
				continue;
			}
			ll ps = ques(0, l - 1);
			double ans = que(l, r, ps, v);
			if (ans < 0)
				cout << -1;
			else
				cout << ans;
			cout << "\n";
		}
	}

	return 0;
}

#include <bits/stdc++.h>
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
#define LL long long
#define db long double
#define INF 1e15;
using namespace std;
const int maxn = 200010;
LL t[maxn * 2];
LL add[maxn * 2];
map<LL, int> mp;
int m;
db ans, v;
struct OP{
	LL id, x, y, z;
};
OP op[maxn];
set<int> s;
set<int>::iterator it, it1, it2;
struct SegmentTree {
	LL sum, lsum, Set;
	int l, r;
	bool flag;
};
SegmentTree tr[maxn * 4];
void pushup(int o) {
	tr[o].sum = tr[ls(o)].sum + tr[rs(o)].sum;
	tr[o].lsum = min(tr[ls(o)].lsum, tr[ls(o)].sum + tr[rs(o)].sum);
}
void maintain(int o, LL val) {
	tr[o].sum = val * (t[tr[o].r + 1] - t[tr[o].l]);
	tr[o].lsum = min(0ll, tr[o].sum);
	tr[o].Set = val;
	tr[o].flag = 1;
}
void pushdown(int o) {
	if(tr[o].flag) {
		maintain(ls(o), tr[o].Set);
		maintain(rs(o), tr[o].Set);
		tr[o].flag = 0;
	}
}
void build(int o, int l, int r) {
	tr[o].l = l, tr[o].r = r;
	if(l == r) {
		tr[o].flag = 0;
		tr[o].sum = 0;
		tr[o].lsum = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(ls(o), l, mid);
	build(rs(o), mid + 1, r);
	pushup(o);
}
void update(int o, int l, int r, int ql, int qr, LL val) {
	if(l >= ql && r <= qr) {
		maintain(o, val);
		return;
	}
	pushdown(o);
	int mid = (l + r) >> 1;
	if(ql <= mid) update(ls(o), l, mid, ql, qr, val);
	if(qr > mid) update(rs(o), mid + 1, r, ql, qr, val);
	pushup(o);
}
void query(int o, int l, int r, int ql, int qr) {
	if(ql > qr) return;
	if(l == r) {
		if(tr[o].lsum + v > 0) {
			v += tr[o].sum;
			return;
		}
		db tmp = v / (-(1.0 * tr[o].Set));
		if(tmp < 0 || (tmp + t[l] > t[qr + 1])) {
			v += tr[o].sum;
			return;
		}
		ans = tmp + t[l];
		return;
	}
	pushdown(o);
	int mid = (l + r) >> 1;
	if(l >= ql && r <= qr) {
		if(tr[o].lsum + v > 0) {
			v += tr[o].sum;
			return;
		}
		if(v + tr[ls(o)].lsum <= 0) {
			query(ls(o), l, mid, ql, qr);
			if(ans != -1) return;
		}
		v += tr[ls(o)].sum;
		if(v + tr[rs(o)].lsum <= 0) {
			query(rs(o), mid + 1, r, ql, qr);
			return;
		}
		v += tr[rs(o)].sum;
		return;
	}
	if(ql <= mid) query(ls(o), l, mid, ql, qr);
	if(ans != -1) return;
	if(qr > mid) query(rs(o), mid + 1, r, ql, qr);
}
int main() {
	int n;
	scanf("%d", &n);
	int cnt = 0;
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &op[i].id);
		if(op[i].id == 1) {
			scanf("%lld%lld", &op[i].x, &op[i].y);
			t[++cnt] = op[i].x;
		} else if(op[i].id == 2) {
			scanf("%lld", &op[i].x);
			t[++cnt] = op[i].x;
		} else {
			scanf("%lld%lld%lld", &op[i].x, &op[i].y, &op[i].z);
			t[++cnt] = op[i].x;
			t[++cnt] = op[i].y;
		}
	}
	sort(t + 1, t + 1 + cnt);
	m = unique(t + 1, t + 1 + cnt) - (t + 1);
	for (int i = 1; i <= m; i++) {
		mp[t[i]] = i;
	}
	t[m + 1] = 1e9 + 1;
	t[0] = 0;
	build(1, 1, m);
	s.insert(m + 1);
	s.insert(0);
	for (int i = 1; i <= n; i++) {
		if(op[i].id == 1) {
			s.insert(mp[op[i].x]);
			it = s.lower_bound(mp[op[i].x]);
			it++;
			update(1, 1, m, mp[op[i].x], (*it) - 1, op[i].y);
			add[mp[op[i].x]] = op[i].y;
		} else if(op[i].id == 2) {
			it = s.lower_bound(mp[op[i].x]);
			it1 = it, it2 = it;
			it1--, it2++;
			int num;
			if((*it1) == 0) {
				num = 1;
			} else {
				num = (*it1);
			}
			update(1, 1, m, num, (*it2) - 1, add[num]);
			add[*it] = 0;
			s.erase(it);
		} else {
			ans = -1;
			v = op[i].z;
			if(v == 0) {
				printf("%d\n", op[i].x);
				continue;
			}
			it = s.lower_bound(mp[op[i].x]);
			query(1, 1, m, *it, mp[op[i].y] - 1);
//			if(ans == -1) printf("-1\n");
//			else printf("%.7lf\n", ans);
//			cout << ans <<endl;
			cout << ans <<endl;
		}
	}
}

#include <bits/stdc++.h>
#define FR first
#define SE second

using namespace std;

typedef double db;

typedef long long ll;
typedef pair<ll,int> pr;

int num[300005];

namespace SGT {

ll sumv[1200000],minn[1200000],setv[1200000];

inline void pushdown(int l,int r,int o) {
  if (setv[o]!=-1) {
  	int m=((l+r)>>1);
  	sumv[o*2]=setv[o]*(num[m+1]-num[l]);minn[o*2]=min(0LL,sumv[o*2]);
  	sumv[o*2+1]=setv[o]*(num[r+1]-num[m+1]);minn[o*2+1]=min(0LL,sumv[o*2+1]);
  	setv[o*2]=setv[o*2+1]=setv[o];
  	setv[o]=-1;
  }
}

inline void pushup(int o) {
  sumv[o]=sumv[o*2]+sumv[o*2+1];
  minn[o]=min(minn[o*2],sumv[o*2]+minn[o*2+1]);
}

void update(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) {
  	sumv[o]=p*(num[r+1]-num[l]);minn[o]=min(0LL,sumv[o]);
  	setv[o]=p;
  }
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=lx) update(l,m,o*2,lx,rx,p);
  	if (m<rx) update(m+1,r,o*2+1,lx,rx,p);
  	pushup(o);
  }
}

pr query2(int l,int r,int o,ll p) {
  if (l==r) return pr(p,l);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (p+minn[o*2]<=0) return query2(l,m,o*2,p);
  	else return query2(m+1,r,o*2+1,p+sumv[o*2]);
  }
}

pr query1(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) return (p+minn[o]<=0)?query2(l,r,o,p):pr(p+sumv[o],-1);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query1(l,m,o*2,lx,rx,p);
  	if (m<lx) return query1(m+1,r,o*2+1,lx,rx,p);
  	pr a=query1(l,m,o*2,lx,rx,p);
  	if (a.SE!=-1) return a;
	return query1(m+1,r,o*2+1,lx,rx,a.FR);
  }
}

ll query3(int l,int r,int o,int p) {
  if (l==r) return setv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=p) return query3(l,m,o*2,p);
  	else return query3(m+1,r,o*2+1,p);
  }
}

}

struct Ope {
  int l,r,v,kind;
  Ope() {}
  Ope(int a,int b,int c,int d):l(a),r(b),v(c),kind(d) {}
};

Ope a[100005];
set <int> st;

int main() {
  int m;
  scanf("%d",&m);
  int n=0;
  for(int i=1;i<=m;i++) {
  	int kind;
  	scanf("%d",&kind);
  	if (kind==1) {
  		int x,y,z;
  		scanf("%d%d",&x,&y);
  		a[i]=Ope(x,x,y,1);
  		num[++n]=x;
	  }
	else if (kind==2) {
		int x;
		scanf("%d",&x);
		a[i]=Ope(x,x,0,2);
		num[++n]=x;
	}
	else {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		a[i]=Ope(x,y,z,3);
		num[++n]=x;num[++n]=y;
	}
  }
  num[++n]=0;num[++n]=1e9+1;
  sort(num+1,num+n+1);
  n=unique(num+1,num+n+1)-num-1;
  st.insert(1);st.insert(n);
  for(int i=1;i<=m;i++)
    if (a[i].kind==1) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	st.insert(t);
    	set<int>::iterator it=st.lower_bound(t);
    	it++;
    	int t2=(*it);
    	SGT::update(1,n,1,t,t2-1,a[i].v);
	}
	else if (a[i].kind==2) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	set<int>::iterator it=st.lower_bound(t),it2=it;
    	it--;it2++;
    	int t1=(*it),t2=(*it2);
    	st.erase(t);
    	SGT::update(1,n,1,t,t2-1,SGT::query3(1,n,1,t1));
	}
	else {
        if (!a[i].v) {
        	printf("%d\n",a[i].l);
        	continue;
		}
		int l=lower_bound(num+1,num+n+1,a[i].l)-num,r=lower_bound(num+1,num+n+1,a[i].r)-num-1;
		if (l>r) {
			puts("-1");
			continue;
		}
		pr t=SGT::query1(1,n,1,l,r,a[i].v);
		if (t.SE!=-1) {
			int v=SGT::query3(1,n,1,t.SE);
			printf("%.10f\n",num[t.SE]+(db)(-t.FR)/v);
		}
		else puts("-1");
	}
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define null NULL
#define mp make_pair
#define pb(a) push_back(a)
#define sz(a) ((int)(a).size())
#define all(a) a.begin() , a.end()
#define fi first
#define se second
#define relaxMin(a , b) (a) = min((a),(b))
#define relaxMax(a , b) (a) = max((a),(b))
#define SQR(a) ((a)*(a))
#define PI 3.14159265358979323846
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

int Rand(){
  return (rand() << 10) ^ rand();
}

const int SZ = 300;
const int MAX = 100010;

struct Block {
  ll add, start, end;
  int type;

  Block(ll _add, ll _start, ll _end,
        int _type){
    add = _add;
    start = _start;
    end = _end;
    type = _type;
  }

  double Zeroes(ll v){
    if(v + (end - start + 1) * add <= 0){
      return start + (v + 0.0) / abs(add);
    } else {
      return -1;
    }
  }

  ll Min(ll v){
    return min(v, v + (end - start + 1) * add);
  }

  ll AtEnd(ll v){
    return v + (end - start + 1) * add;
  }
};

typedef list<Block>::iterator Iter;
ll minv[MAX], at_end[MAX];
Iter lo[MAX], hi[MAX];

map<int, Iter> loc;

list<Block> arr;

void Init(){
  loc[0] = arr.insert(arr.begin(), Block(0, 0, 1E9 + 10, -1));
}

void RebuildBlock(Iter pos){
  int id = pos->type;
  lo[id] = hi[id] = pos;

  while(lo[id] != arr.begin() && (--Iter(lo[id]))->type == id)
    --lo[id];
  while((++Iter(hi[id])) != arr.end() &&
        (++Iter(hi[id]))->type == id)
    ++hi[id];

  ll val = 0;
  minv[id] = val;
  pos = lo[id];
  do{
    relaxMin(minv[id], pos->Min(val));
    val = pos->AtEnd(val);
    if(pos == hi[id]) break;
    ++pos;
  }while(true);

  at_end[id] = val;
}

void Build(){
  int cid = -1;
  Iter pos = arr.begin();

  while(pos != arr.end()){
    ++cid;
    lo[cid] = pos;
    hi[cid] = pos;
    ll val = 0;
    minv[cid] = val;
    for(int i = 0;i < SZ && pos != arr.end();++i){
      pos->type = cid;
      hi[cid] = pos;
      relaxMin(minv[cid], pos->Min(val));
      val = pos->AtEnd(val);
      ++pos;
    }
  }
}

void Delete(int t){
  Iter it = loc[t];
  int me = it->type;

  Iter par = it;
  --par;

  par->end = it->end;
  arr.erase(it);
  loc.erase(t);

  RebuildBlock(par);
  ++par;
  if(par != arr.end() && me == par->type)
    RebuildBlock(par);
}

void Insert(int t, ll add){
  auto it = loc.lower_bound(t);
  --it;

  Iter sp = it->se;
  Block neo(add, t, sp->end, sp->type);
  sp->end = t - 1;

  loc[t] = arr.insert(++sp, neo);
  RebuildBlock(loc[t]);
}

double FirstZero(int l, int r, ll v){
  if(v == 0) return l;

  auto start = loc.lower_bound(l);

  if(start == loc.end()){
    if(v == 0) return l;
    return -1;
  }

  Iter pos = start->se;
  int fg = pos->type;

  ll bal = v;

  while(true){
    if(pos == arr.end()) return -1;
    if(pos->start > r) return -1;

    if(pos->type != fg){
      int id = pos->type;
      if(minv[id] + bal > 0){
        fg = pos->type;
        bal = at_end[id] + bal;
        pos = hi[id];
        ++pos;
        continue;
      }
    }

    double zp = pos->Zeroes(bal);
    if(zp > -0.5 && zp < r + 1E-9) return zp;

    bal = pos->AtEnd(bal);
    fg = pos->type;
    ++pos;
  }
}

int main(){
  Init();
  Build();

  int n = 100000;
  scanf("%d", &n);

  int mods = 0;
  for(int i = 0;i < n;++i){
    if(mods % SZ == SZ - 1) Build();
    int op;
    scanf("%d", &op);
    if(op == 1){
      ++mods;
      int t, s;
      scanf("%d%d", &t, &s);
      Insert(t, s);
    } else if(op == 2){
      int t;
      scanf("%d", &t);
      Delete(t);
    } else if(op == 3){
      int l, r, v;
      scanf("%d%d%d", &l, &r, &v);
      double res = FirstZero(l, r, v);
      if(res < -0.5) printf("-1\n");
      else printf("%.12f\n", res);
    }
  }

  return 0;
}

#include<bits/stdc++.h>
#define mid (l+r>>1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int mn = 1e5+10;
int aa[mn], bb[mn], cc[mn], dd[mn];
vector<int>use;
map<int, int> m;
int siz(int x) {
	return use[x + 1] - use[x];
}
ll seg[1<<20], laz[1<<20],lo[1<<20];
void prop(int x, int l, int r) {
	if (laz[x] == 0x3f3f3f3f3f3f3f3f)return;
	seg[x] = laz[x] * (use[r + 1] - use[l]);
	lo[x] = min(0LL, seg[x]);
	if (x < 1 << 19) {
		laz[x * 2] = laz[x];
		laz[x * 2 + 1] = laz[x];
	}
	laz[x] = 0x3f3f3f3f3f3f3f3f;
}
void calc(int x, int l, int r) {
	prop(x * 2, l, mid);
	prop(x * 2 + 1, mid + 1, r);
	seg[x] = seg[x * 2] + seg[x * 2 + 1];
	lo[x] = min(lo[x * 2], lo[x * 2 + 1] + seg[x * 2]);
}
void update(int x, int l, int r, int a, int b, ll c) {
	if (a == l && b == r) {
		laz[x] = c;
	}
	else {
		prop(x, l, r);
		if (b <= mid)update(x * 2, l, mid, a, b, c);
		else if (a > mid)update(x * 2 + 1, mid + 1, r, a, b, c);
		else update(x * 2, l, mid, a, mid, c), update(x * 2 + 1, mid + 1, r, mid + 1, b, c);
		calc(x, l, r);
	}
}
double val(int x, int l, int r, int a, int b) {
	if (b < a)return 0;
	prop(x, l, r);
	if (a == l && b == r)return seg[x];
	else {
		if (b <= mid)return val(x * 2, l, mid, a, b);
		else if (a > mid)return val(x * 2 + 1, mid + 1, r, a, b);
		else return val(x * 2, l, mid, a, mid) + val(x * 2 + 1, mid + 1, r, mid + 1, b);
	}
}
double query(int x, int l, int r,int a,ll c) {
	prop(x, l, r);
	prop(x * 2, l, mid);
	if (l == r) {
		double ans = 1.0*c / (seg[x] / siz(l));
		if (ans < 0)return siz(l);
		return min(0.0 + siz(l),ans );
	}
	if (lo[x*2]>c||a>mid)return use[mid + 1] - use[l] + query(x * 2 + 1, mid + 1, r,a, c - seg[x * 2]);
	else return query(x * 2, l, mid,a, c);
}
ll s[3 * mn];
int main() {
	int n,i;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d%d", aa + i, bb + i);
		if (aa[i] == 1)scanf("%d", cc + i);
		if (aa[i] == 3)scanf("%d%d",cc+i, dd + i);
		use.push_back(bb[i]);
		if(aa[i]==3)use.push_back(cc[i]);
	}
	use.push_back(0x3f3f3f3f);
	use.push_back(0);
	sort(use.begin(), use.end());
	use.resize(distance(use.begin(), unique(use.begin(), use.end())));
	for (i = 1; i < use.size(); i++)m[use[i]] = i;
	set<int> tms;
	tms.insert(0);
	int tot = use.size()-2;
	tms.insert(tot+1);
	memset(laz, 0x3f, sizeof(laz));
	for (i = 0; i < n; i++) {
		if (aa[i] == 1) {
			ll t = m[bb[i]];
			set<int>::iterator it = tms.upper_bound(t);
			update(1, 1, tot, t, (*it) - 1, cc[i]);
			tms.insert(t);
			s[t] = cc[i];
		}
		else if (aa[i] == 2) {
			ll t = m[bb[i]];
			set<int>::iterator it = --tms.find(t),it2=tms.upper_bound(t);
			update(1, 1, tot, t, (*it2) - 1, s[*it]);
			tms.erase(t);
			s[t] = 0;
		}
		else {
			ll add = val(1, 1, tot, 1, m[bb[i]] - 1);
			double ans = query(1, 1, tot,m[bb[i]],add-dd[i])+use[1];
			if (ans>cc[i])printf("-1\n");
			else printf("%lf\n", ans);
		}
	}
}

#include <bits/stdc++.h>

using namespace std;

const int N = 200010;
const int K = sqrt(N) + 1;
const int INF = (int)1e9 + 10;
const long long INF_LL = (long long)2e18;

int q, k;
vector<int> a[N];
vector<int> moment;
int val[N];

struct Bucket {
    int cnt, firstApp, lastS;
    long long minVal, delta;

    Bucket(int cnt = 0, int firstApp = -1, int lastS = -INF, long long minVal = 0, long long delta = 0) :
        cnt(cnt), firstApp(firstApp), lastS(lastS), minVal(minVal), delta(delta) {}

    void reset() {
        cnt = 0;
        firstApp = -1;
        lastS = -INF;
        minVal = 0;
        delta = 0;
    }

    void debug() {
        cerr << cnt << ' ' << firstApp << ' ' << lastS << ' ' << minVal << ' ' << delta << endl;
    }
} b[N / K + 10];

void init() {
    sort(moment.begin(), moment.end());
    moment.resize(unique(moment.begin(), moment.end()) - moment.begin());
}

void updateBucket(int pos) {
    int u = pos / k;
    b[u].reset();
    int curS = 0;
    for (int i = k * u; i < min(k * (u + 1), (int)moment.size() - 1); i++) {
        if (val[i] == INF) {
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        } else {
            b[u].cnt++;
            if (b[u].firstApp == -1) b[u].firstApp = i;
            curS = val[i];
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        }
        b[u].minVal = min(b[u].minVal, b[u].delta);
    }
    b[u].lastS = curS;
}

bool go(long long &v, int &curS, int l, int r, double &res) {
    for (int i = l; i < r; i++) {
        if (val[i] != INF) curS = val[i];
        if (v + 1ll * curS * (moment[i + 1] - moment[i]) <= 0ll) {
            res = -1.0 * v / curS + moment[i];
            return 1;
        }
        v += 1ll * curS * (moment[i + 1] - moment[i]);
    }
    return 0;
}

double getRes(int l, int r, long long v) {
    l = lower_bound(moment.begin(), moment.end(), l) - moment.begin();
    r = lower_bound(moment.begin(), moment.end(), r) - moment.begin();
    if (v == 0) return moment[l];
    if (moment.size() == 1) {
        return -1;
    }
    r--;
    int ll = l / k;
    int rr = r / k;
    if (ll == rr) {
        int curS = 0;
        double res = -1;
        if (go(v, curS, l, r + 1, res)) return res;
        else return -1;
    }
    int curS = 0;
    double res = -1;
    if (go(v, curS, l, min(k * (ll + 1), (int)moment.size() - 1), res)) return res;
    for (int i = ll + 1; i < rr; i++) {
        if (b[i].cnt == 0) continue;
        int foo = moment[b[i].firstApp] - moment[i * k];
        if (v + 1ll * curS * foo <= 0ll) {
            return -1.0 * v / curS + moment[i * k];
        }
        v += 1ll * curS * foo;
        if (v + b[i].minVal <= 0) {
            if (go(v, curS, i * k, min(k * (i + 1), (int)moment.size() - 1), res)) return res;
        } else {
            v += b[i].delta;
            curS = b[i].lastS;
        }
    }
    if (go(v, curS, k * rr, r + 1, res)) return res;
    return -1;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        int op;
        cin >> op;
        a[i].push_back(op);
        if (op == 1) {
            int t, s;
            cin >> t >> s;
            moment.push_back(t);
            a[i].push_back(t);
            a[i].push_back(s);
        } else if (op == 2) {
            int t;
            cin >> t;
            moment.push_back(t);
            a[i].push_back(t);
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            moment.push_back(l);
            moment.push_back(r);
            a[i].push_back(l);
            a[i].push_back(r);
            a[i].push_back(v);
        }
    }
    init();
    k = sqrt(moment.size()) + 1;

    for (int i = 0; i < moment.size(); i++) val[i] = INF;
    for (int i = 1; i <= q; i++) {
        if (a[i][0] == 1) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = a[i][2];
            updateBucket(pos);
        } else if (a[i][0] == 2) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = INF;
            updateBucket(pos);
        } else {
            double ans = getRes(a[i][1], a[i][2], a[i][3]);
            if (ans < 0) cout << -1 << '\n';
            else cout << fixed << setprecision(10) << ans << '\n';
        }
        // cerr << "q " << i << ' ' << endl;
        // for (int i = 0; i < (int)moment.size() / k; i++) {
        //     cerr << "number " <<  i << ' ' ;
        //     b[i].debug();
        // }
    }
    return 0;
}

#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
using namespace std;

int n,rt,tot;
struct data{
	int t,v,l,r,rv,ch[2],fa;
	LL mins,s;
	data(){t=v=l=r=rv=ch[0]=ch[1]=fa=mins=s=0;}
}t[maxn];

#define lc t[x].ch[0]
#define rc t[x].ch[1]
void upd(int x){
	LL c1 = lc ? (t[x].t-t[lc].r) * 1ll * t[lc].rv : 0 , c2 = rc ? (t[rc].l-t[x].t) * 1ll * t[x].v : 0;
	t[x].s = t[lc].s + c1 + c2 + t[rc].s;
	t[x].mins =
		min(
			min(t[lc].mins,t[lc].s + c1),
			min(t[lc].s+c1+c2,t[lc].s+c1+c2+t[rc].mins)
		);
	t[x].l=lc?t[lc].l:t[x].t;
	t[x].r=rc?t[rc].l:t[x].t;
	t[x].rv=rc?t[rc].rv:t[x].v;
}
#define il inline
il int inr(int x){ return t[t[x].fa].ch[1]==x; }
void rot(int x){
	int y = t[x].fa , z = t[y].fa , c = inr(x);
	if(z) t[z].ch[inr(y)]=x;
	(t[y].ch[c]=t[x].ch[!c]) && (t[t[y].ch[c]].fa=y);
	t[t[t[x].ch[!c]=y].fa=x].fa=z;
	upd(y),upd(x);
}
void splay(int x,int goal){
	if(x<=0) return;
	for(int y;t[x].fa!=goal;rot(x))
		if(t[y=t[x].fa].fa!=goal) rot(inr(x)^inr(y)?x:y);
	upd(x);
	if(goal == 0) rt = x;
}
int Insert(int &now,data &v,int ff){
	//printf("%d %d %d %d\n",t[now].t,now,t[now].ch[0],t[now].ch[1]);
	if(!now){ t[now=++tot]=v,t[now].fa=ff,upd(now);	return now; }
	if(v.t == t[now].t){
		t[now].t = v.t , t[now].v = v.v;
		upd(now);return now;
	}
	int d = v.t > t[now].t;
	int ret = Insert(t[now].ch[d],v,now);
	upd(now);
	return ret;
}
void Delete(int &x){
	if(!rc){
		t[lc].fa = t[x].fa;
		x = lc;
		return;
	}
	Delete(rc);
	upd(x);
}
int Suc(int T){
	int ret = 0 , Min = 0x3f3f3f3f;
	for(int x=rt;x;){
		//printf("%d\n",rt);
		if(t[x].t>T && Min>t[x].t) Min = t[x].t,ret = x;
		if(t[x].t<=T) x=rc;
		else x=lc;
	}
	return ret;
}
int Pre(int T){
	int ret = 0 , Max = -0x3f3f3f3f;
	for(int x=rt;x;){
		if(t[x].t<T && Max<t[x].t) Max=t[x].t,ret=x;
		if(t[x].t>=T) x=lc;
		else x=rc;
	}
	return ret;
}
int Q;
double Query(int x,int r,LL v){
	if(!x) return -1;
	if(Q>=5000 && t[x].t>=3921 && t[x].t<=4738)printf("%d\n",x);
	if(v+t[lc].mins<=0) return Query(lc,t[x].t,v);
	LL c1 = lc ? (t[x].t-t[lc].r) * 1ll * t[lc].rv : 0 , c2 = rc ? (t[rc].l-t[x].t) * 1ll * t[x].v : (r-t[x].t) * 1ll * t[x].v;
	v+=t[lc].s;
	if(Q>=5000 && t[x].t>=3921 && t[x].t<=4738)printf("%d %d %d %lld %lld %lld %d\n",t[x].t,t[lc].r,t[lc].rv,c1,c2,v,t[x].t);
	if(lc && v+c1<=0) return -1.0 * v / t[lc].rv + t[lc].r;
	v+= c1;
	if(v+c2<=0) return -1.0 * v / t[x].v + t[x].t;
	v+= c2;
	return Query(rc,r,v);
}

int main(){
	//freopen("1.out","w",stdout);
	int q,op,l,r,v;
	for(scanf("%d",&q),Q=q;q--;){
		scanf("%d%d",&op,&l);
		if(op == 2){
			int tmp = Suc(l);
			splay(tmp,0);
			if(tmp) Delete(t[rt].ch[0]),upd(rt);
			else Delete(rt);
		}
		if(op == 1){
			scanf("%d",&r);
			data tmp={};
			tmp.t=l,tmp.v=r;
			//puts("@");
			splay(Insert(rt,tmp,0),0);
		}
		if(op == 3){
			scanf("%d%d",&r,&v);
			if(v == 0){
				printf("%d\n",l);
				continue;
			}
			int L = Pre(l);
			int R = Suc(r);
			splay(L,0),splay(R,L);
			if(R) l=t[R].ch[0];
			else if(L) l=t[L].ch[1];
			else l=rt;
			//if(Q>=5000)printf("%d %d %d %d %d %d %d\n",l,r,v,rt,L,R,t[l].t);
			double ret = Query(l,r,v);
			if(ret < 0) puts("-1");
			else printf("%.10lf\n",ret);
		}
	}
}

#pragma GCC optimize("Ofast")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define int lld
typedef int64_t lld;
typedef pair<int,int> pii;
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(),(x).end()
//#define endl '\n'
#define jizz cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

template<typename Iter>
ostream& _out(ostream &s, Iter b, Iter e) {
    s<<"[";
    for ( auto it=b; it!=e; it++ ) s<<(it==b?"":" ")<<*it;
    s<<"]";
    return s;
}
template<class T1,class T2>
ostream& operator<<(ostream& out, pair<T1,T2> p) {
    return out << '(' << p.first << ", " << p.second << ')';
}
template<class T1,class T2>
istream& operator>>(istream& in, pair<T1,T2>& p) {
    return in >> p.ff >> p.ss;
}
template<typename T>
ostream& operator <<( ostream &s, const vector<T> &c ) {
     return _out(s,c.begin(),c.end());
}
template<typename T, size_t N>
ostream& operator <<( ostream &s, const array<T, N> &c ) {
     return _out(s,c.begin(),c.end());
}
inline char readchar() {
	const int S = 1<<20; // buffer size
	static char buf[S], *p = buf, *q = buf;
	if(p == q && (q = (p=buf)+fread(buf,1,S,stdin)) == buf) return EOF;
	return *p++;
}
inline void input(int &_x){
    _x = 0;
    int _tmp = 1; char _tc = readchar();
    while(_tc < '0' || _tc > '9') _tc = readchar();
    while(_tc >= '0' && _tc <= '9') _x = (_x<<1)+(_x<<3)+(_tc-48), _tc = readchar();
}
inline void output(int _x){
    char _buff[20]; int _f = 0;
    if(_x == 0) putchar('0');
    while(_x > 0){
            _buff[_f++] = _x%10+'0';
            _x /= 10;
    }
    for(_f-=1; _f >= 0; _f--)
            putchar(_buff[_f]);
  putchar('\n');
}

inline int ran(){
    static int x = 71222217;
    return x = (x*0xdefaced+1)&INT_MAX;
}

struct Q{
    lld a = 0; int b = 1;
    Q& operator+(int x){
        a+=(lld)x*b; return *this;
    }
    bool operator>(int x){
        return a>(lld)b*x;
    }
    friend ostream& operator<<(ostream& out, Q x){
        return out << (long double)x.a/x.b;
    }
    Q(int aa = 0, int bb = 1){ a = aa, b = bb; if(b<0)b = -b, a = -a; }
};

struct node{
    node *L = 0, *R = 0;
    int a; lld b; // a(t-l) + b;
    int l, r, alt = 0, pri;
    lld mins = LLONG_MAX;
    node(int l, int r, int a, int b) : l(l), r(r), a(a), b(b) {
        pri = ran(); up();
    }
    void upda(int x){ mins+=x, b+=x, alt+=x; }
    void down(){ if(L)L->upda(alt); if(R)R->upda(alt); alt = 0; }
    void up(){ mins = min(b, val()); if(L)mins = min(mins, L->mins); if(R)mins = min(mins, R->mins); }
    tuple<node*, node*, node*> split(int i){
        down();
        if(i < l){
            //while(!L);
            try{
            auto [a, b, c] = L->split(i);
            L = c; up();
            return {a, b, this};
            }catch(int x){ while(i >= x && i < l);exit(0); }
        } else if(i >= r){
            if(!R)throw r;
            try{
            auto [a, b, c] = R->split(i);
            R = a; up();
            return {this, b, c};
            }catch(int x){ exit(0); }
        } else {
            auto a = L, b = R;
            L = R = 0; up();
            return {a, this, b};
        }
    }
    static node* merge(node *a, node *b){
        if(!a)return b; if(!b)return a;
        if(a -> pri < b -> pri){
            a->down();
            a->R = merge(a->R, b);
            a -> up();
            return a;
        }else{
            b->down();
            b->L = merge(a, b->L);
            b-> up();
            return b;
        }
    }
    node* last(){return R?R->last():this; } node*first(){ return L?L->first():this; }
    static node* merge(vector<node*> a){
        node *n = 0;
        for(auto i: a){
                if(n&&i)assert(n->last()->r == i->first()->l);
                n = merge(n, i);
        }
        return n;
    }
    Q find(int x){
        down();
        //cout << x << " " << show() << endl;
        if(L && L->mins <= x)return L->find(x);
        if(val() <= x)
            return inverse(x);
        if(R)return R->find(x);
        throw 0;
    }
    lld setlast(int x){
        if(R){
            down();
            auto a = R->setlast(x);
            up();
            return a;
        }else return r = x, val();
    }
    void assertlast(){ if(R)R->assertlast(); else if(r < 1000000000) while(true); }
    pair<pii, pair<int, lld>> show(){ return  make_pair(make_pair(l, r), make_pair(a, b)); }
    ostream& print(ostream& out){
        down();
        if(L)L->print(out);
        out << show() << " ";
        if(R)R->print(out);
        return out;
    }
    lld val(int x = -1){ if(x<0)x=r; return (lld)a*(x-l)+b; } // a(x-l)=(y-b)/a
    Q inverse(lld y){ return (a?Q(y-b, a):Q())+l; }
} *root = new node(0, 1000100000, 0, 0);

ostream& operator<<(ostream& out, node* n){
    if(!n)return out << "NULL";
    return n->print(out);
}

vector<int> u, v, uu, vv;
signed main(){jizz; //freopen("test.in", "r", stdin);
#ifdef LOCAL
freopen("test.in", "r", stdin);
#endif
    int q;
    cin >> q;
    cout << setprecision(20) << fixed;
    try{
        root->assertlast();
    for(int i = 0; i < q; i++){
        //root->assertlast();
        int a;
        cin >> a;
        //cout << root << endl;
        if(a == 1){
            int t, s;
            cin >> t >> s;t++;
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!m);
            lld prev = m->val();
            if(m->l == t){
                m->a = s;
                if(r)r->upda(m->val()-prev);
                root = node::merge({l, m, r});
            }else{
                int mr = m->r; m->r = t;
                node* x = new node(t, mr, s, m->val());
                if(r)r->upda(x->val()-prev);
                root = node::merge({l, m, x, r});
            }
        }
        if(a == 2){
            int t;
            cin >> t;t++;
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!l); while(!m);while(m->l != t);
            auto newval = l->setlast(m->r);
            if(r)r->upda(newval-m->val());
            root = node::merge({l, r});
            delete m;
        }
        if(a == 3){
            int t, rr, v;
            cin >> t >> rr >> v;
            if(!v){ cout << t << endl; continue; }
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!m);
            lld start = m->val(t)-v;
            if(m->val()<=start){ cout << m->inverse(start) << endl; continue; }
            if(!r){ cout << -1 << endl; continue; }
            try{
                auto ans = r->find(start)+(-1);
                //cout << ans << endl;
                if(ans > rr)throw -1;
                cout << ans << endl;
            }catch(signed i){
                cout << -1 << endl;
            }
            root = node::merge({l, m, r});
        }
        root->assertlast();
    }
    }catch(int xxx){ /*root->assertlast();*/ }
}

#pragma GCC optimize("Ofast")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define int lld
typedef int64_t lld;
typedef pair<int,int> pii;
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(),(x).end()
//#define endl '\n'
#define jizz cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

template<typename Iter>
ostream& _out(ostream &s, Iter b, Iter e) {
    s<<"[";
    for ( auto it=b; it!=e; it++ ) s<<(it==b?"":" ")<<*it;
    s<<"]";
    return s;
}
template<class T1,class T2>
ostream& operator<<(ostream& out, pair<T1,T2> p) {
    return out << '(' << p.first << ", " << p.second << ')';
}
template<class T1,class T2>
istream& operator>>(istream& in, pair<T1,T2>& p) {
    return in >> p.ff >> p.ss;
}
template<typename T>
ostream& operator <<( ostream &s, const vector<T> &c ) {
     return _out(s,c.begin(),c.end());
}
template<typename T, size_t N>
ostream& operator <<( ostream &s, const array<T, N> &c ) {
     return _out(s,c.begin(),c.end());
}
inline char readchar() {
	const int S = 1<<20; // buffer size
	static char buf[S], *p = buf, *q = buf;
	if(p == q && (q = (p=buf)+fread(buf,1,S,stdin)) == buf) return EOF;
	return *p++;
}
inline void input(int &_x){
    _x = 0;
    int _tmp = 1; char _tc = readchar();
    while(_tc < '0' || _tc > '9') _tc = readchar();
    while(_tc >= '0' && _tc <= '9') _x = (_x<<1)+(_x<<3)+(_tc-48), _tc = readchar();
}
inline void output(int _x){
    char _buff[20]; int _f = 0;
    if(_x == 0) putchar('0');
    while(_x > 0){
            _buff[_f++] = _x%10+'0';
            _x /= 10;
    }
    for(_f-=1; _f >= 0; _f--)
            putchar(_buff[_f]);
  putchar('\n');
}

inline int ran(){
    static int x = 71222217;
    return x = (x*0xdefaced+1)&INT_MAX;
}

struct Q{
    lld a = 0; int b = 1;
    Q& operator+(int x){
        a+=(lld)x*b; return *this;
    }
    bool operator>(int x){
        return a>(lld)b*x;
    }
    friend ostream& operator<<(ostream& out, Q x){
        return out << (long double)x.a/x.b;
    }
    Q(int aa = 0, int bb = 1){ a = aa, b = bb; if(b<0)b = -b, a = -a; }
};

struct node{
    node *L = 0, *R = 0;
    int a; lld b; // a(t-l) + b;
    int l, r, alt = 0, pri;
    lld mins = LLONG_MAX;
    node(int l, int r, int a, int b) : l(l), r(r), a(a), b(b) {
        pri = ran(); up();
    }
    void upda(int x){ mins+=x, b+=x, alt+=x; }
    void down(){ if(L)L->upda(alt); if(R)R->upda(alt); alt = 0; }
    void up(){ mins = min(b, val()); if(L)mins = min(mins, L->mins); if(R)mins = min(mins, R->mins); }
    tuple<node*, node*, node*> split(int i){
        down();
        if(i < l){
            //while(!L);
            auto [a, b, c] = L->split(i);
            L = c; up();
            return {a, b, this};
        } else if(i >= r){
            //while(!R);
            auto [a, b, c] = R->split(i);
            R = a; up();
            return {this, b, c};
        } else {
            auto a = L, b = R;
            L = R = 0; up();
            return {a, this, b};
        }
    }
    static node* merge(node *a, node *b){
        if(!a)return b; if(!b)return a;
        if(a -> pri < b -> pri){
            a->down();
            a->R = merge(a->R, b);
            a -> up();
            return a;
        }else{
            b->down();
            b->L = merge(a, b->L);
            b-> up();
            return b;
        }
    }
    node* last(){return R?R->last():this; } node*first(){ return L?L->first():this; }
    static node* merge(vector<node*> a){
        node *n = 0;
        for(auto i: a){
                if(n&&i)assert(n->last()->r == i->first()->l);
                n = merge(n, i);
        }
        return n;
    }
    Q find(int x){
        down();
        //cout << x << " " << show() << endl;
        if(L && L->mins <= x)return L->find(x);
        if(val() <= x)
            return inverse(x);
        if(R)return R->find(x);
        throw 0;
    }
    lld setlast(int x){
        if(R){
            down();
            auto a = R->setlast(x);
            up();
            return a;
        }else return r = x, val();
    }
    //void assertlast(){ if(R)R->assertlast(); else if(r < 1000000000) exit(0); }
    pair<pii, pair<int, lld>> show(){ return  make_pair(make_pair(l, r), make_pair(a, b)); }
    ostream& print(ostream& out){
        down();
        if(L)L->print(out);
        out << show() << " ";
        if(R)R->print(out);
        return out;
    }
    lld val(int x = -1){ if(x<0)x=r; return (lld)a*(x-l)+b; } // a(x-l)=(y-b)/a
    Q inverse(lld y){ return (a?Q(y-b, a):Q())+l; }
} *root = new node(0, 1000100000, 0, 0);

ostream& operator<<(ostream& out, node* n){
    if(!n)return out << "NULL";
    return n->print(out);
}

vector<int> u, v, uu, vv;
signed main(){jizz; //freopen("test.in", "r", stdin);
#ifdef LOCAL
freopen("test.in", "r", stdin);
#endif
    int q;
    cin >> q;
    cout << setprecision(20) << fixed;
    //root->assertlast();
    while(q--){
        //root->assertlast();
        int a;
        cin >> a;
        //cout << root << endl;
        if(a == 1){
            int t, s;
            cin >> t >> s;t++;
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!m);
            lld prev = m->val();
            if(m->l == t){
                m->a = s;
                if(r)r->upda(m->val()-prev);
                root = node::merge({l, m, r});
            }else{
                int mr = m->r; m->r = t;
                node* x = new node(t, mr, s, m->val());
                if(r)r->upda(x->val()-prev);
                root = node::merge({l, m, x, r});
            }
        }
        if(a == 2){
            int t;
            cin >> t;t++;
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!l); while(!m);while(m->l != t);
            auto newval = l->setlast(m->r);
            if(r)r->upda(newval-m->val());
            root = node::merge({l, r});
            delete m;
        }
        if(a == 3){
            int t, rr, v;
            cin >> t >> rr >> v;
            if(!v){ cout << t << endl; continue; }
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!m);
            lld start = m->val(t)-v;
            if(m->val()<=start){ cout << m->inverse(start) << endl; root = node::merge({l, m, r}); continue; }
            if(!r){ cout << -1 << endl; root = node::merge({l, m, r}); continue; }
            try{
                auto ans = r->find(start)+(-1);
                //cout << ans << endl;
                if(ans > rr)throw -1;
                cout << ans << endl;
            }catch(signed i){
                cout << -1 << endl;
            }
            root = node::merge({l, m, r});
        }
        //root->assertlast();
    }
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(time(NULL));
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void ispis(pnode x){

    if(x==NULL)return;
    push(x);

    ispis(x->l);
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void upd(pnode x){
    if(x==NULL)return;
    ////x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
    x->mn=x->val;
    if(x->l!=NULL)x->mn=x->l->val<x->mn?x->l->val:x->mn;
    ///pnode pr=x->r;
    if(x->r!=NULL)x->mn=
        x->r->val<x->mn?
        x->r->val:x->mn;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_mn(x->l)<=val){
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*if(sq==10000){
            printf("\n\nISPIS\n");
            ispis(midtree);
            printf("\n");
        }*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
        ///if(sq==10000)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            ///if(sq==10000)printf("%d TMTM\n",tm);
            ///if(tm==0 || pom1==NULL)printf("AAAJEBOTE\n");

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            if(sq==10000){
                cout<<lst->val<<" "<<lst->t<<" "<<lst->s<<" "<<zero<<" EVO GA"<<endl;
            }
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<" "<<s<<endl;}
            else ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<endl;}
            else del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(sq==101){
                cout<<tip<<" "<<l<<" "<<r<<" "<<v<<endl;
                continue;
            }
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            ///cout<<fixed;
            ///cout<<setprecision(6);
            cout<<query(l,r,v)<<endl;
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 100100
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
struct Data{int k,t;ll s,sl,sr,mxs;};
Data operator+(Data a,Data b)
{
	Data c;c.k=b.k;
	c.s=a.s+b.s;c.t=a.t+b.t;
	c.sr=max(b.sr,a.sr+b.s);
	c.sl=max(a.sl,b.sl+a.s);
	c.mxs=max(a.mxs,b.mxs+a.s);
	return c;
}
struct Node
{
	int ff,ch[2];
	int k,t,len;
	Data a;
	Data Pre(){ll p=max(1ll*k*len,0ll);return (Data){k,len,1ll*k*len,p,p,p};}
}t[MAX];
int rt,tot;
void pushup(int x){t[x].a=t[lson].a+t[x].Pre()+t[rson].a;}
void rotate(int x)
{
	int y=t[x].ff,z=t[y].ff;
	int k=t[y].ch[1]==x;
	if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
	t[y].ch[k]=t[x].ch[k^1];if(t[x].ch[k^1])t[t[x].ch[k^1]].ff=y;
	t[x].ch[k^1]=y;t[y].ff=x;
	pushup(y);pushup(x);
}
void Splay(int x,int goal)
{
	while(t[x].ff!=goal)
	{
		int y=t[x].ff,z=t[y].ff;
		if(z!=goal)
			(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
		rotate(x);
	}
	if(!goal)rt=x;
}
void Insert(int a,int s)
{
	int x=rt,f=0;
	while(233)
	{
		if(t[x].t>a)f=x,x=lson;
		else f=x,x=rson;
		if(!x)break;
	}
	int k=t[f].t<a;x=++tot;
	if(f)t[f].ch[k]=x;t[x].ff=f;
	t[x].t=a;t[x].k=s;
	Splay(x,0);
}
int Find(int a)
{
	int x=rt;
	while(233)
	{
		if(t[x].t==a)return x;
		if(t[x].t<a)x=rson;
		else x=lson;
	}
}
int uNext(int a,int p)
{
	int x=rt,u=0;
	while(233)
	{
		if(t[x].t==a)return x;
		int k=t[x].t<a;
		if(p^k)u=x;
		if(!t[x].ch[k])break;
		x=t[x].ch[k];
	}
	return u;
}
int Next(int a,int p)
{
	int x=rt,u=0;bool fl=false;
	while(233)
	{
		if(t[x].t==a){fl=true;break;}
		int k=t[x].t<a;
		if(p^k)u=x;
		if(!t[x].ch[k])break;
		x=t[x].ch[k];
	}
	if(!fl)return u;
	if(!t[x].ch[p])return u;
	else x=t[x].ch[p];
	while(t[x].ch[p^1])x=t[x].ch[p^1];
	return x;
}
void Adding(int a,int s)
{
	Insert(a,s);
	int nw=Find(a),lt=Next(a,0),nt=Next(a,1);
	Splay(lt,0);t[lt].len=a-t[lt].t;pushup(lt);
	Splay(nw,0);t[nw].len=t[nt].t-a;pushup(nw);
}
void Delete(int a)
{
	int uL=Next(a,0),uR=Next(a,1);
	Splay(uL,0);Splay(uR,uL);
	t[uR].ch[0]=0;
	pushup(uR);
	t[uL].len=t[uR].t-t[uL].t;
	pushup(uL);
}
double Query(int l,int r,ll V)
{
	if(!V)return l;
	int uL=Next(l,0),uR=Next(r,1),QwQ=uNext(l,1);
	Splay(uL,0);Splay(uR,uL);
	int nw=t[uR].ch[0];
	if(t[nw].a.mxs<V)return -1;
	int u=nw;Data now=(Data){0,0,0,0,0,0};
	double ret=t[QwQ].t;
	while(233)
	{
		Data pre=now+t[t[u].ch[0]].a+t[u].Pre();
		if(pre.mxs<V)now=pre,u=t[u].ch[1],ret+=pre.t;
		else
		{
			Data qwq=now+t[t[u].ch[0]].a;
			if(qwq.mxs<V)
			{
				V-=qwq.s;
				return 1.0*V/t[u].k+ret+t[t[u].ch[0]].a.t;
			}
			u=t[u].ch[0];
		}
		if(!u)return -1;
	}
}
int main()
{
	Insert(0,0);Insert(2e9+1,0);
	int Q=read();
	while(Q--)
	{
		int opt=read();
		if(opt==1)
		{
			int a=read(),s=read();
			Adding(a,-s);
		}
		else if(opt==2)Delete(read());
		else
		{
			int l=read(),r=read(),V=read();
			double s=Query(l,r,V);
			if(s>r)puts("-1");
			else printf("%.10lf\n",s);
		}
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define mp make_pair
#define fi first
#define se second
const int L=1,R=1000000000;
int n,tot,ord,l,r,p,mid,ans;
long long v,nw;
set<pair<int,int> > s;
set<pair<int,int> >::iterator it;

struct node
{
	int ls,rs;
	long long val,lazk,lazb;
	bool laz;
}t[6000001];

void pushdown(int i,int l,int r)
{
	if (!t[i].ls) t[i].ls=(++tot);
	if (!t[i].rs) t[i].rs=(++tot);
	if (!t[i].laz&&t[i].lazb==0) return;
	int mid=(l+r)>>1;
	if (t[i].laz)
	{
		t[t[i].ls].laz=t[t[i].rs].laz=1;
		t[t[i].ls].lazk=t[t[i].rs].lazk=t[i].lazk;
		t[t[i].ls].lazb=t[t[i].rs].lazb=t[i].lazb;
		if (t[i].lazk>0) t[t[i].ls].val=1ll*l*t[i].lazk+t[i].lazb,t[t[i].rs].val=1ll*(mid+1)*t[i].lazk+t[i].lazb;
		else t[t[i].ls].val=1ll*mid*t[i].lazk+t[i].lazb,t[t[i].rs].val=1ll*r*t[i].lazk+t[i].lazb;
		t[i].laz=0; t[i].lazk=t[i].lazb=0; return;
	}
	t[t[i].ls].val+=t[i].lazb; t[t[i].rs].val+=t[i].lazb;
	t[t[i].ls].lazb+=t[i].lazb; t[t[i].rs].lazb+=t[i].lazb;
	t[i].lazb=0;
}

long long getmin(long long a,long long b) {return a<b?a:b;}

void add(int i,int l,int r,int ql,int qr,long long v)
{
	if (ql>qr) return;
	if (l==ql&&r==qr) {t[i].val+=v,t[i].lazb+=v; return;}
	pushdown(i,l,r); int mid=(l+r)>>1;
	if (qr<=mid) add(t[i].ls,l,mid,ql,qr,v); else
	if (ql>mid) add(t[i].rs,mid+1,r,ql,qr,v); else
	add(t[i].ls,l,mid,ql,mid,v),add(t[i].rs,mid+1,r,mid+1,qr,v);
	t[i].val=getmin(t[t[i].ls].val,t[t[i].rs].val);
}

void change(int i,int l,int r,int ql,int qr,long long k,long long b)
{
	if (ql>qr) return;
	if (l==ql&&r==qr)
	{
		if (k>0) t[i].val=k*l+b; else t[i].val=k*r+b;
		t[i].laz=1; t[i].lazk=k; t[i].lazb=b; return;
	}
	pushdown(i,l,r); int mid=(l+r)>>1;
	if (qr<=mid) change(t[i].ls,l,mid,ql,qr,k,b); else
	if (ql>mid) change(t[i].rs,mid+1,r,ql,qr,k,b); else
	change(t[i].ls,l,mid,ql,mid,k,b),change(t[i].rs,mid+1,r,mid+1,qr,k,b);
	t[i].val=getmin(t[t[i].ls].val,t[t[i].rs].val);
}

long long query(int i,int l,int r,int ql,int qr)
{
	if (ql>qr) return 0;
	if (ql==l&&qr==r) return t[i].val;
	int mid=(l+r)>>1;
	if (t[i].laz)
	{
		if (t[i].lazk>0) return t[i].lazk*ql+t[i].lazb;
		else return t[i].lazk*qr+t[i].lazb;
	}
	if (qr<=mid)
	{
		if (!t[i].ls) return t[i].lazb;
		return query(t[i].ls,l,mid,ql,qr)+t[i].lazb;
	}
	if (ql>mid)
	{
		if (!t[i].rs) return t[i].lazb;
		return query(t[i].rs,mid+1,r,ql,qr)+t[i].lazb;
	}
	long long ansl,ansr;
	if (t[i].ls) ansl=query(t[i].ls,l,mid,ql,mid); else ansl=0;
	if (t[i].rs) ansr=query(t[i].rs,mid+1,r,mid+1,qr); else ansr=0;
	return getmin(ansl,ansr)+t[i].lazb;
}

int main()
{
	s.clear(); s.insert(mp(0,0)); s.insert(mp(1000000001,0));
	scanf("%d",&n); tot=1;
	while (n--)
	{
		scanf("%d",&ord);
		if (ord==1)
		{
			scanf("%d%I64d",&p,&v);
			it=s.lower_bound(mp(p,0)); r=(*it).fi; it--;
			if (p==1) nw=0; else nw=query(1,L,R,p-1,p-1);
			change(1,L,R,p,r-1,v,v*(1-p)+nw);
			add(1,L,R,r,R,1ll*(r-p)*(v-(*it).se));
			s.insert(mp(p,v));
		} else
		if (ord==2)
		{
			scanf("%d",&p);
			it=s.lower_bound(mp(p,0));
			it--; l=(*it).se; it++; it++; r=(*it).fi; it--;
			if (p==1) nw=0; else nw=query(1,L,R,p-1,p-1);
			change(1,L,R,p,r-1,l,1ll*l*(1-p)+nw);
			add(1,L,R,r,R,1ll*(r-p)*(l-(*it).se));
			s.erase(mp(p,(*it).se));
		} else
		{
			scanf("%d%d%I64d",&l,&r,&v); int lll=l;
			if (v==0) {printf("%d\n",l); continue;}
			if (l==r) {puts("-1"); continue;} r--;
			if (l>1) v=query(1,L,R,l-1,l-1)-v; else v=-v;
			ans=-2;
			while (l<=r)
			{
				mid=(l+r)>>1;
				if (query(1,L,R,lll,mid)<=v) ans=mid,r=mid-1; else l=mid+1;
			}
			if (ans==-2) puts("-1"); else
			{
				nw=query(1,L,R,ans,ans);
				it=s.lower_bound(mp(ans,0)); if ((*it).fi!=ans) it--;
				printf("%.6lf\n",ans+1.0*(v-nw)/(1.0*(*it).se)+1);
			}
		}
	}
	return 0;
}

#include "bits/stdc++.h"
using namespace std;

#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define pb push_back
#define eb emplace_back
#define ins insert
#define f first
#define s second
#define cbr cerr << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ll(x.size())
#define all(x) (x).begin(), (x).end()
#define lbd(x,y) (lower_bound(all(x),y)-x.begin())
#define ubd(x,y) (upper_bound(all(x),y)-x.begin())
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
inline long long rand(long long x, long long y) { return (rng() % (y+1-x)) + x; } //inclusivesss
string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?llabs(b):gcd(b%a,a); }

typedef long long ll;
typedef long double ld;
#define FOR(i,s,e) for(ll i=s;i<=ll(e);++i)
#define DEC(i,s,e) for(ll i=s;i>=ll(e);--i)
typedef pair<ll,ll>pi; typedef pair<ll,pi>spi; typedef pair<pi,pi>dpi;

#define LLINF ((long long)1e18)
#define INF int(1e9+1e6)
#define MAXN (100006)
const ll sqn = 1;
const ll other = MAXN / sqn * 3;
ll q;
struct node {
	int s,e,m;
	ll v,place;
	node*l,*r;
	node(int S,int E){
		s=S,e=E,m=(s+e)>>1;
		v=0, place=other+5;
		l=r=0;
	}
	void update(int x,bool b,ll num){
		if(s==e) {
			v=b;
			place=num;
			return;
		}
		if(x>m) {
			if(!r) r=new node(m+1,e);
			r->update(x,b,num);
		}else{
			if(!l) l=new node(s,m);
			l->update(x,b,num);
		}
		v=(l?l->v:0)+(r?r->v:0);
		place=min(l?l->place:other+5,r?r->place:other+5);
	}
	ll rmq(int x){
		if(s==e) return place;
		if(r && r->place < other) return r->rmq(x);
		else if(l && l->place < other) return l->rmq(x);
		else return other + 5;
	}
	ll pos(int x){
		if(s==e) return place;
		if(x>m) return r->pos(x);
		else return l->pos(x);
	}
}*seg;
bool stop;
pi C=pi(-1,-1);
struct bkt {
	ll mi=0,ind,end=1e9+5,total=0;
	vector<pi> v;
	void insert(pi x){
		vector<pi> tmp;
		while(v.size() && v.back() > x) tmp.pb(v.back()), v.pop_back();
		tmp.eb(x);
		while(tmp.size()) v.eb(tmp.back()), tmp.pop_back();
		if(ind) C=pi(ind-1, v[0].f);
		recalc();
	}
	void re(ll x){
		assert(lbd(v,pi(x,-LLINF)) < v.size() && v[lbd(v,pi(x,-LLINF))].f==x);
		v.erase(v.begin()+lbd(v,pi(x,-LLINF)));
		if(ind && siz(v)) {
			C=pi(ind-1, v[0].f);
		}else if(ind){
			// FOR(i,ind+1,other-1) if(this[i].v.size()) {
				// this[ind-1].end = this[i].v[0].f;
				// this[ind-1].recalc();
				// break;
			// }
			C=pi(ind-1, -1);
		}
		recalc();
	}
	void recalc(){
		if(stop)return;
		total = 0, mi = 0;
		FOR(i,0,siz(v)-1){
			total += ((i==siz(v)-1 ? end : v[i+1].f) - v[i].f) * v[i].s;
			mi=max(mi,-total);
		}
	}
	ld query(ll l,ll r,ll x){
		auto bound=[&](ll x){
			return min(max(l, x), r+1);
		};
		FOR(i,0,siz(v)-1)if(v[i].f>=l&&v[i].f<=r){
			if(x + (bound(i==siz(v)-1 ? end : v[i+1].f) - bound(v[i].f)) * v[i].s > 0) {
				x += (bound(i==siz(v)-1 ? end : v[i+1].f) - bound(v[i].f)) * v[i].s;
			} else {
				assert(v[i].s < 0);
				return bound(v[i].f) + ld(x) / ld(-v[i].s);
			}
		}
		assert(0);
	}
	pi from(ll l,ll r){
		if(v[0].f >= l && v.back().f <= r) return pi(total,mi);
		if(v.back().f < l) assert(0);
		ll used = 0, mx = 0;
		auto bound=[&](ll x){
			return min(max(l, x), r+1);
		};
		FOR(i,0,siz(v)-1)if(v[i].f>=l&&v[i].f<=r){
			used += (bound(i==siz(v)-1 ? end : v[i+1].f) - bound(v[i].f)) * v[i].s;
			mx = max(mx, - used);
		}
		return pi(used,mx);
	}
} bk[other];
void push(){
	if(C.f==-1) return;
	if(C.s==-1){
		FOR(i,C.f+1,other-1)if(bk[i].v.size()){
			bk[C.f].end=bk[i].v[0].f;
			bk[C.f].recalc();
			break;
		}
	}else{
		bk[C.f].end=C.s;
		bk[C.f].recalc();
	}
	C=pi(-1,-1);
}
void rebuild(){
	vector<pi> everyone;
	FOR(i,0,other-1) { for(auto j:bk[i].v) everyone.eb(j); bk[i].v.clear(), bk[i].mi=0, bk[i].total=0, bk[i].end=1e9+5; }
	stop=1;
	FOR(i,0,siz(everyone)-1){
		bk[i/sqn].insert(everyone[i]);
		push();
		seg->update(everyone[i].f, 1, i/sqn);
	}
	stop=0;
	FOR(i,0,(siz(everyone)-1)/sqn) bk[i].recalc();
}
int main(){
	cout<<setprecision(12)<<fixed;
	cerr<<setprecision(12)<<fixed;
	FAST
	seg=new node(0, 1e9);
	FOR(i,0,other-1) bk[i].ind=i;
	cin>>q;
	while(q--){
		ll op; cin>>op;
		if(op==1){
			ll t, s; cin>>t>>s;
			ll indy = seg->rmq(t);
			if(indy>=other) indy=0;
			seg->update(t, 1, indy);
			bk[indy].insert(pi(t,s));
			push();
			if(bk[indy].v.size() >= 2 * sqn) {
				rebuild();
			}
		}else if(op==2){
			ll t; cin>>t;
			bk[seg->pos(t)].re(t);
			seg->update(t,0,other+5);
			push();
		}else {
			ll l,r,v;cin>>l>>r>>v;
			if(v==0){
				cout<<l<<'\n';
				continue;
			}
			bool done=0;
			FOR(i,0,other-1) if(bk[i].v.size()) {
				if(bk[i].v[0].f > r){
					break;
				}
				if(bk[i].v.back().f < l) continue;
				if(bk[i].from(l,r).s >= v){
					ld tmp=bk[i].query(l,r,v);
					if(tmp <= r) cout<<tmp<<'\n';
					else cout<<"-1\n";
					done=1;
					break;
				}
				v += bk[i].from(l,r).f;
				assert(v>0);
			}
			if(done) continue;
			cout<<"-1\n";
		}
	}
}
/*
15
1 1000000000 1000000000
2 1000000000
1 1 1000000000
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 500 1000000000
1 322 1000000000
1 500000000 -1000000000
3 1 1000000000 1
*/

#include<bits/stdc++.h>
typedef long long ll;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) FOR(i,0,a)

using namespace std;
int Q;
const int MAX_Q=1e5,BUC=448,INF=1e9+32;
ll buk[448][4];
vector<int> tim;
int typ[MAX_Q],T[MAX_Q],L[MAX_Q],R[MAX_Q];
ll V[MAX_Q];
ll S[MAX_Q];
ll spd[MAX_Q*2];
int main(){
	scanf("%d",&Q);
	REP(i,Q){
		scanf("%d",typ+i);
		switch(typ[i]){
			case 1:
			scanf("%d %I64d",T+i,S+i);
			break;
			case 2:
			scanf("%d",T+i);
			break;
			case 3:
			scanf("%d %d %I64d",L+i,R+i,V+i);
		}
		if(typ[i]<=2){
			tim.push_back(T[i]);
		}else{
			tim.push_back(L[i]);
			tim.push_back(R[i]);
		}
	}
	tim.push_back(INF);
	sort(tim.begin(),tim.end());
	tim.erase(unique(tim.begin(),tim.end()),tim.end());
	REP(i,Q){
		if(typ[i]<=2){
			T[i]=lower_bound(tim.begin(),tim.end(),T[i])-tim.begin();
		}else{
			L[i]=lower_bound(tim.begin(),tim.end(),L[i])-tim.begin();
			R[i]=lower_bound(tim.begin(),tim.end(),R[i])-tim.begin();
		}
	}
	REP(i,317){
		buk[i][2]=(i+1)*BUC;
		buk[i][3]=-1;
	}
	memset(spd,-1,sizeof(spd));
	REP(q,Q){
		switch(typ[q]){
			case 1:
			spd[T[q]]=S[q];
			break;
			case 2:
			spd[T[q]]=-1;
			break;
			case 3:
			ll s=0,v=V[q];
			int l=L[q];
			double ans;
			if(v==0){
				ans=tim[l];
				goto LAB;
			}
			while(l<R[q] && l%BUC>0){
				if(spd[l]!=-1){
					s=spd[l];
				}
				if(v+s*(tim[l+1]-tim[l])<=0){
					if(s==0){
						ans=tim[l];
					}else{
						ans=-(double)v/s+tim[l];
					}
					goto LAB;
				}
				v+=s*(tim[l+1]-tim[l]);
				l++;
			}
			while(l+BUC<R[q]){
				if(v+s*(tim[buk[l/BUC][2]]-tim[l])<=0){
					if(s==0){
						ans=tim[l];
					}else{
						ans=-(double)v/s+tim[l];
					}
					goto LAB;
				}
				v+=s*(tim[buk[l/BUC][2]]-tim[l]);
				if(buk[l/BUC][2]-l<BUC){
					l=buk[l/BUC][2];
					if(v+buk[l/BUC][0]<=0){
						break;
					}
					v+=buk[l/BUC][1];
				}
				if(buk[l/BUC][3]!=-1){
					s=buk[l/BUC][3];
				}
				l=(l/BUC+1)*BUC;
			}
			while(l<R[q]){
				if(spd[l]!=-1){
					s=spd[l];
				}
				if(v+s*(tim[l+1]-tim[l])<=0){
					if(s==0){
						ans=tim[l];
					}else{
						ans=-(double)v/s+tim[l];
					}
					goto LAB;
				}
				v+=s*(tim[l+1]-tim[l]);
				l++;
			}
			if(l==R[q]){
				ans=-1;
				goto LAB;
			}
			LAB:
			printf("%.16f\n",ans);
		}
		if(typ[q]<=2){
			int l=T[q]/BUC*BUC,r=l+BUC;
			if(T[q]/BUC!=(int)tim.size()/BUC){
				while(l<r && spd[l]==-1){
					l++;
				}
				buk[T[q]/BUC][2]=l;
				ll v=0,s=0;
				buk[T[q]/BUC][0]=0;
				buk[T[q]/BUC][3]=-1;
				while(l<r){
					if(spd[l]!=-1){
						s=spd[l];
						buk[T[q]/BUC][3]=s;
					}
					v+=s*(tim[l+1]-tim[l]);
					buk[T[q]/BUC][0]=min(buk[T[q]/BUC][0],v);
					l++;
				}
				buk[T[q]/BUC][1]=v;
			}
		}
	}
}

#include <bits/stdc++.h>
#define N 100007
using namespace std;
struct info{int op,t,s,l,r,v;}a[N];
int b[N],s[N],e[N*4],mn[N*4];
long long pre[N*4],sum[N*4],tag[N*4];
int find(int l,int r,int x){
    int res=r;
    while(l<=r){
        int mid=(l+r)>>1;
        if(b[mid]>=x)res=mid,r=mid-1;
        else l=mid+1;
    }
    return res;
}
int lst(int k,int l,int r,int x){
    if(r<=x)
        if(e[k])
            if(l==r)return l;
            else{
                int mid=(l+r)>>1;
                if(e[k*2+1])return lst(k*2+1,mid+1,r,x);
                else return lst(k*2,l,mid,x);
            }
        else return -1;
    int mid=(l+r)>>1;
    if(x>mid){
        int tmp=lst(k*2+1,mid+1,r,x);
        if(tmp!=-1)return tmp;
    }
    return lst(k*2,l,mid,x);
}
int nxt(int k,int l,int r,int x){
    if(x<=l)
        if(e[k])
            if(l==r)return l;
            else{
                int mid=(l+r)>>1;
                if(e[k*2])return nxt(k*2,l,mid,x);
                else return nxt(k*2+1,mid+1,r,x);
            }
        else return -1;
    int mid=(l+r)>>1;
    if(x<=mid){
        int tmp=nxt(k*2,l,mid,x);
        if(tmp!=-1)return tmp;
    }
    return nxt(k*2+1,mid+1,r,x);
}
void put(int k,int l,int r,int x){
    if(l==r){e[k]=x>0;return;}
    int mid=(l+r)>>1;
    if(abs(x)<=mid)put(k*2,l,mid,x);
    else put(k*2+1,mid+1,r,x);
    e[k]=e[k*2]|e[k*2+1];
}
void init(int k,int l,int r){
    mn[k]=l;
    if(l==r)return;
    int mid=(l+r)>>1;
    init(k*2,l,mid);
    init(k*2+1,mid+1,r);
}
void up(int k){
    if(pre[k*2]<sum[k*2]+pre[k*2+1])mn[k]=mn[k*2],pre[k]=pre[k*2];
    else mn[k]=mn[k*2+1],pre[k]=sum[k*2]+pre[k*2+1];
    sum[k]=sum[k*2]+sum[k*2+1];
}
void push(int k,int l,int mid,int r){
    sum[k*2]+=tag[k]*(b[mid+1]-b[l]);
    if(sum[k*2]>0)mn[k*2]=l,pre[k*2]=0;
    else mn[k*2]=mid+1,pre[k*2]=sum[k*2];
    tag[k*2]+=tag[k];
    sum[k*2+1]+=tag[k]*(b[r+1]-b[mid+1]);
    if(sum[k*2+1]>0)mn[k*2+1]=mid+1,pre[k*2+1]=0;
    else mn[k*2+1]=r+1,pre[k*2+1]=sum[k*2+1];
    tag[k*2+1]+=tag[k];
    tag[k]=0;
}
void upd(int k,int l,int r,int L,int R,int delta){
    if(L<=l && r<=R){
        sum[k]+=1LL*delta*(b[r+1]-b[l]);
        if(sum[k]>0)mn[k]=l,pre[k]=0;
        else mn[k]=r+1,pre[k]=sum[k];
        tag[k]+=delta;
        return;
    }
    int mid=(l+r)>>1;
    if(tag[k])push(k,l,mid,r);
    if(L<=mid)upd(k*2,l,mid,L,R,delta);
    if(R>mid)upd(k*2+1,mid+1,r,L,R,delta);
    up(k);
}
long long base;
int pos(int k,int l,int r,int L){
    if(L<=l)
        if(pre[k]<=base)return mn[k];
        else{base-=sum[k];return -1;}
    int mid=(l+r)>>1;
    if(tag[k])push(k,l,mid,r);
    if(L<=mid){
        int tmp=pos(k*2,l,mid,L);
        if(tmp!=-1)return tmp;
    }
    return pos(k*2+1,mid+1,r,L);
}
long long get(int k,int l,int r,int L,int R){
    if(L<=l && r<=R)return sum[k];
    int mid=(l+r)>>1;
    if(tag[k])push(k,l,mid,r);
    long long res=0;
    if(L<=mid)res+=get(k*2,l,mid,L,R);
    if(R>mid)res+=get(k*2+1,mid+1,r,L,R);
    return res;
}
int main(){
    int q,n=0;
    scanf("%d",&q);
    b[++n]=0,b[++n]=1000000001;
    for(int i=1;i<=q;++i){
        scanf("%d",&a[i].op);
        if(a[i].op==1)scanf("%d%d",&a[i].t,&a[i].s),b[++n]=a[i].t;
        if(a[i].op==2)scanf("%d",&a[i].t);
        if(a[i].op==3)scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].v);
    }
    sort(b+1,b+n+1);
    n=unique(b+1,b+n+1)-b-1;
    put(1,1,n,1),put(1,1,n,n);
    init(1,1,n-1);
    for(int i=1;i<=q;++i){
        if(a[i].op==1){
            int x=find(1,n,a[i].t);
            int l=lst(1,1,n,x),r=nxt(1,1,n,x+1);
            put(1,1,n,x);
            upd(1,1,n-1,x,r-1,a[i].s-s[l]);
            s[x]=a[i].s;
        }
        if(a[i].op==2){
            int x=find(1,n,a[i].t);
            int l=lst(1,1,n,x-1),r=nxt(1,1,n,x+1);
            put(1,1,n,-x);
            upd(1,1,n-1,x,r-1,s[l]-s[x]);
        }
        if(a[i].op==3)
            if(!a[i].v)printf("%d\n",a[i].l);
            else{
                int x=find(1,n,a[i].l);
                x=nxt(1,1,n,x);
                base=-a[i].v;
                int y=pos(1,1,n-1,x);
                if(y==-1)puts("-1");
                else{
                    int l=lst(1,1,n,y-1);
                    base=a[i].v+get(1,1,n-1,x,l-1);
                    double ans=(double)base/(-s[l])+b[l];
                    if(ans>(double)a[i].r)puts("-1");
                    else printf("%.8f\n",ans);
                }
            }
    }
}

#include<bits/stdc++.h>

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I __attribute__((always_inline))inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
#define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)

struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define UC unsigned char
#define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;

const int N=8333333,V=1000000005;

struct node
{
	int lc,rc,mp;
	ll mi,tag;
}f[N];

int fm;

inline void st(int&x,ll v,int l,int r)
{
	if(!x)x=++fm,f[x].mp=l;
	f[x].tag+=v;
	f[x].mi+=v;
}

inline void pd(int x,int l,int r,int t)
{
	if(f[x].tag)
	{
		st(f[x].lc,f[x].tag,l,t);
		st(f[x].rc,f[x].tag,t+1,r);
		f[x].tag=0;
	}
}

inline void modify(int&x,int l,int r,int ql,int qr,ll v)
{
	if(!x)x=++fm,f[x].mp=l;
	if(l>=ql&&r<=qr)return st(x,v,l,r);
	int t=(l+r)>>1;pd(x,l,r,t);
	if(ql<=t)modify(f[x].lc,l,t,ql,qr,v);
	if(qr>t)modify(f[x].rc,t+1,r,ql,qr,v);
	if(f[f[x].lc].mi<=f[f[x].rc].mi)f[x].mi=f[f[x].lc].mi,f[x].mp=f[f[x].lc].mp;
	else f[x].mi=f[f[x].rc].mi,f[x].mp=f[f[x].rc].mp;
}

/*ll mi;int mp;

inline void query(int x,int l,int r,int ql,int qr)
{
	if(l>=ql&&r<=qr)
	{
		if(repl(mi,f[x].mi))mp=f[x].mp;
		return;
	}
	int t=(l+r)>>1;pd(x,l,r,t);
	if(ql<=t)query(f[x].lc,l,t,ql,qr);
	if(qr>t)query(f[x].rc,t+1,r,ql,qr);
}*/

int qa;

inline void query(int x,int l,int r,int p,ll req)
{
	if(f[x].mi>req||qa)return;
	if(!f[x].lc&&!f[x].rc)
	{
		qa=max(l,p);
		return;
	}
	int t=(l+r)>>1;pd(x,l,r,t);
	if(p<=t)query(f[x].lc,l,t,p,req);
	query(f[x].rc,t+1,r,p,req);
}

inline ll find(int x,int l,int r,int p)
{
	if(!f[x].lc&&!f[x].rc)return f[x].mi;
	int t=(l+r)>>1;pd(x,l,r,t);
	if(p<=t)return find(f[x].lc,l,t,p);
	return find(f[x].rc,t+1,r,p);
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	fm=1;
	std::map<int,int>vv;
	vv[0]=0;
	vv[V]=0;
	int rt=1;
	for(int q=in;q--;)
	{
		int op=in;
		if(op==1)
		{
			int t,s;
			in,t,s;
			pii o=*(--vv.lower_bound(t));
			pii g=*vv.lower_bound(t);
			//out,'/',o.xx,' ',o.yy,'\n';
			//o.yy->s
			modify(rt,0,V,g.xx,V,(ll)(s-o.yy)*(g.xx-t));
			//out,'/',g.xx,' ',V,' ',(ll)(s-o.yy)*(g.xx-t),'\n';
			modify(rt,0,V,t,g.xx-1,(ll)o.yy*(t-o.xx));
			//out,'/',t,' ',g.xx-1,' ',(ll)o.yy*(t-o.xx),'\n';
			vv[t]=s;
		}
		else if(op==2)
		{
			int t=in,s=vv[t];
			pii o=*(--vv.find(t));
			pii g=*++vv.find(t);
			modify(rt,0,V,g.xx,V,-(ll)(s-o.yy)*(g.xx-t));
			modify(rt,0,V,t,g.xx-1,-(ll)o.yy*(t-o.xx));
			vv.erase(t);
		}
		else
		{
			int l,r,v;
			in,l,r,v;
			if(!v)
			{
				out,l,'\n';
				continue;
			}
			qa=0;
			std::map<int,int>::iterator o=vv.upper_bound(l);
			ll fd=find(1,0,V,o->xx);
			ll st=fd;
			/*ll sf=fd+ll(o->xx-l)*to->yy;
			ll gg=fd+ll(r-l)*to->yy;
			if(r<=o->xx&&gg>st-v)
			{
				out,-1,'\n';
				continue;
			}
			//out,to->xx,' ',fd,' ',st,' ',sf,'\n';
			if(sf<=st-v)
			{
				lf tm=(lf)-v/to->yy+l;
				printf("%.9lf\n",tm);
				continue;
			}*/
			//out,"o.xx=",o->xx," st=",st,'\n';
			query(1,0,V,o->xx,st-v);
			//out,"qa:",qa," value:",find(1,0,V,qa),'\n';
			if(!qa)
			{
				out,-1,'\n';
				continue;
			}
			if(qa==l)
			{
				out,l,'\n';
				continue;
			}
			assert(vv.count(qa));
			std::map<int,int>::iterator b=vv.find(qa),a=b;--a;
			ll sl=find(1,0,V,a->xx);
			if(a->xx<=r&&b->xx>=r)
			{
				if(sl+a->yy*ll(r-a->xx)>st-v)
				{
					out,-1,'\n';
					continue;
				}
			}
			if(a->xx>r)
			{
				out,-1,'\n';
				continue;
			}
			lf tm=lf(st-v-sl)/a->yy+a->xx;
			printf("%.9lf\n",tm);
		}
	}
}

/*
    17.03.2019 21:55:57
*/

#include <bits/stdc++.h>

using namespace std;

struct item;
string to_string(item a);

#ifdef HOMEn
#define TAG_LENGTH 45
#define LR_LEFT left
#define LR_RIGHT right
#define LR_VALUE value
#define LR_SECOND_VALUE mn
#include "C:/C++ libs/print.cpp"
#define showl cout << endl;
#define shows cout << string(5, ' ') + string(TAG_LENGTH, '-') << endl;
#else
#define show(...) 42;
#define showt(...) 42;
#define showl 42;
#define shows 42;
#define print(...) 42;
#define printTree(...) 42;
#define printLRTree(...) 42;
#define printMatrix(...) 42;
#endif

const long long inf = 1e9 * 5;

struct item {
    long long mn = 0, delta = 0, l = 0, r = 0, end_speed = 0, start = 0;
    bool active = false, leaf = false;

    void init(pair< long long, long long >& pr) {
        l = pr.first;
        r = pr.second;
        leaf = true;
    }

    void update(item& a, item& b) {
        l = a.l; r = b.r;
        if (!a.active && !b.active) {
            active = false;
        } else if (!a.active) {
            active = true;
            mn = b.mn;
            delta = b.delta;
            start = b.start;
            end_speed = b.end_speed;
        } else if (!b.active) {
            active = true;
            delta = a.delta + a.end_speed * (b.r - b.l);
            mn = min(a.mn, delta);
            start = a.start;
            end_speed = a.end_speed;
        } else {
            active = true;
            start = a.start;
            delta = a.delta + (b.start - b.l) * a.end_speed + b.delta;
            mn = min(a.mn, b.mn + delta - b.delta);
            end_speed = b.end_speed;
        }
    }

    long double ask(long long v) {
        show(*this, v);
        if (end_speed >= 0) return -1;
        return -(long double)v / (long double)end_speed;
    }
};

item operator + (item a, item b) {
    item c;
    c.update(a, b);
    return c;
}

string to_string(item a) {
    return "[active: " + to_string(a.active) + ", " +
            "mn: " + to_string(a.mn) + ", " +
            "delta: " + to_string(a.delta) + ", " +
            "(l, r): (" + to_string(a.l) + ", " + to_string(a.r) + "), " +
            "end_speed: " + to_string(a.end_speed) + ", " +
            "start: " + to_string(a.start) + "]";
}

using T = item;

struct segtree {
    vector< T > tree;
    int n;

    segtree(int size) : n(size), tree(size * 4) {}
    segtree(vector< pair< long long, long long > >& v) : n(v.size()), tree(v.size() * 4) {
        build(v, 0, 0, n - 1);
    }

    void build(vector< pair< long long, long long > >& v, int i, int l, int r) {
        if (l == r) {
            tree[i].init(v[l]);
            return;
        }
        int m = (l + r) / 2;
        build(v, i * 2 + 1, l, m);
        build(v, i * 2 + 2, m + 1, r);
        tree[i].update(tree[2 * i + 1], tree[2 * i + 2]);
    }

    void set(int ind, long long t, long long s, int i, int l, int r) {
        while (l < r) {
            int m = (l + r) / 2;
            if (ind <= m) {
                r = m;
                i = 2 * i + 1;
            } else {
                l = m + 1;
                i = 2 * i + 2;
            }
        }
        tree[i].active = true;
        tree[i].end_speed = s;
        tree[i].delta = s * (tree[i].r - tree[i].l);
        tree[i].mn = min(0ll, tree[i].delta);
        tree[i].start = tree[i].l;
        while (i != 0) {
            i = (i - 1) / 2;
            tree[i].update(tree[2 * i + 1], tree[2 * i + 2]);
        }
    }

    void set(int ind, long long t, long long s) {
        set(ind, t, s, 0, 0, n - 1);
    }

    void erase(int ind) {
        int l = 0, r = n - 1, i = 0;
        while (l < r) {
            int m = (l + r) / 2;
            if (ind <= m) {
                r = m;
                i = 2 * i + 1;
            } else {
                l = m + 1;
                i = 2 * i + 2;
            }
        }
        tree[i].active = false;
        while (i != 0) {
            i = (i - 1) / 2;
            tree[i].update(tree[2 * i + 1], tree[2 * i + 2]);
        }
    }

    void split(int l, int r, int i, int vl, int vr, vector< int >& ans) {
        if (l == vl && r == vr) {
            ans.push_back(i);
            return;
        }
        int m = (vl + vr) / 2;
        if (r <= m) split(l, r, 2 * i + 1, vl, m, ans);
        else if (l > m) split(l, r, 2 * i + 2, m + 1, vr, ans);
        else {
            split(l, m, 2 * i + 1, vl, m, ans);
            split(m + 1, r, 2 * i + 2, m + 1, vr, ans);
        }
    }

    vector< int > split(int l, int r) {
        vector< int > answer;
        split(l, r, 0, 0, n - 1, answer);
        return answer;
    }

    long double ask(int l, int r, long long v) {
        vector< int > ind_ = split(l, r);
        if (v == 0) return tree[ind_[0]].l;
        vector< int > ind;
        for (auto i : ind_)
            if (tree[i].active) ind.push_back(i);
        show(l, r, ind_, ind);
        for (int j = 0; j < ind.size(); ++j) {
            int i = ind[j];
            if (!tree[i].active) continue;
            if (tree[i].mn + v <= 0 || (tree[i].r == inf && tree[i].end_speed < 0)){
                long double ans = ask_(i, v);
                show(ans);
                if (ans < 0) return -1;
                return ans + tree[i].l;
            }
            else {
                v += tree[i].delta;
                if (j + 1 < ind.size()) {
                    v += (tree[ind[j + 1]].start - tree[i].r) * tree[i].end_speed;
                }
            }
        }
        return -1;
    }

    long double ask_(int i, long long v) {
        show(i, v, tree[i]);
        if (tree[i].leaf) return tree[i].ask(v);
        if (tree[2 * i + 1].active && tree[2 * i + 1].mn + v <= 0 || !tree[2 * i + 2].active)
            return ask_(2 * i + 1, v);
        else {
            show(tree[2*i+1], tree[2*i+2]);
            if (tree[2 * i + 1].active)
                v += (tree[2 * i + 2].start - tree[2 * i + 1].r) * tree[2 * i + 1].end_speed +
                    tree[2 * i + 1].delta;
            long double ans = ask_(2 * i + 2, v);
            // show(i, ans+tree[2*i+1].r-tree[2*i+1].l);
            if (ans < 0) return -1;
            return ans + tree[2 * i + 1].r - tree[2 * i + 1].l;
        }
    }
};

int main() {
    int q;
    cin >> q;
    vector< vector< int > > queries(q);
    vector< long long > times;
    for (int i = 0; i < q; ++i) {
        int type;
        cin >> type;
        queries[i].push_back(type);
        if (type == 1) {
            int t, s;
            cin >> t >> s;
            times.push_back(t);
            queries[i].push_back(t);
            queries[i].push_back(s);
        } else if (type == 2) {
            int t;
            cin >> t;
            times.push_back(t);
            queries[i].push_back(t);
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            times.push_back(l);
            times.push_back(r);
            queries[i].push_back(l);
            queries[i].push_back(r);
            queries[i].push_back(v);
        }
    }
    times.push_back(inf);
    sort(times.begin(), times.end());
    times.erase(unique(times.begin(), times.end()), times.end());
    vector< pair< long long, long long > > tpr;
    for (int i = 0; i + 1 < times.size(); ++i) {
        tpr.emplace_back(times[i], times[i + 1]);
    }
    segtree tr(tpr);
    // show(tpr, tr.tree);
    for (int i = 0; i < q; ++i) {
        if (queries[i][0] == 1) {
            long long t = queries[i][1], s = queries[i][2];
            tr.set(lower_bound(times.begin(), times.end(), t) - times.begin(), t, s);
        } else if (queries[i][0] == 2){
            long long t = queries[i][1];
            tr.erase(lower_bound(times.begin(), times.end(), t) - times.begin());
        } else {
            long long l = queries[i][1]; l = lower_bound(times.begin(), times.end(), l) - times.begin();
            long long r = queries[i][2]; r = lower_bound(times.begin(), times.end(), r) - times.begin();
            long long v = queries[i][3];
            long double ans = tr.ask(l, r, v);
            if (ans > queries[i][2] || ans < 0)
                cout << -1 << '\n';
            else
                cout << setprecision(10) << ans << '\n';
        }
        // for (auto k : tr.tree) {
        //     show(k);
        // }
        // shows;
    }
    return 0;
}

#include <bits/stdc++.h>
#define watch(x) std::cout << "$ LINE @" << __LINE__ << " FUNC @" << __FUNCTION__ << "\n$ " \
                           << (#x) << ": " << x << std::endl

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

template <typename Tp>
inline void read(Tp &x)
{
    static char c;
    static bool neg;
    x = 0, c = getchar(), neg = false;
    for (; !isdigit(c); c = getchar())
    {
        if (c == '-')
        {
            neg = true;
        }
    }
    for (; isdigit(c); c = getchar())
    {
        x = x * 10 + c - '0';
    }
    if (neg)
    {
        x = -x;
    }
}

typedef pair<double, ll> pdl;

const int INF = 1e9 + 5;
const int N = 1e5 + 5;

int q;

namespace Seg
{
#define lson son[0]
#define rson son[1]

    struct Node
    {
        Node *son[2];
        bool flag;
        int set;
        ll sum, lsum;
        inline void pushUp();
        inline void pushDown(int, int);
        inline void setVal(int);
        inline void ensureLeft();
        inline void ensureRight();
        inline void ensureBoth();
    };

    inline Node *newNode()
    {
        Node *res = new Node();
        res->son[0] = res->son[1] = nullptr;
        res->flag = false;
        res->set = 0;
        res->sum = res->lsum = 0LL;
        return res;
    }
    inline void Node::pushUp()
    {
        ensureBoth();
        sum = lson->sum + rson->sum;
        lsum = std::min(lson->lsum, lson->sum + rson->lsum);
    }
    inline void Node::pushDown(int l, int r)
    {
        if (flag)
        {
            int mid = (l + r) >> 1;
            ensureBoth();
            lson->flag = rson->flag = true;
            lson->set = rson->set = set;
            lson->sum = (ll)(mid - l + 1) * set;
            lson->lsum = set >= 0 ? 0 : lson->sum;
            rson->sum = (ll)(r - mid) * set;
            rson->lsum = set >= 0 ? 0 : rson->sum;
            flag = false;
        }
    }
    inline void Node::ensureLeft()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
    }
    inline void Node::ensureRight()
    {
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    inline void Node::ensureBoth()
    {
        if (lson == nullptr)
        {
            lson = newNode();
        }
        if (rson == nullptr)
        {
            rson = newNode();
        }
    }
    void update(Node *u, int l, int r, int ul, int ur, int x)
    {
        if (ul <= l && r <= ur)
        {
            u->flag = true;
            u->set = x;
            u->sum = (ll)(r - l + 1) * x;
            u->lsum = x >= 0 ? 0 : u->sum;
            return;
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        if (ul <= mid)
        {
            u->ensureLeft();
            update(u->lson, l, mid, ul, ur, x);
        }
        if (mid < ur)
        {
            u->ensureRight();
            update(u->rson, mid + 1, r, ul, ur, x);
        }
        u->pushUp();
    }
    pdl query(Node *u, int l, int r, int ql, int qr, ll x)
    {
        if (ql <= l && r <= qr)
        {
            if (u->lsum + x > 0)
            {
                return (pdl){-1.0, u->sum};
            }
            if (l == r)
            {
                return (pdl){(double)l - (double)x / (double)u->sum, u->sum};
            }
            if (u->flag)
            {
                return (pdl){(double)l - (double)x / (double)(u->sum / (ll)(r - l + 1)), u->sum};
            }
            int mid = (l + r) >> 1;
            u->ensureBoth();
            pdl res = query(u->lson, l, mid, ql, qr, x);
            if (res.first > 0)
            {
                return res;
            }
            else
            {
                pdl pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
                return (pdl){pir.second, res.second + pir.second};
            }
        }
        u->pushDown(l, r);
        int mid = (l + r) >> 1;
        pdl res = (pdl){-1.0, 0}, pir;
        if (ql <= mid)
        {
            u->ensureLeft();
            res = query(u->lson, l, mid, ql, qr, x);
        }
        if (mid < qr)
        {
            if (res.first > 0)
            {
                return res;
            }
            u->ensureRight();
            pir = query(u->rson, mid + 1, r, ql, qr, res.second + x);
            res = (pdl){pir.first, res.second + pir.second};
        }
        return res;
    }

#undef lson
#undef rson
} // namespace Seg

int main()
{
    read(q);
    map<int, int> timeline;
    int L = 1, R = INF;
    timeline[L - 1] = timeline[R + 1] = 0;
    auto root = Seg::newNode();
    for (int i = 0, op, x, y, z; i < q; ++i)
    {
        read(op);
        if (op == 1)
        {
            read(x), read(y);
            timeline[x] = y;
            Seg::update(root, L, R - 1, x, std::min(next(timeline.find(x))->first, R) - 1, y);
        }
        else if (op == 2)
        {
            read(x);
            auto iter = timeline.find(x);
            Seg::update(root, L, R - 1, x, std::min(next(iter)->first, R) - 1, prev(iter)->second);
            timeline.erase(iter);
        }
        else
        {
            read(x), read(y), read(z);
            if (z == 0)
            {
                printf("%d\n", x);
            }
            else
            {
                x = timeline.lower_bound(x)->first;
                if (x >= y)
                {
                    puts("-1");
                }
                else
                {
                    auto ans = Seg::query(root, L, R - 1, x, y - 1, z);
                    if (ans.first < 0)
                    {
                        puts("-1");
                    }
                    else
                    {
                        printf("%.8f\n", ans.first);
                    }
                }
            }
        }
    }
}

    #include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

#define pitem item*
#define tam 1023456
#define tamN 12345
using namespace std;
typedef long long ll;

typedef pair<ll,ll> ii;
typedef pair<int,ii> iii;
const ll INF=1e18;
struct item
{
    int prior,cnt;
    ll pos,speed,minn,tot;
    ii pos_viz;
    ii pos_vder;
    pitem l;
    pitem r;
    item(){}
    item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
    {
        prior=rand();
        minn=INF;
        pos_viz=pos_vder=ii(pos,speed);
    }

};
int cnt(pitem t){return t?t->cnt:0;}
ll gtot(pitem t){return t?t->tot:0;}
ll gmin(pitem t){return t?t->minn:INF;}

ll gextraiz(pitem t){
    if (!t|| (!t->l))
        return INF;
    else
        return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
}
ll gextrader(pitem t){
    if (!t|| (!t->r))
        return INF;
    return  (t->r->pos_viz.f-t->pos)*(t->speed);
}
void upd_cnt(pitem t)
{
    if (t)
    {
        t->cnt=cnt(t->l)+cnt(t->r)+1;
        ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
        t->tot=totiz;
        t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
        if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
        if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
        t->tot+=gtot(t->r);
        t->minn=gmin(t->l);
        t->minn=min(t->minn,totiz+extraiz);
        t->minn=min(t->minn,totiz+extraiz+extrader);
        t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
    }
}
void split(pitem t,pitem &l,pitem &r,int key)
{
    if (!t)
        return void(l=r=0);
    if (t->pos>key)
        split(t->l,l,t->l,key),r=t;
    else
        split(t->r,t->r,r,key),l=t;
    upd_cnt(t);
}
void merge(pitem &t,pitem l,pitem r)
{
    if (!l||!r)
        t=l?l:r;
    else if (r->prior>l->prior)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd_cnt(t);
}
ll auxresp;
double respf;ll iz,der;
pitem ant_t;
bool print=false;
void query(pitem t,ll inival)
{

    if (t==0)
    {
        if (!ant_t)
            return void(auxresp=-1);
        if (print==1)
            cout<<"ultimo\n";
        // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
        ll extra;
        extra=(der-ant_t->pos)*(ant_t->speed);
        if (inival+extra<=0)
        {
            auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
            respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
            return;
        }
        else
            return void(auxresp=-1);
    }
    ant_t=t;
    ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
    if (gmin(t->l)+inival<=0)
    {
        query(t->l,inival);
        // cout<<"go left\n";
    }
    else
    {
        ll extraiz,extrader,totiz;
        extraiz=(t->l)?gextraiz(t):0;
        extrader=(t->r)?gextrader(t):0;
        totiz=gtot(t->l);
        ll auxini=totiz+extraiz+extrader;
        // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
        if (totiz+extraiz+inival<=0)
        {
            inival+=totiz;
            auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
            respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
            if (print)
            cout<<"ramo izquierdo\n";
            if (print)
                if ((inival)/(t->l->pos_vder.s)>=0)
                cout<<"wat\n";
            else
                cout<<"nelperro\n";

        }
        else if (totiz+extraiz+extrader+inival<=0)
        {
            if (print)
            cout<<"ramo derecho\n";
            inival+=totiz+extraiz;
            auxresp=(t->pos)-(inival)/(t->speed);//-.-
            respf=-(double)(inival%t->speed)/(t->speed);//-.-

        }
        else
            {

                // cout<<"go right\n";
                query(t->r,auxini+inival);
            }

    }
}

int main()
{
    int casos;
    scanf("%d",&casos);
    if (casos==100)
        print=1;
    int tipo;
    pitem t1;pitem t2;pitem t3;
    pitem s;
    pitem tree=new item(1e9+1,1);
    ll val,pos;
    double auxrespf;
    while(casos--)
    {
        scanf("%d",&tipo);
        if (tipo==1)
        {
            scanf("%lld %lld",&pos,&val);
            if (val==0)
            {
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
                continue;
            }
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            s=new item(pos,val);
            merge(tree,t1,s);
            merge(tree,tree,t3);
        }
        else if (tipo==2)
        {
            scanf("%lld",&pos);
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            merge(tree,t1,t3);
        }
        else if (tipo==3)
        {
            scanf("%lld %lld %lld",&iz,&der,&val);
            if (val==0)
            {
                printf("%lld.0\n",iz);
                continue;
            }
            split(tree,t1,t3,der);
            split(t1,t1,t2,iz-1);
            ant_t=NULL;
            query(t2,val);
            if (auxresp==-1)
                printf("-1\n");
            else
            {
                auxrespf=auxresp+respf;
                printf("%.9lf\n",auxrespf);
            }
            merge(tree,t1,t2);
            merge(tree,tree,t3);
        }
     //   inorder(tree);
        //// cout<<endl;
    }
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef double db;
typedef long double ldb;

typedef long long ll;
typedef pair<ll,int> pr;

int num[300005];
int cnt;

namespace SGT {

ll sumv[1200000],minn[1200000],setv[1200000];

inline void pushdown(int l,int r,int o) {
  if (setv[o]!=-1) {
  	int m=((l+r)>>1);
  	sumv[o*2]=setv[o]*(num[m+1]-num[l]);minn[o*2]=min(0LL,sumv[o*2]);
  	sumv[o*2+1]=setv[o]*(num[r+1]-num[m+1]);minn[o*2+1]=min(0LL,sumv[o*2+1]);
  	setv[o*2]=setv[o*2+1]=setv[o];
  	setv[o]=-1;
  }
}

inline void pushup(int o) {
  sumv[o]=sumv[o*2]+sumv[o*2+1];
  minn[o]=min(minn[o*2],sumv[o*2]+minn[o*2+1]);
}

void update(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) {
  	sumv[o]=p*(num[r+1]-num[l]);minn[o]=min(0LL,sumv[o]);
  	setv[o]=p;
  }
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=lx) update(l,m,o*2,lx,rx,p);
  	if (m<rx) update(m+1,r,o*2+1,lx,rx,p);
  	pushup(o);
  }
}

pr query2(int l,int r,int o,ll p) {
  if (l==r) return pr(p,l);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (p+minn[o*2]<=0) return query2(l,m,o*2,p);
  	else return query2(m+1,r,o*2+1,p+sumv[o*2]);
  }
}

pr query1(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) return (p+minn[o]<=0)?query2(l,r,o,p):pr(p+sumv[o],-1);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query1(l,m,o*2,lx,rx,p);
  	if (m<lx) return query1(m+1,r,o*2+1,lx,rx,p);
  	pr a=query1(l,m,o*2,lx,rx,p);
  	if (a.SE!=-1) return a;
	return query1(m+1,r,o*2+1,lx,rx,a.FR);
  }
}

ll query3(int l,int r,int o,int p) {
  if (l==r) return setv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=p) return query3(l,m,o*2,p);
  	else return query3(m+1,r,o*2+1,p);
  }
}

ll query4(int l,int r,int o,int lx,int rx) {
  if (l>=lx&&r<=rx) return sumv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query4(l,m,o*2,lx,rx);
  	if (m<lx) return query4(m+1,r,o*2+1,lx,rx);
  	return query4(l,m,o*2,lx,rx)+query4(m+1,r,o*2+1,lx,rx);
  }
}

}

struct Ope {
  int l,r,v,kind;
  Ope() {}
  Ope(int a,int b,int c,int d):l(a),r(b),v(c),kind(d) {}
};

Ope a[100005];
set <int> st;

int val[100005];

int main() {
  memset(val,0x3f,sizeof(val));
  int m;
  scanf("%d",&m);
  int n=0;
  for(int i=1;i<=m;i++) {
  	int kind;
  	scanf("%d",&kind);
  	if (kind==1) {
  		int x,y,z;
  		scanf("%d%d",&x,&y);
  		a[i]=Ope(x,x,y,1);
  		num[++n]=x;
	  }
	else if (kind==2) {
		int x;
		scanf("%d",&x);
		a[i]=Ope(x,x,0,2);
		num[++n]=x;
	}
	else {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		a[i]=Ope(x,y,z,3);
		num[++n]=x;num[++n]=y;
	}
  }
  num[++n]=0;num[++n]=1e9+1;
  sort(num+1,num+n+1);
  n=unique(num+1,num+n+1)-num-1;
  st.insert(1);st.insert(n);
  for(int i=1;i<=m;i++)
    if (a[i].kind==1) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	st.insert(t);
    	set<int>::iterator it=st.lower_bound(t);
    	it++;
    	int t2=(*it);
    	SGT::update(1,n,1,t,t2-1,a[i].v);
    	if (m==10000) val[a[i].l]=a[i].v;
    	if (m==10000&&a[i].v==-1) printf("%d %d %d %d\n",i,a[i].l,t,t2-1);
	}
	else if (a[i].kind==2) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	set<int>::iterator it=st.lower_bound(t),it2=it;
    	it--;it2++;
    	int t1=(*it),t2=(*it2);
    	st.erase(t);
    	SGT::update(1,n,1,t,t2-1,SGT::query3(1,n,1,t1));
    	if (m==10000) val[a[i].l]=inf;
	}
	else {
		cnt++;
		if (!a[i].v) {
			if (m!=10000) printf("%d\n",a[i].l);
			continue;
		}
		int l=lower_bound(num+1,num+n+1,a[i].l)-num,r=lower_bound(num+1,num+n+1,a[i].r)-num-1;
		set<int>::iterator it=st.lower_bound(l);
		l=(*it);
		if (l>r) {
			if (m!=10000) puts("-1");
			continue;
		}
		pr t=SGT::query1(1,n,1,l,r,a[i].v);
		if (t.SE!=-1) {
			db v=SGT::query3(1,n,1,t.SE);
			if (m!=10000) printf("%.8f\n",(db)(num[t.SE]+(ldb)(-t.FR)/v));
		}
		else if (m!=10000) puts("-1");
	}
  return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(time(NULL));
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void ispis(pnode x){

    if(x==NULL)return;
    push(x);

    ispis(x->l);
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void upd(pnode x){
    if(x==NULL)return;
    x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_val(x->l)<=val){
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*printf("ISPIS\n");
        ispis(midtree);
        printf("\n");*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
       /// printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);

    scanf("%d",&q);
    while(q--){

        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            cout<<query(l,r,v)<<endl;
            ///printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(500);
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void upd(pnode x){
    if(x==NULL)return;
    ///x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
    x->mn=x->val;
    if(x->l!=NULL)x->mn=x->l->val<x->mn?x->l->val:x->mn;
    ///pnode pr=x->r;
    if(x->r!=NULL)x->mn=
        x->r->val<x->mn?
        x->r->val:x->mn;
}
void ispis(pnode x,int &ct){

    if(ct<1)return;
    if(x==NULL)return;
    push(x);
    upd(x);

    ispis(x->l,ct);
    ct--;
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r,ct);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
    upd(l);
    upd(r);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);
    upd(x);
    ///if(sq==10000)cout<<val<<" "<<get_mn(x->l)<<" "<<x->val<<" "<<x->t<<" U KURAC VISE\n";

    if(get_mn(x->l)<=val){
        if(sq==10000)printf("LEFT\n");
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else{
        if(sq==10000)printf("right\n");
        qry(x->r,val,tm);
    }
}
void go(pnode x){

    if(x==NULL)return;

    push(x);
    ////upd(x);
    if(sq==10000)cout<<" "<<get_mn(x->l)<<" "<<x->val<<" "<<x->t<<" U KURAC \n";

    if(x->l!=NULL){
        go(x->l);
    }
    else{
        go(x->r);
    }

}
int e;
void trazi(pnode x,ll val){

    if(x==NULL)return;
    if(x->t==val){
        e=1;
        printf("NASAO\n");
        return;
    }
    else{
        trazi(x->l,val);
        if(!e){
            trazi(x->r,val);
            if(e)printf("RIGHT\n");
        }
        else{
            if(e)printf("LEFT\n");
        }
    }

}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*if(sq==10000){
            printf("\n\nISPIS A\n");
            int pm=12;
            ///ispis(midtree,pm);
            go(midtree);
            printf("\n");
        }*/

        trazi(midtree,11233);

        //// mozda vamo bude greska ako nema proslog
        int tm=0;
        ///if(sq==10000)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);

            if(sq==10000){
                ///go(midtree);
            }

            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            ///if(sq==10000)printf("%d TMTM\n",tm);
            ///if(tm==0 || pom1==NULL)printf("AAAJEBOTE\n");

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            if(sq==10000){
                ///cout<<lst->val<<" "<<lst->t<<" "<<lst->s<<" "<<zero<<" EVO GA"<<endl;
            }
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<" "<<s<<endl;}
            else ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<endl;}
            else del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(sq==101){
                cout<<tip<<" "<<l<<" "<<r<<" "<<v<<endl;
                continue;
            }
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            cout<<fixed;
            cout<<setprecision(6);
            cout<<query(l,r,v)<<endl;
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>

using namespace std;

const long long MAX_N = 1 << 18;

long long sum[2 * MAX_N];
long long minVal[2 * MAX_N];
long long posSum[2 * MAX_N];
long long value[2 * MAX_N];
map<int, int> M;

void update(long long node, long long low, long long high, long long nlow, long long nhigh, long long val) {
    if (nhigh < low || nlow > high) return;
    if (low >= nlow && high <= nhigh) {
        value[node] = val;
        sum[node] = (long long) val * (posSum[high + 1] - posSum[low]);
        if (val >= 0) {
            minVal[node] = 0;
        } else {
            minVal[node] = sum[node];
        }
        return;
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    update(node * 2 + 1, low, mid, nlow, nhigh, val);
    update(node * 2 + 2, mid + 1, high, nlow, nhigh, val);
    minVal[node] = min(minVal[node * 2 + 1], sum[node * 2 + 1] + minVal[node * 2 + 2]);
    sum[node] = sum[node * 2 + 1] + sum[node * 2 + 2];
}

double findPos(long long node, long long low, long long high, long long val) {
    if (low == high) {
        if (val == 0) return (double) posSum[low];
        if (value[node] >= 0) return -1.0;
        return posSum[low] + val / (double) (-value[node]);
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    if (-minVal[node * 2 + 1] >= val)
        return findPos(node * 2 + 1, low, (low + high) / 2, val);
    return findPos(node * 2 + 2, (low + high) / 2 + 1, high, val + sum[node * 2 + 1]);
}

pair<double, long long> get(long long node, long long low, long long high, long long nlow, long long nhigh, long long val) {
    if (nhigh < low || nlow > high) return {-1.0, 0};
    if (low >= nlow && high <= nhigh) {
        if (-minVal[node] >= val) {
            return {findPos(node, low, high, val), 0.0};
        }
        return {-1.0, sum[node]};
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    auto res = get(node * 2 + 1, low, mid, nlow, nhigh, val);
    if (res.first > -0.5)
        return res;
    auto ret = get(node * 2 + 2, mid + 1, high, nlow, nhigh, res.second + val);
    ret.second += res.second;
    return ret;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long q; cin >> q;
    vector<int> type(q);
    vector<int> a(q);
    vector<int> b(q);
    vector<int> c(q);
    vector<int> t; t.clear();
    for (long long i = 0; i < q; ++i) {
        cin >> type[i];
        if (type[i] == 1) cin >> a[i] >> b[i], t.push_back(a[i]);
        else if (type[i] == 2) cin >> a[i];
        else cin >> a[i] >> b[i] >> c[i], t.push_back(a[i]), t.push_back(b[i]);
    }

    sort(t.begin(), t.end());
    t.push_back(t.back() + 1);
    vector<int> nt = t;
    t.clear();
    for (long long i = 0; i < nt.size(); ++i)
        if (i == 0 || nt[i] != nt[i - 1])
            t.push_back(nt[i]);
    M.clear();
    for (long long i = 0; i < t.size(); ++i) {
        posSum[i] = t[i];
        M[t[i]] = i;
    }

    set<pair<int, int>> S; S.clear();
    S.insert({t.back(), 1e9});
    for (long long i = 0; i < q; ++i) {
        if (type[i] == 1) {
            auto it = S.lower_bound({a[i], 0});
            update(0, 0, MAX_N - 1, M[a[i]], M[(*it).first] - 1, b[i]);
            S.insert({a[i], b[i]});
        } else if (type[i] == 2) {
            auto it = S.lower_bound({a[i], -1e9 - 1});
            long long val = 0;
            if (it != S.begin()) {
                --it;
                val = (*it).second;
                ++it;
            }
            ++it;
            update(0, 0, MAX_N - 1, M[a[i]], M[(*it).first] - 1, val);
            --it;
            S.erase(it);
        } else {
            auto it = S.lower_bound({a[i], -1e9 -1});
            if (it == S.end() || (*it).first > b[i]) {
                printf("%.7lf\n", c[i] == 0 ? a[i] : -1.0);
            } else {
                auto pos = get(0, 0, MAX_N - 1, M[(*it).first], M[b[i]], c[i]);
                printf("%.7lf\n", (pos.first > b[i] ? -1.0 : pos.first));
            }
        }
    }

    return 0;
}

#include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int maxn=1e5+10;

inline char gc(){
	return getchar();
	static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd(){
    ll x=0;char c=gc();bool neg=0;
    while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();}
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc();
    return neg?(~x+1):x;
}

int op[maxn][4],data[maxn],Q,M;

struct Node{
	int tim[2],out;
	ll low,cg;
}t[maxn<<2];

inline Node operator +(Node a,Node b){
	Node p;
	if(a.tim[0]<0) p=b;
	else if(b.tim[0]<0) p=a;
	else{
		p.tim[0]=a.tim[0],p.tim[1]=b.tim[1];
		p.out=b.out;
		p.low=min(a.low,a.cg+1ll*(data[b.tim[0]]-data[a.tim[1]])*a.out+min(b.low,0ll));
		p.cg=a.cg+1ll*(data[b.tim[0]]-data[a.tim[1]])*a.out+b.cg;
	}return p;
}

inline void build(int p,int l,int r){
	if(l==r){
		t[p].tim[0]=t[p].tim[1]=-1;
	}else{
		int m=l+r>>1;
		build(p<<1,l,m);build(p<<1|1,m+1,r);
		t[p]=t[p<<1]+t[p<<1|1];
	}
}

inline void del(int p,int l,int r,int x){
	// printf("DD%d %d %d %d\n",p,l,r,x);
	if(l==r){
		t[p].tim[0]=t[p].tim[1]=-1;
	}else{
		int m=l+r>>1;
		if(x<=m) del(p<<1,l,m,x);
		else del(p<<1|1,m+1,r,x);
		t[p]=t[p<<1]+t[p<<1|1];
	}
}

inline void insert(int p,int l,int r,int x,int y){
	// printf("II%d %d %d %d %d\n",p,l,r,x,y);
	if(l==r){
		t[p].tim[0]=t[p].tim[1]=l;
		t[p].out=y;
	}else{
		int m=l+r>>1;
		if(x<=m) insert(p<<1,l,m,x,y);
		else insert(p<<1|1,m+1,r,x,y);
		t[p]=t[p<<1]+t[p<<1|1];
	}
}

inline void query(int p,int l,int r,int x,int y,Node &q){
	if(l<=x&&r<=y) q=q+t[p];
	else{
		int m=l+r>>1;
		if(x<=m) query(p<<1,l,m,x,y,q);
		if(y>=m+1) query(p<<1|1,m+1,r,x,y,q);
	}
}

int main(){
    //freopen("","r",stdin);
    Q=rd();int j=0;
    for(int i=1;i<=Q;i++){
    	op[i][0]=rd();
    	if(op[i][0]==1) data[++j]=op[i][1]=rd(),op[i][2]=rd();
    	else if(op[i][0]==2) op[i][1]=rd();
    	else op[i][1]=rd(),op[i][2]=rd(),op[i][3]=rd();
    }
    sort(data+1,data+j+1);
    M=unique(data+1,data+j+1)-data-1;

    build(1,1,M);
    // puts("aa");
    for(int i=1;i<=Q;i++){
    	// printf("~%d\n",i);
    	if(op[i][0]==1){
    		insert(1,1,M,lower_bound(data+1,data+M+1,op[i][1])-data,op[i][2]);
    	}else if(op[i][0]==2){
    		del(1,1,M,lower_bound(data+1,data+M+1,op[i][1])-data);
    	}else{
    		if(op[i][3]==0){
    			printf("%d\n",op[i][1]);
    			continue;
    		}
    		Node p;
    		p.tim[0]=p.tim[1]=-1;
    		p.cg=0,p.low=0;
    		int x=lower_bound(data+1,data+M+1,op[i][1])-data;
    		int y=op[i][2];
    		int z=op[i][3],ans=x;
    		for(int l=x,r=M;l<=r;){
    			int m=l+r>>1;
    			Node q;
    			q.tim[0]=q.tim[1]=-1;
	    		q.cg=0,q.low=0;
    			query(1,1,M,l,m,q);
    			if(q.low+z>0) p=q,ans=m,l=m+1;
    			else r=m-1;
    		}
    		double a=-1;
    		if(data[ans]<=y&&p.out<=0){
    			if(ans<M){
    				Node pp;pp.tim[0]=-1;
    				query(1,1,M,ans+1,M,pp);
    				if(pp.tim[0]!=-1) y=min(y,data[pp.tim[0]]);
    			}
    			a=-1.0*(z+p.cg)/p.out+data[p.tim[1]];
    			// printf("~%d %d %d %d %d\n",ans,p.cg,z,y,data[p.tim[1]]);
    			if(a>y) a=-1;
    		}
    		printf("%.10lf\n",a);
    	}
    }
    return 0;
}

#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("-O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define sset ordered_set
#define sqr(x) (x)*(x)
#define pw(x) (1ll << x)

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
const ll MAXN = 1123456;
const ll N = 2e5;
mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T> void vout(T s){cout << s << endl;exit(0);}

struct node{
    bool us;
    ll tl, tr, last_s, sum, min_pref, pref_sum;
    node *l, *r;
    node(int le, int ri): tl(le), tr(ri), pref_sum(ri - le + 1), last_s(0), sum(0), min_pref(0), us(0), l(r=nullptr){}
};

struct nd{
    bool us;
    ll tl, tr, last_s, sum, min_pref, pref_sum;
};

ll pos;
pll val;

node *root;

nd add(node *a, ll last_s){
    nd res;
    res.sum = a -> sum + last_s * a -> pref_sum;
    res.min_pref = min(a -> min_pref, 0ll);
    res.min_pref += last_s * (a -> pref_sum);
    res.min_pref = min(res.min_pref, last_s);
    return res;
}

void unite(node *a, node *l, node *r){
    a -> tl = l -> tl;
    a -> tr = r -> tr;
    a -> us = l -> us | r -> us;
    a -> sum = l -> sum + r -> sum;
    ll RM = r -> min_pref;
    if(l -> us && r -> pref_sum){
        RM = min(RM, 0ll);
        RM += (l -> last_s) * (r -> pref_sum);
        RM = min(RM, l -> last_s);
        a -> sum += (l -> last_s) * (r -> pref_sum);
    }
    a -> l = l;
    a -> r = r;

    a -> min_pref = min(l -> min_pref, l -> sum + RM);
    a -> pref_sum = l -> pref_sum;
    if(l -> pref_sum == l -> tr - l -> tl + 1)a -> pref_sum += r -> pref_sum;

    if(r -> us)a -> last_s = r -> last_s;
    else a -> last_s = l -> last_s;
}

void modify(node *v){
    if(v -> tl == v -> tr){
        v -> us = val.se;
        v -> last_s = val.fi;
        if(val.se){
            v -> sum = v -> min_pref = val.fi;
            v -> pref_sum = 0;
        }else{
            v -> sum = v -> min_pref = 0;
            v -> pref_sum = 1;
        }
        return;
    }
    ll tm = (v -> tl + v -> tr) >> 1;

    if(v -> l == nullptr){
        v -> l = new node(v -> tl, tm);
    }

    if(v -> r == nullptr){
        v -> r = new node(tm + 1, v -> tr);
    }

    if(pos <= tm)modify(v -> l);
    else modify(v -> r);
    unite(v, v -> l, v -> r);

}

node *Ans;

ll V;

bool ok;

ld ans = -1;
ll last_S;
void dfs(node *v){
    if(v -> tl == v -> tr){
        ok = 1;
        ans = v -> tl - 1;
        if(v -> us)last_S = v -> last_s;
        if(last_S != 0)ans += ld(V) / -last_S;
        return;
    }
    ll tm = (v -> tl + v -> tr) >> 1;
    if(v -> l == nullptr){
        v -> l = new node(v -> tl, tm);
    }

    if(v -> r == nullptr){
        v -> r = new node(tm + 1, v -> tr);
    }

    nd rt = add(v -> l, last_S);

    if(rt.min_pref + V <= 0)dfs(v -> l); else{
        V += rt.sum;
        if((v -> l) -> us)last_S = (v -> l) -> last_s;
        dfs(v -> r);
    }

}
void get(node *v, ll l, ll r){
    if(l > r)return;
    if(ok)return;
    if(v -> tl == l && v -> tr == r){
        nd rt = add(v, last_S);
        if(V + rt.min_pref <= 0){
            dfs(v);
        }else{
            V += rt.sum;
            if(v -> us)last_S = v -> last_s;
        }
        return;
    }
    ll tm = (v -> tl + v -> tr) >> 1;
    if(v -> l == nullptr){
        v -> l = new node(v -> tl, tm);
    }

    if(v -> r == nullptr){
        v -> r = new node(tm + 1, v -> tr);
    }
    get(v -> l, l, min(r, tm));
    get(v -> r, max(tm + 1, l), r);
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

    ll q;
    cin >> q;

    root = new node(1, 1e9);

    while(q--){
        ll t;
        cin >> t;
        if(t == 1){
            ll s;
            cin >> pos >> s;
            val = {s, 1};
            modify(root);
        }else if(t == 2){
            cin >> pos;
            val = {0ll, 0ll};
            modify(root);
        }else {
            ok = 0;
            ans = -1;
            last_S = 0;
            ll l, r;
            cin >> l >> r >> V;
            get(root, l, r - 1);
            if(!ok)cout << "-1\n"; else cout << fixed << setprecision(6) << ans + 1 << "\n";
        }

    }

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll __int128
#define int __int128
#define double long double
#define pii pair<int, int>
#define ull unsigned ll
#define f first
#define s second
#define ALL(x) x.begin(),x.end()
#define SZ(x) (int)x.size()
#define SQ(x) (x)*(x)
#define MN(a,b) a = min(a,(__typeof__(a))(b))
#define MX(a,b) a = max(a,(__typeof__(a))(b))
#define pb push_back
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#ifdef BALBIT
#define IOS()
#define bug(...) fprintf(stderr,"#%d (%s) = ",__LINE__,#__VA_ARGS__),_do(__VA_ARGS__);
template<typename T> void _do(T &&x){cerr<<(long long)x<<endl;}
template<typename T, typename ...S> void _do(T &&x, S &&...y){cerr<<(long long)x<<", ";_do(y...);}
#else
#define IOS() ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define bug(...)
#endif

const int iinf = 1e9+10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const __int128 INF = 0x3f3f3f3f3f3f3f3f3f3f3f3f;
const ll mod = 1e9+7 ;

void GG(){cout<<"0\n"; exit(0);}

ll mpow(ll a, ll n, ll mo = mod){ // a^n % mod
    ll re=1;
    while (n>0){
        if (n&1) re = re*a %mo;
        a = a*a %mo;
        n>>=1;
    }
    return re;
}

ll inv (ll b, ll mo = mod){
    if (b==1) return b;
    return (mo-mo/b) * inv(mo%b) % mo;
}

const int maxn = 1e5+5;

ll mn[maxn*4], tg[maxn*4];
set<ll> have;
//map<ll, int> id;

void push(int o, int l, int r){
    if (tg[o]) {
        mn[o] += tg[o];
        if (l!=r) {
            tg[o*2] += tg[o];
            tg[o*2+1] += tg[o];
        }
        tg[o] = 0;
    }
}
int n;
void MO(int L, int R, ll v, int o=1, int l=0, int r=n-1) {
    push(o,l,r);
    if (l>R || r<L) return;
    if (l >= L && r <= R) {
        tg[o] += v;
        push(o,l,r);
        return;
    }
    int mid = (l+r)/2;
    MO(L,R,v,o*2,l,mid);
    MO(L,R,v,o*2+1,mid+1,r);
    mn[o] = min(mn[o*2], mn[o*2+1]);
}

ll QU(int L, int R, int o=1, int l=0, int r=n-1) {
    push(o,l,r);
    if (l>R || r<L) return inf;
    if (l>=L && r<=R) {
        return mn[o];
    }
    int mid = (l+r)/2;
    return min(QU(L,R,o*2,l,mid), QU(L,R,o*2+1,mid+1,r));
}

struct Que{
    int Tp;
    int t,s,l,r,v;
};

int slope[maxn];
bool state[maxn];

signed main(){
    IOS();
    signed Q; cin>>Q;
    vector<Que> queries;
    vector<ll> allt;
    allt.pb(0); allt.pb(1000000005);
    have.insert(0); have.insert(1000000005);
    for (int i = 0; i<Q; ++i) {
        signed Tp; cin>>Tp;
        if (Tp == 1) {
            signed t,s;cin>>t>>s; allt.pb(t);
            queries.pb({Tp,t,s,0,0,0});
        }
        if (Tp == 2) {
            signed t; cin>>t; allt.pb(t);
            queries.pb({Tp,t,0,0,0,0});
        }
        if (Tp == 3) {
            signed l,r,v; cin>>l>>r>>v;
            queries.pb({Tp,0,0,l,r,v});
        }
    }
    SORT_UNIQUE(allt);
    n = SZ(allt);
    bug(n);
    MO(1,n-2,0x3f3f3f3f3f3f3f3);
//    MO(0,0,-inf);
//    MO(n-1,n-1,-inf);
    state[0] = 1;
    cout<<fixed<<setprecision(10);
    for (Que q: queries) {
        int lp, rp;

        if (q.Tp == 1) {

            lp = *prev(have.upper_bound(q.t)), rp = *have.upper_bound(q.t);
            int lat = lower_bound(ALL(allt), lp) - allt.begin();
            int rat = lower_bound(ALL(allt), rp) - allt.begin();
            int mat = lower_bound(ALL(allt), q.t) - allt.begin();
            assert(rat!=mat);
            assert(lat != mat);
            ll bfr = QU(rat,rat);
//            __int128 tmp = (q.t-lp) * (__int128)(bfr - QU(lat,lat));
//            if(tmp % ((rp-lp)) != 0)while(1);
            ll myv = QU(lat,lat) + slope[lat] * (q.t-lp);
            ll prevme = QU(mat,mat);
            bug(prevme, myv);

            MO(mat,mat,myv-prevme);
            bug(QU(mat,mat));
            assert(myv == QU(mat,mat));

            slope[mat] = q.s;
            ll newr = myv + (rp-q.t) * q.s;
            MO(rat, n-1, newr-bfr);
            bug(rat, (rp-q.t) * q.s);
            bug(mat, QU(mat,mat), QU(rat, rat));
            have.insert(q.t);
        }

        if(q.Tp==2) {
            if (!have.count(q.t)) assert(0);
            have.erase(q.t);
            lp = *prev(have.upper_bound(q.t)), rp = *have.upper_bound(q.t);
            int lat = lower_bound(ALL(allt), lp) - allt.begin();
            int rat = lower_bound(ALL(allt), rp) - allt.begin();
            int mat = lower_bound(ALL(allt), q.t) - allt.begin();
            MO(mat, mat, 0x3f3f3f3f3f3f3f3-QU(mat,mat));
            ll oldr = QU(rat, rat);
            ll newr = (rp-lp) * slope[lat] + QU(lat, lat);
            MO(rat, n-1, newr-oldr);
        }

        if (q.Tp == 3) {
            ll st = *have.lower_bound(q.l), stp = lower_bound(ALL(allt), st) - allt.begin();
            int mat = lower_bound(ALL(allt), q.l) - allt.begin();
//            bug(lp,rp,lat,rat);
//            bug(QU(lat,lat), QU(rat, rat));
            ll myv = QU(stp,stp);
            bug(q.l, myv);
            if (q.v == 0) {
                cout<<(long long)q.l<<endl; continue;
            }
            myv -= q.v;
            int l = mat, r = n-1;
            while(l!=r) {
                int mid = (l+r)/2;
                if (QU(mat, mid)<=myv) {
                    r = mid;
                }else{
                    l = mid+1;
                }
            }
            bug(l);
            if ( l >= n || l == mat) {
                cout<<-1<<endl; continue;
            }
//            assert(have.count(allt[l]));
            int prv = *prev(have.lower_bound(allt[l])), pp = lower_bound(ALL(allt), prv) - allt.begin();
            int A = QU(pp,pp), B = QU(l,l);
            bug(pp,l);
            bug(A,B,prv, allt[l]);
            if (B <= myv) {
                if (A==B) while(1);
                double ans = (myv-A) / (double) (B-A) * (allt[l]-prv)   + prv;
                if (ans <= q.r +1e-12 ) cout<<ans<<endl;
                else cout<<-1<<endl;
            }else{
//                assert(0);
                cout<<-1<<endl;
            }
        }
    }
}

    #include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

#define pitem item*
#define tam 1023456
#define tamN 12345
using namespace std;
typedef long long ll;

typedef pair<ll,ll> ii;
typedef pair<int,ii> iii;
const ll INF=1e18;
struct item
{
    int prior,cnt;
    ll pos,speed,minn,tot;
    ii pos_viz;
    ii pos_vder;
    pitem l;
    pitem r;
    item(){}
    item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
    {
        prior=rand();
        minn=INF;
        pos_viz=pos_vder=ii(pos,speed);
    }

};
int cnt(pitem t){return t?t->cnt:0;}
ll gtot(pitem t){return t?t->tot:0;}
ll gmin(pitem t){return t?t->minn:INF;}

ll gextraiz(pitem t){
    if (!t|| (!(t->l)))
        return INF;
    else
        return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
}
ll gextrader(pitem t){
    if (!t|| !(t->r))
        return INF;
    return  (t->r->pos_viz.f-t->pos)*(t->speed);
}
void upd_cnt(pitem t)
{
    if (t)
    {
        t->cnt=cnt(t->l)+cnt(t->r)+1;
        ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
        t->tot=totiz;
        t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
        if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
        if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
        t->tot+=gtot(t->r);
        t->minn=gmin(t->l);
        t->minn=min(t->minn,totiz+extraiz);
        t->minn=min(t->minn,totiz+extraiz+extrader);
        t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
        if (t->tot!=0)
        t->minn=min(t->minn,t->tot);
    }
}
void split(pitem t,pitem &l,pitem &r,int key)
{
    if (!t)
        return void(l=r=0);
    if (t->pos>key)
        split(t->l,l,t->l,key),r=t;
    else
        split(t->r,t->r,r,key),l=t;
    upd_cnt(t);
}
void merge(pitem &t,pitem l,pitem r)
{
    if (!l||!r)
        t=l?l:r;
    else if (r->prior>l->prior)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd_cnt(t);
}
ll auxresp;
double respf;ll iz,der;
pitem ant_t;
bool print=false;
void query(pitem t,ll inival)
{

    if (t==0)
    {
        if (!ant_t)
            return void(auxresp=-1);

        // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
        ll extra;
        extra=(der-ant_t->pos)*(ant_t->speed);
        if (inival+extra<=0)
        {
            auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
            if ((inival)/(ant_t->speed)>0)
                cout<<"watultimo\n";
            if (print==1)
                cout<<" aca: ";
            respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
            return;
        }
        else
            return void(auxresp=-1);
    }
    ant_t=t;
    ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
    if (gmin(t->l)+inival<=0)
    {
        query(t->l,inival);
        // cout<<"go left\n";
    }
    else
    {
        ll extraiz,extrader,totiz;
        extraiz=(t->l)?gextraiz(t):0;
        extrader=(t->r)?gextrader(t):0;
        totiz=gtot(t->l);
        ll auxini=totiz+extraiz+extrader;
        // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
        if (totiz+extraiz+inival<=0)
        {
            inival+=totiz;
            auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
            if ((inival)/(t->l->pos_vder.s)>0)
                cout<<"watizquierda\n";
            respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
        }
        else if (totiz+extraiz+extrader+inival<=0)
        {
            inival+=totiz+extraiz;
            auxresp=(t->pos)-(inival)/(t->speed);//-.-
            if (inival/t->speed>0)
                cout<<"watderecha\n";
            respf=-(double)(inival%t->speed)/(t->speed);//-.-

        }
        else
            {

                // cout<<"go right\n";
                query(t->r,auxini+inival);
            }

    }
}

int main()
{
    int casos;
    scanf("%d",&casos);
    if (casos>5000)
        print=1;

    int tipo;
    pitem t1;pitem t2;pitem t3;
    pitem s;
    pitem tree=new item(2e9,1);
    ll val,pos;
    double auxrespf;
    while(casos--)
    {
        scanf("%d",&tipo);
        if (tipo==1)
        {
            scanf("%lld %lld",&pos,&val);
            if (val==0)
            {
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
                continue;
            }
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            s=new item(pos,val);
            merge(tree,t1,s);
            merge(tree,tree,t3);
        }
        else if (tipo==2)
        {
            scanf("%lld",&pos);
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            merge(tree,t1,t3);
        }
        else if (tipo==3)
        {
            scanf("%lld %lld %lld",&iz,&der,&val);
            if (val==0)
            {
                printf("%lld.0\n",iz);
                continue;
            }
            split(tree,t1,t3,der);
            split(t1,t1,t2,iz-1);
            ant_t=NULL;
            query(t2,val);
            if (auxresp==-1)
                printf("-1\n");
            else
            {
                auxrespf=auxresp+respf;
                printf("%.9lf\n",auxrespf);
            }
            merge(tree,t1,t2);
            merge(tree,tree,t3);
        }
     //   inorder(tree);
        //// cout<<endl;
    }
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(time(NULL));
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void ispis(pnode x){

    if(x==NULL)return;
    push(x);

    ispis(x->l);
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void upd(pnode x){
    if(x==NULL)return;
    ////x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
    x->mn=x->val;
    if(x->l!=NULL)x->mn=x->l->val<x->mn?x->l->val:x->mn;
    ///pnode pr=x->r;
    if(x->r!=NULL)x->mn=
        x->r->val<x->mn?
        x->r->val:x->mn;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_mn(x->l)<=val){
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*printf("\n\nISPIS\n");
        ispis(midtree);
        printf("\n");*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
        ///printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            ///printf("%d TMTM\n",tm);
            if(tm==0 || pom1==NULL)printf("AAAJEBOTE\n");

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    int sq=q;
    int cnt=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<" "<<s<<endl;}
            else ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<endl;}
            else del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(sq==101){
                if(cnt>80)cout<<tip<<" "<<l<<" "<<r<<" "<<v<<endl;
                continue;
            }
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            cout<<query(l,r,v)<<endl;
            ///printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include "bits/stdc++.h"
using namespace std;

#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define pb push_back
#define eb emplace_back
#define ins insert
#define f first
#define s second
#define cbr cerr << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ll(x.size())
#define all(x) (x).begin(), (x).end()
#define lbd(x,y) (lower_bound(all(x),y)-x.begin())
#define ubd(x,y) (upper_bound(all(x),y)-x.begin())
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
inline long long rand(long long x, long long y) { return (rng() % (y+1-x)) + x; } //inclusivesss
string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?llabs(b):gcd(b%a,a); }

typedef long long ll;
typedef long double ld;
#define FOR(i,s,e) for(ll i=s;i<=ll(e);++i)
#define DEC(i,s,e) for(ll i=s;i>=ll(e);--i)
typedef pair<ll,ll>pi; typedef pair<ll,pi>spi; typedef pair<pi,pi>dpi;

#define LLINF ((long long)1e18)
#define INF int(1e9+1e6)
#define MAXN (300006)
const ll sqn = 500;
const ll other = MAXN / sqn * 3;
ll q;
struct node {
	int s,e,m;
	ll v,place;
	node*l,*r;
	node(int S,int E){
		s=S,e=E,m=(s+e)>>1;
		v=0;
		l=r=0;
	}
	void update(int x,bool b,ll num){
		if(s==e) {
			v=b;
			place=num;
			return;
		}
		if(x>m) {
			if(!r) r=new node(m+1,e);
			r->update(x,b,num);
		}else{
			if(!l) l=new node(s,m);
			l->update(x,b,num);
		}
		v=(l?l->v:0)+(r?r->v:0);
	}
	ll rmq(int x,int y){
		if(s==x&&e==y) return v;
		if(x>m)return r?r->rmq(x,y):0;
		else if(y<=m) return l?l->rmq(x,y):0;
		else return (l?l->rmq(x,m):0)+(r?r->rmq(m+1,y):0);
	}
	ll pos(int x){
		if(s==e) return place;
		if(x>m) return r->pos(x);
		else return l->pos(x);
	}
}*seg;
bool stop;
pi C=pi(-1,-1);
struct bkt {
	ll mi=0,ind,end=1e9,total=0;
	vector<pi> v;
	void insert(pi x){
		vector<pi> tmp;
		while(v.size() && v.back() > x) tmp.pb(v.back()), v.pop_back();
		tmp.eb(x);
		while(tmp.size()) v.eb(tmp.back()), tmp.pop_back();
		if(ind) C=pi(ind-1, v[0].f);
		recalc();
	}
	void re(ll x){
		assert(v[lbd(v,pi(x,-LLINF))].f==x);
		v.erase(v.begin()+lbd(v,pi(x,-LLINF)));
		if(ind && siz(v)) {
			C=pi(ind-1, v[0].f);
		}else if(ind){
			// FOR(i,ind+1,other-1) if(this[i].v.size()) {
				// this[ind-1].end = this[i].v[0].f;
				// this[ind-1].recalc();
				// break;
			// }
			C=pi(ind-1, -1);
		}
		recalc();
	}
	void recalc(){
		if(stop)return;
		total = 0, mi = 0;
		FOR(i,0,siz(v)-1){
			total += ((i==siz(v)-1 ? end : v[i+1].f) - v[i].f) * v[i].s;
			mi=max(mi,-total);
		}
	}
	ld query(ll l,ll r,ll x){
		auto bound=[&](ll x){
			return min(max(l, x), r+1);
		};
		FOR(i,0,siz(v)-1){
			if(x + (bound(i==siz(v)-1 ? end : v[i+1].f) - bound(v[i].f)) * v[i].s > 0) {
				x += (bound(i==siz(v)-1 ? end : v[i+1].f) - bound(v[i].f)) * v[i].s;
			} else {
				assert(v[i].s < 0);
				return bound(v[i].f) + ld(x) / ld(-v[i].s);
			}
		}
		assert(0);
	}
	pi from(ll l,ll r){
		if(v[0].f >= l && v.back().f <= r) return pi(total,mi);
		if(v.back().f < l) assert(0);
		ll used = 0, mx = 0;
		auto bound=[&](ll x){
			return min(max(l, x), r+1);
		};
		FOR(i,0,siz(v)-1){
			used += (bound(i==siz(v)-1 ? end : v[i+1].f) - bound(v[i].f)) * v[i].s;
			mx = max(mx, - used);
		}
		return pi(used,mx);
	}
} bk[other];
void push(){
	if(C.f==-1) return;
	if(C.s==-1){
		FOR(i,C.f+1,other-1)if(bk[i].v.size()){
			bk[C.f].end=bk[i].v[0].f;
			bk[C.f].recalc();
			break;
		}
	}else{
		bk[C.f].end=C.s;
		bk[C.f].recalc();
	}
}
void rebuild(){
	vector<pi> everyone;
	FOR(i,0,other-1) { for(auto j:bk[i].v) everyone.eb(j); bk[i].v.clear(), bk[i].mi=0, bk[i].total=0, bk[i].end=1e9; }
	stop=1;
	FOR(i,0,siz(everyone)-1){
		bk[i/sqn].insert(everyone[i]);
		push();
		seg->update(everyone[i].f, 1, i/sqn);
	}
	stop=0;
	FOR(i,0,(siz(everyone)-1)/sqn) bk[i].recalc();
}
int main(){
	cout<<setprecision(12)<<fixed;
	cerr<<setprecision(12)<<fixed;
	FAST
	seg=new node(0, 1e9);
	FOR(i,0,other-1) bk[i].ind=i;
	cin>>q;
	while(q--){
		ll op; cin>>op;
		if(op==1){
			ll t, s; cin>>t>>s;
			ll indy = seg->rmq(0, t);
			seg->update(t, 1, indy/sqn);
			bk[indy/sqn].insert(pi(t,s));
			push();
			if(bk[indy/sqn].v.size() >= 2 * sqn) {
				rebuild();
			}
		}else if(op==2){
			ll t; cin>>t;
			bk[seg->pos(t)/sqn].re(t);
			seg->update(t,0,other+1000);
			push();
		}else {
			ll l,r,v;cin>>l>>r>>v;
			if(v==0){
				cout<<l<<'\n';
				continue;
			}
			bool done=0,f=0;
			ll last=0;
			FOR(i,0,other-1) if(bk[i].v.size()) {
				if(bk[i].v[0].f > r){
					break;
				}
				if(bk[i].v.back().f < l) { last=bk[i].v.back().s; continue; }
				if(f==0){
					f=1;
					if(bk[i].v[0].f > l) {
						if(v+(bk[i].v[0].f-l)*last > 0) v += (bk[i].v[0].f - l) * last;
						else {assert(last<0);
							ld tmp = ld(v) / ld(-last) + l;
							if(tmp<=r) cout<<tmp<<'\n';
							else cout<<"-1\n";
							done=1;
							break;
						}
					}
				}
				if(bk[i].from(l,r).s >= v){
					ld tmp=bk[i].query(l,r,v);
					if(tmp <= r) cout<<tmp<<'\n';
					else cout<<"-1\n";
					done=1;
					break;
				}
				v += bk[i].from(l,r).f;
				assert(v>0);
			}
			if(done) continue;
			if(f==0){
				f=1;
				if(v+(r-l)*last > 0) v += (r - l) * last;
				else {assert(last<0);
					ld tmp = ld(v) / ld(-last) + l;
					if(tmp<=r) cout<<tmp<<'\n';
					else cout<<"-1\n";
					done=1;
					continue;
				}
			}
			cout<<"-1\n";
		}
	}
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define y0 y0998244353
#define y1 y1998244353
#define die(cond) if (cond) for (;;) {}
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acosl(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

signed main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

struct vertex {
	ll time, speed;
	ll tl, tr, speedR;
	ll res = 0, minn = 0;
	ll l = -1, r = -1;
	ll prior = rand();
};
struct treap {
	vector<vertex> t;
	treap() {}
	void upd(ll v) {
		if (v == -1) {
			return;
		}
		ll& time = t[v].time;
		ll& speed = t[v].speed;
		ll& res = t[v].res;
		ll& minn = t[v].minn;
		ll l = t[v].l, r = t[v].r;
		res = 0, minn = 0;
		if (l != -1) {
			mineq(minn, t[l].minn);
			res += t[l].res;
			res += t[l].speedR * (time - t[l].tr);
			mineq(minn, res);
			t[v].tl = t[l].tl;
		} else {
			t[v].tl = time;
		}
		if (r != -1) {
			res += speed * (t[r].tl - time);
			mineq(minn, res + t[r].minn);
			res += t[r].res;
			mineq(minn, res);
			t[v].tr = t[r].tr;
			t[v].speedR = t[r].speedR;
		} else {
			t[v].tr = time;
			t[v].speedR = speed;
		}
	}
	ll newv(ll t_, ll s_) {
		vertex v;
		v.time = t_, v.speed = s_;
		t.pb(v);
		upd(sz(t) - 1);
		return sz(t) - 1;
	}
	pll split(ll v, ll k) {
		if (v == -1) {
			return { -1, -1 };
		}
		pll p;
		if (t[v].time < k) {
			p = split(t[v].r, k);
			t[v].r = p.ft;
			p.ft = v;
		} else {
			p = split(t[v].l, k);
			t[v].l = p.sd;
			p.sd = v;
		}
		upd(v);
		return p;
	}
	ll merge(ll f, ll s) {
		if (f == -1) {
			return s;
		}
		if (s == -1) {
			return f;
		}
		if (t[f].prior > t[s].prior) {
			t[f].r = merge(t[f].r, s);
			upd(f);
			return f;
		} else {
			t[s].l = merge(f, t[s].l);
			upd(s);
			return s;
		}
	}
	ll add(ll root, ll t_, ll s) {
		ll a, b;
		tie(a, b) = split(root, t_);
		ll v = newv(t_, s);
		root = merge(merge(a, v), b);
		return root;
	}
	ll del(ll root, ll t_) {
		ll a, b, c;
		tie(a, b) = split(root, t_);
		tie(b, c) = split(b, t_ + 1);
		root = merge(a, c);
		return root;
	}
	ld down(ll v, ll V, ll R, ll f = 0) {
		if (v == -1) {
			return -1;
		}
		if (V + t[v].minn <= 0) {
			ll v1 = down(t[v].l, V, t[v].time);
			if (v1 != -1) {
				return v1;
			}
			if (t[v].l != -1) {
				V += t[t[v].l].res + t[t[v].l].speedR * (t[v].time - t[t[v].l].tr);
			}
			if (t[v].r != -1) {
				ll nV = V + t[v].speed * (t[t[v].r].tl - t[v].time);
				if (nV <= 0) {
					ld ans = t[v].time - ld(V) / ld(t[v].speed);
					return ans;
				}
				V = nV;
			}
			ll v2 = down(t[v].r, V, R);
			if (v2 != -1) {
				return v2;
			}
		} else {
			V += t[v].res;
		}
		if (R > t[v].tr) {
			ll nV = V + t[v].speedR * (R - t[v].tr);
			if (nV <= 0) {
				ld ans = t[v].tr - ld(V) / ld(t[v].speedR);
				return ans;
			}
			V = nV;
		}
		return -1;
	}
	ld getans(ll root, ll l, ll r, ll v) {
		if (v == 0) {
			return l;
		}
		ll a, b, c;
		tie(a, b) = split(root, l);
		tie(b, c) = split(b, r + 1);
		ld ans = down(b, v, r, 1);
		root = merge(merge(a, b), c);
		return ans;
	}
};

ll q;
treap tr;

inline void solve() {
	cout << setprecision(7) << fixed;
	ll root = -1;
	for (ll i = 0; i < q; i++) {
		ll t;
		cin >> t;
		if (t == 1) {
			ll time, s;
			cin >> time >> s;
			root = tr.add(root, time, s);
		} else if (t == 2) {
			ll time;
			cin >> time;
			root = tr.del(root, time);
		} else if (t == 3) {
			ll l, r, v;
			cin >> l >> r >> v;
			ld ans = tr.getans(root, l, r, v);
			cout << ans << endl;
		}
	}
}

inline void read() {
	cin >> q;
}

#include <bits/stdc++.h>
#include <chrono>
#define INF 1000 * 1000 * 1000
#define LINF INF * (LL)INF
#define LL long long
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
LL l , r , v;
struct node
{
	int L , R;
	int y;
	LL time , speed , tL , tR , speedR , res , mn;
	node()
	{
		L = -1 , R = -1;
		speed = 0;
		y = rng();
	}
}
t[100005];
int nodeCnt;
int getNode()
{
	return nodeCnt++;
}
int update(int v)
{
	if(v == -1)
		return v;
	t[v].tL = t[v].tR = t[v].time;
	t[v].speedR = t[v].speed;

	LL Mn = 0 , Res = 0;
	if(t[v].L != -1)
	{
		t[v].tL = t[t[v].L].tL;
		Mn = min(Mn , t[t[v].L].mn);
		Mn = min(Mn , t[t[v].L].res + (t[v].time - t[t[v].L].tR) * (LL) t[t[v].L].speedR);
		Res = t[t[v].L].res + (t[v].time - t[t[v].L].tR) * (LL) t[t[v].L].speedR;
	}
	if(t[v].R != -1)
	{
		Mn = min(Mn , Res + (t[t[v].R].tL - t[v].time) * (LL)t[v].speed + t[t[v].R].mn);
		Res += (t[t[v].R].tL - t[v].time) * t[v].speed;
		Res += t[t[v].R].res;
		t[v].speedR = t[t[v].R].speedR;
		t[v].tR = t[t[v].R].tR;
	}
	t[v].mn = Mn;
	t[v].res = Res;

	return v;
}
void split(int v , int T , int &L , int &R)
{
	if(v == -1)
	{
		L = -1 , R = -1;
		return;
	}
	if(t[v].time >= T)
	{
		split(t[v].L , T , L , t[v].L);
		R = update(v);
	}
	else
	{
		split(t[v].R , T , t[v].R , R);
		L = update(v);
	}
}
int merge(int L , int R)
{
	if(L == -1)
		return R;
	if(R == -1)
		return L;
	if(t[L].y > t[R].y)
	{
		t[L].R = merge(t[L].R , R);
		return update(L);
	}
	else
	{
		t[R].L = merge(L , t[R].L);
		return update(R);
	}
}
double getAns(int noda)
{
	if(v == 0)
		return l;
	//////debug(noda);
	if(noda == -1)
	{
		return -1;
	}
	if(t[noda].mn <= -v)
	{
		if(t[noda].L != -1 && t[t[noda].L].mn <= -v)
		{
			return getAns(t[noda].L);
		}
		LL Res = t[noda].L == -1 ? 0 : t[t[noda].L].res;

		if(t[noda].L != -1)
		{
			if(Res + (t[noda].time - t[t[noda].L].tR) * t[t[noda].L].speedR <= -v)
			{
				v += Res;
				//debug("Tut1");
				return t[t[noda].L].tR + (v * 1.0) / abs(t[t[noda].L].speedR);
			}
			Res += (t[noda].time - t[t[noda].L].tR) * t[t[noda].L].speedR;
		}
		if(t[noda].R != -1)
		{
			////debug(t[t[noda].R].tL);
			////debug(t[noda].speed);
			////debug(Res + (t[t[noda].R].tL - t[noda].time) * t[noda].speed);
			if(Res + (t[t[noda].R].tL - t[noda].time) * t[noda].speed <= -v)
			{
				v += Res;
				//debug("Tut2");
				return t[noda].time + (v * 1.0) / abs(t[noda].speed);
			}
			Res += (t[t[noda].R].tL - t[noda].time) * t[noda].speed;
			v += Res;
			return getAns(t[noda].R);
		}
		assert(false);
	}
	else
	{
		LL val = t[noda].res + (r - t[noda].tR) * (LL)t[noda].speedR;
		//////debug(val);
		if(val <= -v)
		{
				//debug("Tut3");
				//debug(t[noda].tR);
				//debug(t[noda].res);
				//debug(t[noda].speedR);

				v += t[noda].res;
				//debug(v);
				return t[noda].tR + ((v * 1.0) / abs(t[noda].speedR));
		}
		return -1;
	}
}
int main()
{
	ios_base::sync_with_stdio(0);
	int q;
	cin >> q;
	int root = -1;
	while(q--)
	{
		//debug(root);
		int type;
		cin >> type;
		if(type == 1)
		{
			int T , s;
			cin >> T >> s;
			int newNode = getNode();
			//////debug(newNode);
			t[newNode].time = T;
			t[newNode].speed = s;
			update(newNode);
			int L , R;
			split(root , T , L , R);
			root = merge(L , newNode);
			root = merge(root , R);
			//////debug(t[root].speedR);
		}
		else if(type == 2)
		{
			int t;
			cin >> t;
			int L , R;
			split(root , t , L , R);
			int L1 , R1;
			split(R , t + 1 , L1 , R1);
			root = merge(L , R1);
		}
		else
		{
			cin >> l >> r >> v;
			int L , M , M1 , R;
			split(root , l - 1 , L , M);
			//////debug(t[M].speedR);
			//////debug(t[M].tL);
			//////debug(t[M].tR);
			split(M , r + 1 , M1 , R);
			////debug(t[M1].speedR);
			////debug(t[M1].tL);
			////debug(t[M1].tR);
			////debug(t[M1].res);
			////debug(t[M1].mn);
			//cout << "Answer!!!" << endl;
			cout << fixed << setprecision(10) << getAns(M1) << '\n';
			root = merge(L , M1);
			root = merge(root , R);
		}
	}
}

#include<bits/stdc++.h>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
using namespace std;
inline char nc(){ static char buf[100000] , *p1,*p2; return p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,100000,stdin),p1 == p2) ? EOF : *p1++;}
template<class T>inline void rd(T & x){ int f = 1;x = 0;char ch = nc();for(;!isdigit(ch);ch = nc()) if(ch == '-') f = -1; for(;isdigit(ch);ch = nc()) x = x * 10 + ch - '0';x *= f;}

const int maxn = 1e5 + 10;

struct op{
	int type;
	int t,l,r,v,s;
} querys[maxn];

int times[maxn],n;
inline int upper(double time){
	int l = 1,r = n,ans = n + 1;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] >= time){
			ans = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	return ans;
}
inline int lower(double time){
	int l = 1,r = n,ans = 0;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] <= time){
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return ans;
}

int mark[maxn];
namespace Fenwick{
	int tr[maxn];
	inline void update(int x,int v){ for(;x < maxn;x += x & (-x)) tr[x] += v;}
	inline int query(int x){ int ans = 0; for(;x;x ^= x & (-x)) ans += tr[x]; return ans;}
	inline int val(int x) { return query(x) - query(x - 1);}
	inline int bs(int x){ // min query(ans) >= x
		int l = 0,r = n,ans = 0;
		while(l <= r){
			int mid = l + r >> 1;
			if(query(mid) >= x) {
				ans = mid;
				r = mid - 1;
			} else {
				l = mid + 1;
			}
		}
		return ans;
	}
	inline int pre(int x){
		int d = query(x - 1);
		return bs(d);
	}
	inline int suc(int x){
		return bs(query(x) + 1);
	}
}
double cur[maxn];
const double inf = 2e20;
namespace Segment{
	double tra[maxn << 2],tri[maxn << 2];
	double lazy[maxn << 2];
	int mk[maxn << 2];

	inline void pushup(int rt){
		tra[rt] = max(tra[rt << 1],tra[rt << 1 | 1]);
		tri[rt] = min(tri[rt << 1],tri[rt << 1 | 1]);
	}
	inline void pushdown(int rt){
		if(!mk[rt]) return;
		mk[rt] = 0;
		mk[rt << 1] = 1;
		mk[rt << 1 | 1] = 1;
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		tra[rt << 1] += lazy[rt];
		tri[rt << 1] += lazy[rt];
		tra[rt << 1 | 1] += lazy[rt];
		tri[rt << 1 | 1] += lazy[rt];
		lazy[rt] = 0;
	}
	void _update(double * target,int pos,double v,int l,int r,int rt){
		if(l == r){
			target[rt] = v;
			return;
		}
		pushdown(rt);
		int mid = l + r >> 1;
		if(pos <= mid) _update(target,pos,v,lson);
		else _update(target,pos,v,rson);
		pushup(rt);
	}
	void setVoid(int pos){
		_update(tra,pos,-inf,1,n,1);
		_update(tri,pos,inf,1,n,1);
	}
	void setZero(int pos){
		_update(tra,pos,0,1,n,1);
		_update(tri,pos,0,1,n,1);
	}
	void build(int l,int r,int rt){
		if(l == r){
			tra[rt] = -inf;
			tri[rt] = inf;
			return;
		}
		int mid = l + r >> 1;
		build(lson);
		build(rson);
		pushup(rt);
	}
	void update(int L,int R,double v,int l,int r,int rt){
		if(L <= l && r <= R){
			lazy[rt] += v;
			tra[rt] += v;
			tri[rt] += v;
			mk[rt] = 1;
			return;
		}
		pushdown(rt);
		int mid = l + r >> 1;
		if(L <= mid) update(L,R,v,lson);
		if(R > mid) update(L,R,v,rson);
		pushup(rt);
	}
	double querya(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tra[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = -inf;
		if(L <= mid) ans = max(ans,querya(L,R,lson));
		if(R > mid)ans = max(ans,querya(L,R,rson));
		return ans;
	}
	double queryi(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tri[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = inf;
		if(L <= mid) ans = min(ans,queryi(L,R,lson));
		if(R > mid) ans = min(ans,queryi(L,R,rson));
		return ans;
	}

}
double getV(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return cur[x];
}
double calc(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return (double)(l - times[x]) * cur[x] + Segment::querya(x,x,1,n,1);
}
const double eps = 1e-15;
bool check(double l,double r,double c){
	double qa = -inf,qi = inf;
	if(fabs(l - r) <= eps) return fabs(calc(l) - c) <= eps;
	qa = max(calc(l),qa);
	qi = min(calc(l),qi);
	qa = max(calc(r),qa);
	qi = min(calc(r),qi);
	int lx = upper(l),rx = lower(r);
	if(lx <= rx && lx != 0 && rx != 0){
		qa = max(qa,Segment::querya(lx,rx,1,n,1));
		qi = min(qi,Segment::queryi(lx,rx,1,n,1));
	}
//	printf("%.9f %.9f %.9f %.9f %.9f\n",l,r,qa,qi,c);
	return qa - c >= 0 && qi - c <= 0;
}

int main(){
	int TAT;
	rd(TAT);
	for(int i = 1;i <= TAT;i++){
		int type,t,l,r,v,s;
		rd(type);
		if(type == 1){ // add
			rd(t); rd(v);
			times[++n] = t;
			querys[i].type = 1;
			querys[i].t = t;
			querys[i].v = v;
		} else if(type == 2){
			rd(t);
			querys[i].type = 2;
			querys[i].t = t;
		} else {
			rd(l); rd(r); rd(s);
			querys[i].type = 3;
			querys[i].l = l;
			querys[i].r = r;
			querys[i].s = s;
		}
	}
	sort(times + 1,times + n + 1);
	n = unique(times + 1,times + n + 1) - times - 1;

	if(n!=0)Segment::build(1,n,1);
	for(int i = 1;i <= TAT;i++){
		int type = querys[i].type;
		if(type == 1){
			int t = querys[i].t, v = querys[i].v;
			int pos = upper(t);
			Fenwick::update(pos,1);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			cur[pos] = v;
			assert(pos != n + 1);
			Segment::setZero(pos);
			if(pre){
				double delta = (double)cur[pre] * (times[pos] - times[pre]) + Segment::querya(pre,pre,1,n,1);
				Segment::update(pos,pos,delta,1,n,1);
			}
			if(suc){
				double delta = (double)(v - cur[pre]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
		} else if(type == 2){
			int t = querys[i].t;
			int pos = upper(t);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			Fenwick::update(pos,-1);
			if(suc){
				double delta = (double)(cur[pre] - cur[pos]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
			Segment::setVoid(pos);
			cur[pos] = 0;
		} else {
			double l = querys[i].l , r = querys[i].r , s = -querys[i].s;
			int lx = upper(l);
			if(Fenwick::val(lx) == 0) lx = Fenwick::suc(lx);
			l = times[lx];
			if(s == 0) {
				printf("%d\n",querys[i].l);
				continue;
			}
			if(n == 0 || Fenwick::query(n) == 0 || !lx || l > r) {
				printf("-1\n");
				continue;
			}
			s += Segment::querya(lx,lx,1,n,1);

			bool ok = 0,done = 0;
			l -= eps * 2;
			r += eps * 2;
			for(int k = 0;k < 50;k++){
				double mid = (l + r) / 2;
				if(check(l,mid,s)){
					int t1 = lower(l),t2 = lower(mid);
					if(t1 == t2 && t1){
						done = 1;
						double tt = times[t1];
						printf("%.9f\n",tt + (double)(s - calc(tt)) /  getV(tt));
						break;
					}
					r = mid;
					ok = 1;
				} else {
					l = mid;
				}
			}
			if(done) continue;
			if(fabs(calc(l) - s) <= eps) ok = 1;
			if(ok)printf("%.9f\n",r);
			else printf("-1\n");
		}
	}
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <random>
#include <climits>
#include <iomanip>
#include <queue>
#include <bitset>
#include <cctype>

using namespace std;

#define forn(i,n) for (int i = 0;i < int(n);i++)
#define ford(i,n) for (int i = n-1;i >=0;i--)
#define fore(i,l,r) for (int i = int(l);i < int(r);i++)
#define forv(a) for(int i = 0;i < (a).size();i++) cin >> a[i]
#define correct(x,n) (((x) >= 0) && ((x) < n))
#define sort_all(a) sort((a).begin(),(a).end())
#define mp(a,b) make_pair((a),(b))
#define all(a) (a).begin(),(a).end()
#define pb(a) push_back(a)
#define rnd() (rand() + (RAND_MAX+1)*rand())
#define fi first
#define se second
#define V(A) vector<A>
//#define DEBUG_

//#define x first
//#define y second

typedef long long li;
typedef vector<int> vi;
typedef vector<li> vli;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<vi> vvi;
typedef vector<vli> vvli;
typedef long double ld;
typedef pair<li, li> Point;

const ld EPS = 1e-9;

class Node
{
public:
	li key,pr,s;
	li mn, mx, smx,d,dmn;//Min t,max t, s of max t,d,and minimum of d in subtree
	Node* l, *r;
	Node() {}

	Node(li key, li s) : key(key), s(s), mn(key), pr(rnd()), mx(key), smx(s),d(0),dmn(0),l(nullptr),r(nullptr) {}
};

typedef Node* DTree;

li getMin(DTree t)
{
	if (!t)
		return 1500000000;
	return t->mn;
}

li getMax(DTree t)
{
	if (!t)
		return 0;
	return t->mx;
}

li getSMax(DTree t)
{
	if (!t)
		return 0;
	return t->smx;
}

li getD(DTree t)
{
	if (!t)
		return 0;
	return t->d;
}

li getDMin(DTree t)
{
	if (!t)
		return 0;
	return t->dmn;
}

void update(DTree t)
{
	if (!t)
		return;

	t->mn = min(t->key, getMin(t->l));
	t->mx = max(t->key, getMax(t->r));

	if (t->key > getMax(t->r))
		t->smx = t->s;
	else
		t->smx = getSMax(t->r);

	li d = 0, dmn = 0;
	dmn = min(dmn, getDMin(t->l));
	d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	dmn = min(dmn, d);
	d += (t->r ? t->s*(getMin(t->r) - t->key) : 0);
	dmn = min(dmn, d + getDMin(t->r));
	d += getD(t->r);
	dmn = min(dmn, d);
	t->d = d;
	t->dmn = dmn;
}

void split(DTree t, DTree &l, DTree &r,li key)
{
	if (!t)
	{
		l = r = nullptr;
		return;
	}
	if (key < t->key)
		split(t->l, l, t->l, key), r = t;
	else
		split(t->r, t->r, r, key), l = t;
	update(t);
}

void merge(DTree &t, DTree l, DTree r)
{
	if (!l || !r)
	{
		t = (l ? l : r);
		return;
	}
	if (l->pr > r->pr)
		merge(l->r, l->r, r), t = l;
	else
		merge(r->l, l, r->l), t = r;
	update(t);
}

void insert(DTree &t,li key,li s)
{
	DTree tl, tm = new Node(key, s), tr;
	split(t, tl, tr, key);
	merge(t, tl, tm);
	merge(t, t, tr);
}

void erase(DTree &t, li key)
{
	DTree tl, tm, tr;
	split(t, tl, tm, key-1);
	split(tm, tm, tr, key);
	merge(t, tl, tr);
}

double getAns(DTree t,li r,li v)
{
	if (!t)
		return -1;

	if (t->dmn + v > 0)
		return (t->smx >= 0 || t->mx * t->smx - (t->d + v) < r * t->smx ? -1 : t->mx - (double)(t->d + v) / t->smx);

	li dl = getDMin(t->l);
	li d = getD(t->l) + getSMax(t->l)*(t->key - getMax(t->l));
	li dr = d + (t->r ? t->s*(getMin(t->r) - t->key) + getD(t->r) : 0);

	if (dl + v <= 0)
		return getAns(t->l, r, v);

	if (d + v <= 0)
		return getMax(t->l) - (double)(v + dl) / getSMax(t->l);

	if (dr + v <= 0)
		return t->key - (double)(v + d) / t->s;

	return getAns(t->r, r, v - dr);
}

double getAns(DTree t, li l, li r, li v)
{
	if (!v)
		return l;
	DTree tl, tm,tr;
	split(t, tl, tm, l - 1);
	split(tm, tm, tr, r);
	double ans = getAns(tm, r, v);
	merge(t, tl, tm);
	merge(t, t, tr);
	return ans;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	DTree t = nullptr;

	int n;
	cin >> n;
	forn(i, n)
	{
		int q;
		cin >> q;
		if (q == 1)
		{
			li key, s;
			cin >> key >> s;
			insert(t, key, s);
		}
		if (q == 2)
		{
			li key;
			cin >> key;
			erase(t, key);
		}
		if (q == 3)
		{
			li l, r, v;
			cin >> l >> r >> v;
			cout << setprecision(20) << getAns(t, l, r, v) << '\n';
		}
	}
}

#include <bits/stdc++.h>

using namespace std;

const int N = 200010;
const int K = sqrt(N) + 1;
const int INF = (int)1e9 + 10;
const long long INF_LL = (long long)2e18;

int q, k;
vector<int> a[N];
vector<int> moment;
int val[N];

struct Bucket {
    int cnt, firstApp, lastS;
    long long minVal, delta;

    Bucket(int cnt = 0, int firstApp = -1, int lastS = -INF, long long minVal = 0, long long delta = 0) :
        cnt(cnt), firstApp(firstApp), lastS(lastS), minVal(minVal), delta(delta) {}

    void reset() {
        cnt = 0;
        firstApp = -1;
        lastS = -INF;
        minVal = 0;
        delta = 0;
    }

    void debug() {
        cerr << cnt << ' ' << firstApp << ' ' << lastS << ' ' << minVal << ' ' << delta << endl;
    }
} b[N / K + 10];

void init() {
    sort(moment.begin(), moment.end());
    moment.resize(unique(moment.begin(), moment.end()) - moment.begin());
    for (int i = 0; i < moment.size(); i++) val[i] = INF;
}

void updateBucket(int pos) {
    int u = pos / k;
    b[u].reset();
    int curS = 0;
    for (int i = k * u; i < min(k * (u + 1), (int)moment.size() - 1); i++) {
        if (val[i] == INF) {
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        } else {
            b[u].cnt++;
            if (b[u].firstApp == -1) b[u].firstApp = i;
            curS = val[i];
            b[u].delta += 1ll * curS * (moment[i + 1] - moment[i]);
        }
        b[u].minVal = min(b[u].minVal, b[u].delta);
    }
    b[u].lastS = curS;
}

bool go(long long &v, int &curS, int l, int r, long double &res) {
    for (int i = l; i < r; i++) {
        if (val[i] != INF) curS = val[i];
        if (v + 1ll * curS * (moment[i + 1] - moment[i]) <= 0ll) {
            res = -(long double)v / curS + moment[i];
            return 1;
        }
        v += 1ll * curS * (moment[i + 1] - moment[i]);
    }
    return 0;
}

long double getRes(int l, int r, long long v) {
    l = lower_bound(moment.begin(), moment.end(), l) - moment.begin();
    r = lower_bound(moment.begin(), moment.end(), r) - moment.begin();
    if (v == 0) return moment[l];
    if (moment.size() == 1) {
        return -1;
    }
    r--;
    int ll = l / k;
    int rr = r / k;
    if (ll == rr) {
        int curS = 0;
        long double res = -1;
        if (go(v, curS, l, r + 1, res)) return res;
        else return -1;
    }
    int curS = 0;
    long double res = -1;
    if (go(v, curS, l, min(k * (ll + 1), (int)moment.size() - 1), res)) return res;
    for (int i = ll + 1; i < rr; i++) {
        if (b[i].cnt == 0) {
            // int fullTime = moment[k * (i + 1)] - moment[k * i];
            // if (v + 1ll * curS * fullTime <= 0) return -(long double)v / curS + moment[k * i];
            // v += 1ll * curS * fullTime;
            continue;
        }
        int foo = moment[b[i].firstApp] - moment[i * k];
        if (v + 1ll * curS * foo <= 0ll) {
            return -(long double)v / curS + moment[i * k];
        }
        v += 1ll * curS * foo;
        if (v + b[i].minVal <= 0) {
            if (go(v, curS, b[i].firstApp, min(k * (i + 1), (int)moment.size() - 1), res)) return res;
        } else {
            v += b[i].delta;
            curS = b[i].lastS;
        }
    }
    if (go(v, curS, k * rr, r + 1, res)) return res;
    return -1;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        int op;
        cin >> op;
        a[i].push_back(op);
        if (op == 1) {
            int t, s;
            cin >> t >> s;
            moment.push_back(t);
            a[i].push_back(t);
            a[i].push_back(s);
        } else if (op == 2) {
            int t;
            cin >> t;
            moment.push_back(t);
            a[i].push_back(t);
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            moment.push_back(l);
            moment.push_back(r);
            a[i].push_back(l);
            a[i].push_back(r);
            a[i].push_back(v);
        }
    }
    init();
    k = sqrt(moment.size()) + 1;

    for (int i = 1; i <= q; i++) {
        if (a[i][0] == 1) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = a[i][2];
            updateBucket(pos);
        } else if (a[i][0] == 2) {
            int pos = lower_bound(moment.begin(), moment.end(), a[i][1]) - moment.begin();
            val[pos] = INF;
            updateBucket(pos);
        } else {
            double ans = getRes(a[i][1], a[i][2], a[i][3]);
            if (ans < 0) cout << -1 << '\n';
            else cout << fixed << setprecision(10) << ans << '\n';
        }
        // cerr << "q " << i << ' ' << endl;
        // for (int i = 0; i < (int)moment.size() / k; i++) {
        //     cerr << "number " <<  i << ' ' ;
        //     b[i].debug();
        // }
    }
    return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef double db;
typedef long double ldb;

typedef long long ll;
typedef pair<ll,int> pr;

int num[300005];
int cnt;

namespace SGT {

ll sumv[1200000],minn[1200000],setv[1200000];

inline void pushdown(int l,int r,int o) {
  if (setv[o]!=-1) {
  	int m=((l+r)>>1);
  	sumv[o*2]=setv[o]*(num[m+1]-num[l]);minn[o*2]=min(0LL,sumv[o*2]);
  	sumv[o*2+1]=setv[o]*(num[r+1]-num[m+1]);minn[o*2+1]=min(0LL,sumv[o*2+1]);
  	setv[o*2]=setv[o*2+1]=setv[o];
  	setv[o]=-1;
  }
}

inline void pushup(int o) {
  sumv[o]=sumv[o*2]+sumv[o*2+1];
  minn[o]=min(minn[o*2],sumv[o*2]+minn[o*2+1]);
}

void update(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) {
  	sumv[o]=p*(num[r+1]-num[l]);minn[o]=min(0LL,sumv[o]);
  	setv[o]=p;
  }
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=lx) update(l,m,o*2,lx,rx,p);
  	if (m<rx) update(m+1,r,o*2+1,lx,rx,p);
  	pushup(o);
  }
}

pr query2(int l,int r,int o,ll p) {
  if (l==r) return pr(p,l);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (p+minn[o*2]<=0) return query2(l,m,o*2,p);
  	else return query2(m+1,r,o*2+1,p+sumv[o*2]);
  }
}

pr query1(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) return (p+minn[o]<=0)?query2(l,r,o,p):pr(p+sumv[o],-1);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query1(l,m,o*2,lx,rx,p);
  	if (m<lx) return query1(m+1,r,o*2+1,lx,rx,p);
  	pr a=query1(l,m,o*2,lx,rx,p);
  	if (a.SE!=-1) return a;
	return query1(m+1,r,o*2+1,lx,rx,a.FR);
  }
}

ll query3(int l,int r,int o,int p) {
  if (l==r) return setv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=p) return query3(l,m,o*2,p);
  	else return query3(m+1,r,o*2+1,p);
  }
}

ll query4(int l,int r,int o,int lx,int rx) {
  if (l>=lx&&r<=rx) return sumv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query4(l,m,o*2,lx,rx);
  	if (m<lx) return query4(m+1,r,o*2+1,lx,rx);
  	return query4(l,m,o*2,lx,rx)+query4(m+1,r,o*2+1,lx,rx);
  }
}

}

struct Ope {
  int l,r,v,kind;
  Ope() {}
  Ope(int a,int b,int c,int d):l(a),r(b),v(c),kind(d) {}
};

Ope a[100005];
set <int> st;

int val[100005];

int main() {
  memset(val,0x3f,sizeof(val));
  int m;
  scanf("%d",&m);
  int n=0;
  for(int i=1;i<=m;i++) {
  	int kind;
  	scanf("%d",&kind);
  	if (kind==1) {
  		int x,y,z;
  		scanf("%d%d",&x,&y);
  		a[i]=Ope(x,x,y,1);
  		num[++n]=x;
	  }
	else if (kind==2) {
		int x;
		scanf("%d",&x);
		a[i]=Ope(x,x,0,2);
		num[++n]=x;
	}
	else {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		a[i]=Ope(x,y,z,3);
		num[++n]=x;num[++n]=y;
	}
  }
  num[++n]=0;num[++n]=1e9+1;
  sort(num+1,num+n+1);
  n=unique(num+1,num+n+1)-num-1;
  st.insert(1);st.insert(n);
  for(int i=1;i<=m;i++)
    if (a[i].kind==1) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	st.insert(t);
    	set<int>::iterator it=st.lower_bound(t);
    	it++;
    	int t2=(*it);
    	SGT::update(1,n,1,t,t2-1,a[i].v);
    	if (m==10000) val[a[i].l]=a[i].v;
    	if (a[i].l==8626) printf("%d %d\n",0,i);
	}
	else if (a[i].kind==2) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	set<int>::iterator it=st.lower_bound(t),it2=it;
    	it--;it2++;
    	int t1=(*it),t2=(*it2);
    	st.erase(t);
    	SGT::update(1,n,1,t,t2-1,SGT::query3(1,n,1,t1));
    	if (m==10000) val[a[i].l]=inf;
    	if (a[i].l==8626) printf("%d %d\n",1,i);
	}
	else {
		cnt++;
		if (!a[i].v) {
			if (m!=10000) printf("%d\n",a[i].l);
			continue;
		}
		int l=lower_bound(num+1,num+n+1,a[i].l)-num,r=lower_bound(num+1,num+n+1,a[i].r)-num-1;
		set<int>::iterator it=st.lower_bound(l);
		l=(*it);
		if (l>r) {
			if (m!=10000) puts("-1");
			continue;
		}
		pr t=SGT::query1(1,n,1,l,r,a[i].v);
		if (t.SE!=-1) {
			db v=SGT::query3(1,n,1,t.SE);
			if (m!=10000) printf("%.8f\n",(db)(num[t.SE]+(ldb)(-t.FR)/v));
		}
		else if (m!=10000) puts("-1");
	}
  return 0;
}

#include <iostream>
#include <queue>
#include <stack>
#include <set>
#include <cstring>
#include <stdio.h>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <iterator>
#include <algorithm>
#include <functional>
#include <map>
#include <cassert>
#include <bitset>
#include <iomanip>

using namespace std;

typedef long long ll;
#define pii pair<ll, ll>
#define mp make_pair

ll read() {
    int f = 1;
    ll res = 0;
    char ch;
    do {
        ch = getchar();
        if (ch == '-') f = -f;
    } while (ch < '0' || ch > '9');
    do {
        res = res * 10 + ch - '0';
        ch = getchar();
    } while (ch >= '0' && ch <= '9');
    return f == 1 ? res : -res;
}

void fast_io() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

const int N = 100010;
const int mod = 1000000007;
const ll INF = 1e18;
int n,m,q;
int A[N], B[N];
char str[N];

int head[N*2], to[N * 2], nxt[N * 2], tot;
void addEdge(int u, int v) {
    tot++;
    nxt[tot] = head[u];
    to[tot] = v;
    head[u] = tot;
}

template <class T>
T mmax(T a, T b) {
    return a < b ? b: a;
}

template <class T>
T mmin(T a, T b) {
    return a < b? a: b;
}

int countOne(int set) {
    int res = 0;
    while (set) {
        res++;
        set &= set - 1;
    }
    return res;
}

bool contain(int set, int i) {
    return (set & (1 << i)) > 0;
}

ll myPow(ll a, int p) {
    if (p == 0) return 1;
    ll res = myPow(a, p / 2);
    res *= res;
    res %= mod;
    if (p % 2 == 1) {
        res *= a;
        res %= mod;
    }
    return res;
}

void addMode(int &a, ll b) {
    a = (a+b) % mod;
}

ll mul(ll a, ll b) {
    return a * b % mod;
}

template <class T>
void mySwap(T &a, T &b) {
    T tmp = a;
    a = b;
    b = tmp;
}

struct Query {
    int time, l, r, type;
    int speed, vol;
};

vector<int> added;
vector<Query> query;

const int M = N * 4;
struct ST {
    pii f[M], e[M];
    ll res[M], mn[M];

    void init() {
        fill(mn, mn+M, INF);
    }
    void build(int x, int nl, int nr) {
        if (nl == nr) {
            mn[x] = INF;
            return;
        }
        int m = (nl + nr) / 2;
        build(x*2, nl, m);
        build(x*2+1, m+1, nr);
        mn[x] = INF;
    }

    void update(int x) {
        if (mn[x*2] == INF) {
            int child = x*2+1;
            f[x] = f[child];
            e[x] = e[child];
            res[x] = res[child];
            mn[x] = mn[child];
            return;
        }
        if (mn[x*2+1] == INF) {
            int child = x*2;
            f[x] = f[child];
            e[x] = e[child];
            res[x] = res[child];
            mn[x] = mn[child];
            return;
        }
        int l = x*2;
        int r = x*2+1;
        f[x] = f[l];
        e[x] = e[r];
        ll diff = e[l].second * (f[r].first - e[l].first);
        res[x] = res[l] + diff + res[r];
        mn[x] = mmin(mn[l], res[l] + diff);
        mn[x] = mmin(mn[x], res[l] + diff + mn[r]);
    }

    void set(int l, int time, int speed, int x, int nl ,int nr) {
        if (nl == nr) {
            f[x] = mp(time, speed);
            e[x] = mp(time, speed);
            res[x] = 0;
            mn[x] = 0;
            return;
        }
        int m = (nl + nr) / 2;
        if (l <= m) set(l, time, speed, x*2, nl, m);
        else set(l, time, speed, x*2+1, m+1, nr);
        update(x);
    }

    void del(int l, int x, int nl , int nr) {
        if (nl == nr) {
            mn[x] = INF;
            return;
        }
        int m = (nl + nr) / 2;
        if (l <= m) del(l, x*2, nl, m);
        else del(l, x*2+1, m+1, nr);
        update(x);
    }

    struct node {
        double to;
        ll v;
    };
    node query(int l, int r, ll v, int ss, int rr, int x, int nl, int nr) {

        if (mn[x] == INF) return {-1, v};
        if (l > r) return {-1, v};
        if (rr <= f[x].first) {
            return {-1, v};
        }
//        if (ss > e[x].first) {
//            return {-1, v};
//        }
//        if (f[x] == e[x]) {
//            ll nv = res[x] + v + (rr - e[x].first) * e[x].second;
//            if (nv > 0) return {-1, nv};
//            else return {e[x].first - (res[x] + v) * 1.0 / e[x].second, 0LL};
//        }
        if (l == nl && r == nr) {
            if (f[x] == e[x]) {
                ll nv = res[x] + v + (rr - e[x].first) * e[x].second;
                if (nv > 0) return {-1, nv};
                else return {e[x].first - (res[x] + v) * 1.0 / e[x].second, 0LL};
            }
            int lchild = x*2;
            int rchild = x*2+1;
            int m = (nl + nr) / 2;
            if (mn[lchild] == INF) return query(l, m, v, ss, rr, x*2, nl, m);
            if (mn[rchild] == INF) return query(m+1, r, v, ss, rr, x*2+1, m+1, nr);

            if (mn[lchild] + v <= 0) return query(l, m, v, ss, f[x*2+1].first, x*2, nl, m);
            ll diff = e[lchild].second * (f[rchild].first - e[lchild].first);
            if (v + res[lchild] + diff <= 0) {
                return {e[lchild].first - (v + res[lchild]) * 1.0 / e[lchild].second, 0};
            }

            if (mn[x] + v > 0) {
                ll nv = res[x] + v + (rr - e[x].first) * e[x].second;
                if (nv <= 0) {
                    return {e[x].first - (v + res[x]) * 1.0 / e[x].second, 0};
                } else {
                    return {-1, nv};
                }
            } else {
                v = v + res[lchild] + diff;
                return query(m+1, r, v, ss, rr, x*2+1, m+1, nr);
            }
        }

        int lchild = x*2;
        int rchild = x*2+1;
        int m = (nl + nr) / 2;
        if (mn[lchild] == INF) return query(l, m, v, ss, rr, x*2, nl, m);
        if (mn[rchild] == INF) return query(m+1, r, v, ss, rr, x*2+1, m+1, nr);
        node res = query(l, mmin(r, m), v, ss, f[x*2+1].first, x*2, nl, m);
        if (res.to != -1) return res;
        return query(mmax(l, m+1), r, res.v, ss, rr, x*2+1, m+1, nr);
    }
}st;

int main() {

    fast_io();
    cout << fixed << setprecision(10);

    cin >> n;
    for (int i = 0; i < n; i++) {
        int tp;
        cin >> tp;
        Query q;
        q.type = tp;
        if (tp == 1) {
            int time, speed;
            cin >> time >> speed;
            q.time = time;
            q.speed = speed;
            added.push_back(time);
        } else if (tp == 2) {
            int time;
            cin >> time;
            q.time = time;
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            q.l = l;
            q.r = r;
            q.vol = v;
        }
        query.push_back(q);
    }
    if (added.size() == 0) added.push_back(0);

    sort(added.begin(), added.end());
    added.erase(unique(added.begin(), added.end()), added.end());

    int m = added.size();
    st.init();
    st.build(1, 1, m);

    for (int i = 0; i < n; i++) {
        Query q = query[i];
        if (q.type == 1) {
            int idx = lower_bound(added.begin(), added.end(), q.time) - added.begin();
            idx++;
            int time = q.time;
            int speed = q.speed;
            st.set(idx, time, speed, 1, 1, m);
        } else if (q.type == 2) {
            int idx = lower_bound(added.begin(), added.end(), q.time) - added.begin();
            idx++;
            st.del(idx, 1, 1, m);
        } else {
            if (q.vol == 0) {
                cout << q.l << '\n';
            } else {
                int l = lower_bound(added.begin(), added.end(), q.l) - added.begin();
                l++;
                int r = lower_bound(added.begin(), added.end(), q.r+1) - added.begin();
                cout << st.query(l, r, q.vol, q.l, q.r, 1, 1, m).to << '\n';
            }
        }
    }
    return 0;
}

#include <sstream>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
#include <cassert>
#include <bitset>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)

#define DEBUG
#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define deputs(str) fprintf(stderr, "%s\n",str)
#else
#define debug(...)
#define deputs(str)
#endif // DEBUG
typedef unsigned long long ULL;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long long LL;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e5+107;
const double pi=acos(-1.0);
const double eps=0.0000000001;
LL gcd(LL a, LL b) {return b?gcd(b,a%b):a;}
template<typename T>inline void pr2(T x,int k=64) {ll i; REP(i,k) debug("%d",(x>>i)&1); putchar(' ');}
template<typename T>inline void add_(T &A,int B,ll MOD=M) {A+=B; (A>=MOD) &&(A-=MOD);}
template<typename T>inline void mul_(T &A,ll B,ll MOD=M) {A=(A*B)%MOD;}
template<typename T>inline void mod_(T &A,ll MOD=M) {A%=MOD; A+=MOD; A%=MOD;}
template<typename T>inline void max_(T &A,T B) {(A<B) &&(A=B);}
template<typename T>inline void min_(T &A,T B) {(A>B) &&(A=B);}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a, T b) {
	T ret=1;
	for (; b; b>>=1ll,a=(LL)a*a%M)
		if (b&1) ret=(LL)ret*a%M;
	return ret;
}
int startTime;
void startTimer() {startTime=clock();}
void printTimer() {debug("/--- Time: %ld milliseconds ---/\n",clock()-startTime);}

struct node{
	int l,r;
	int lpos,rm,value;//rm:maxi
	ll maxused,used;//lpos+(v-used)/value
	node():lpos(0),rm(0),value(0),maxused(0),used(0){l=r=0;};
}T[maxn*50]; int tot;
void merge(node &ret,node A,node B) {//避免l,r被改
	if (!A.lpos) {
		ret.lpos=B.lpos; ret.rm=B.rm;
		ret.value=B.value;
		ret.maxused=B.maxused; ret.used=B.used;
		return;
	} if (!B.lpos) {
		ret.lpos=A.lpos; ret.rm=A.rm;
		ret.value=A.value;
		ret.maxused=A.maxused; ret.used=A.used;
		return;
	} ret.maxused=max(A.maxused,A.used+(ll)(B.rm-A.lpos)*A.value+B.maxused);
	ret.lpos=B.lpos; ret.value=B.value; ret.rm=A.rm;
	ret.used=A.used+(ll)(B.rm-A.lpos)*A.value+B.used;
} int root;
int op,t,s,l,r,v;
void update(int &x,int L,int R) {//starttime
	if (!x) x=++tot;
	if (L==R) {//lpos:start_time(position)
		if (op==1) T[x].lpos=T[x].rm=t,T[x].value=s;
		else T[x].lpos=T[x].rm=0,T[x].value=0;
		return;
	} int mid=(L+R)/2;
	if (t<=mid) update(T[x].l,L,mid);
	else update(T[x].r,mid+1,R);
	merge(T[x],T[T[x].l],T[T[x].r]);
	// printf("update : %d %d   %d %d %lld %lld _l=%d %d; used=%lld\n"
	// 	,L,R,T[x].lpos,T[x].value,T[x].maxused,T[x].used,T[T[x].l].lpos,T[T[x].r].lpos,T[T[x].l].used);
} double ans;
node now;
void query(int x,int L,int R) {//(l,R]时间段内
	if (ans>=0) return;
	if (l<=L&&R<=r) {
		node tmp;
		merge(tmp,now,T[x]);
		if (!x) {
			if (tmp.used+(ll)(R-tmp.lpos)*tmp.value>=v)
				ans=tmp.lpos+1.*(v-tmp.used)/tmp.value;
			return;
		}
		// printf("check: (%d-%d) now=%d %d %lld %lld; chk=%lld: v=%d\n",
		// 	L,R,tmp.lpos,tmp.value,tmp.maxused,tmp.used,tmp.used+(ll)(R-tmp.lpos)*tmp.value,v);
		if (tmp.maxused>=v) {//not
			// if (L==R) puts("no way! L=R");//zero
			if (L==R) {//tmp.maxused=0; must tmp.value>0
				ans=L;
				return;
			} int mid=(L+R)/2;
			query(T[x].l,L,mid);
			query(T[x].r,mid+1,R);
			if (ans>=0) return;
			puts("no way 1");
		} else if (tmp.used+(ll)(R-tmp.lpos)*tmp.value>=v) {
			// printf("query: %d %d: okay\n",L,R);
			if (L==R) {//tmp.maxused=0; must tmp.value>0
				ans=tmp.lpos+1.*(v-tmp.used)/tmp.value;
				return;
			} int mid=(L+R)/2;
			query(T[x].l,L,mid);
			query(T[x].r,mid+1,R);
			if (ans>=0) return;
			puts("no way 2");
		} else {
			now=tmp; return;
		}
	} int mid=(L+R)/2;
	if (l<=mid) query(T[x].l,L,mid);
	if (mid<r) query(T[x].r,mid+1,R);
}
int main() {
	int q,i;
	scanf("%d",&q);
	FOR(i,1,q){
		scanf("%d",&op);
		if (op==1) {
			scanf("%d%d",&t,&s); s=-s;
			update(root,1,1000000000);
		} else if (op==2) {
			scanf("%d",&t);
			update(root,1,1000000000);
		} else {
			scanf("%d%d%d",&l,&r,&v);
			ans=-1; now=node();
			query(root,1,1000000000);
			// printf("query %d %d %lld %lld\n",now.lpos,now.value,now.maxused,now.used);
			printf("%.10f\n",ans);
		}
		// now=T[1];
		// printf("_i: %d %d %lld %lld\n",now.lpos,now.value,now.maxused,now.used);
	}

}
/*
10
1 1 1000000000
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 500 1000000000
1 322 1000000000
1 500000000 -1000000000
3 1 1000000000 1
3 1 1000000000 1000000000
3 100 1000000000 1
*/

//时间节点离散化，用线段树维护时间区间上的二次函数，最终线段树上应当存了一些互不相交的函数区间。
//修改操作：modify 更改一段区间上的二次函数，如果破坏了原有的函数区间，需要将原有的函数pushdown
//修改操作：cover 直接重置一段区间上的二次函数，不管有没有原有的函数
//查询操作：query 应当先查询左子树，再查询右子树。一旦有了答案就停止查询。对于每个线段树区间维护增量的min和sum，查询完左子树之后要加上sum。如果min值带入计算仍大于等于0则提前返回。如果当前到达的区间是一个整块的函数区间，无论是否完全被查询区间包含，都只在当前区间查询并且停止递归

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int maxt=(1<<18)+10;
int n;
ll datk[maxt],datb[maxt],sum[maxt],mn[maxt];
int id[maxt];
int read_tl[maxn],read_tr[maxn],read_tval[maxn],cal_tl[maxn],cal_tr[maxn],tp[maxn],covr[maxn];
vector<int> lsh;
map<int,int> ttoi;
set<int> st;
set<int>::iterator it;
int pred,curd;
double ans;
ll preval;
void modify(int x,int l,int r,int tl,int tr,ll k,ll b,int ii)
{
	if(l>tr||r<tl)return;
	if(tl<=l&&r<=tr){id[x]=ii;datk[x]=k;datb[x]=b;sum[x]=k*(lsh[r]-lsh[l]+1);mn[x]=min(0ll,sum[x]);return;}
	id[x]=-1;datk[x]=datb[x]=0;
	int mid=(l+r)/2;modify(x*2,l,mid,tl,tr,k,b,ii);modify(x*2+1,mid+1,r,tl,tr,k,b,ii);
	sum[x]=sum[x*2]+sum[x*2+1];
	mn[x]=min(mn[x*2],sum[x*2]+mn[x*2+1]);
}
void query(int x,int l,int r,int tl,int tr)
{
	if(l>tr||r<tl||!(ans<0))return;
	if(tl<=l&&r<=tr)
	{
		if(preval+mn[x]>0){preval+=sum[x];return;}
		if(id[x]==-1)
		{if(l==r)return;int mid=(l+r)/2;if(mn[x*2]+preval<=0){query(x*2,l,mid,tl,tr);return;}else{preval+=sum[x*2];query(x*2+1,mid+1,r,tl,tr);return;}}
		else//preval+kx+b=0
		{
			double pos=1.0*(-preval)/datk[x]+lsh[l]-1;
			if((lsh[l]-1.0)<=pos&&pos<=1.0*lsh[r]&&lsh[tl]*1.0<=pos){ans=pos;return;}
		}
		preval+=sum[x];return;
	}
	else
	{
		if(id[x]==-1)
		{int mid=(l+r)/2;query(x*2,l,mid,tl,tr);if(!(ans<0))return;query(x*2+1,mid+1,r,tl,tr);return;}
		else
		{
			if(tl>=cal_tl[id[x]])return;
			double pos=1.0*(-preval)/datk[x]+lsh[l]-1;
			if((lsh[l]-1.0)<=pos&&pos<=1.0*lsh[r]&&lsh[tl]*1.0<=pos){ans=pos;return;}
		}
		preval+=sum[x];return;
	}
}
int main()
{
	int q;scanf("%d",&q);for(int i=0;i<q;i++){scanf("%d",&tp[i]);if(tp[i]==1){scanf("%d%d",&read_tl[i],&read_tval[i]);lsh.push_back(read_tl[i]);lsh.push_back(read_tl[i]+1);}else if(tp[i]==2){scanf("%d",&read_tl[i]);}else{scanf("%d%d%d",&read_tl[i],&read_tr[i],&read_tval[i]);lsh.push_back(read_tl[i]);lsh.push_back(read_tr[i]);}}

	sort(lsh.begin(),lsh.end());lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end());n=lsh.size();
//	modify(1,0,n-1,0,n-1,0,0,-1);memset(id,-1,sizeof(id));
	for(int i=0;i<q;i++)
	{
		if(tp[i]==1)
		{
	cal_tl[i]=lower_bound(lsh.begin(),lsh.end(),read_tl[i]+1)-lsh.begin();it=st.lower_bound(read_tl[i]);covr[i]=(it==st.end()?n:cal_tl[ttoi[*it]])-1;modify(1,0,n-1,cal_tl[i],covr[i],read_tval[i],-read_tval[i]*1ll*read_tl[i],i);if(it!=st.begin()){--it;pred=ttoi[*it];covr[pred]=cal_tl[i]-1;modify(1,0,n-1,cal_tl[pred],covr[pred],read_tval[pred],-read_tval[pred]*1ll*read_tl[pred],pred);}st.insert(read_tl[i]);ttoi[read_tl[i]]=i;}

		else if(tp[i]==2)
		{
	it=st.lower_bound(read_tl[i]);curd=ttoi[read_tl[i]];if(it!=st.begin()){--it;pred=ttoi[*it];covr[pred]=covr[curd];modify(1,0,n-1,cal_tl[pred],covr[pred],read_tval[pred],-read_tval[pred]*1ll*read_tl[pred],pred);}else{modify(1,0,n-1,0,covr[curd],0,0,-1);}st.erase(read_tl[i]);
}
		else{cal_tl[i]=lower_bound(lsh.begin(),lsh.end(),read_tl[i])-lsh.begin();cal_tr[i]=lower_bound(lsh.begin(),lsh.end(),read_tr[i])-lsh.begin();ans=-1;preval=read_tval[i];query(1,0,n-1,cal_tl[i],cal_tr[i]);printf("%.10lf\n",ans);}
	}
	return 0;
}

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <set>
#include <utility>
#include <vector>
using namespace std;

const int Q = 1e5;

int q, real_t[Q], n = 0;
struct query {int type, t, s, r, v, old_t;};
query queries[Q];

//c*t+d
bool is_lazy[Q];
int a[2*Q], b[2*Q];
long long f[2*Q], c[2*Q], d[2*Q], l[Q], r[Q], s[Q];

set<int> active_nxt;
set<int, greater<int>> active_prv;

void init(int k, int x, int y) {
    a[k] = x; b[k] = y;
    if(x == y) return;
    int m = (x+y)/2;
    init(2*k, x, m);
    init(2*k+1, m+1, y);
}

//c[t] * real_t[t] + d[t]
void push_down(int k) {
    if(!is_lazy[k]) return; is_lazy[k] = false;
    int m = (a[k]+b[k])/2;
    l[2*k]   += c[k]*real_t[a[k]] + d[k];
    r[2*k]   += c[k]*real_t[m]    + d[k];
    l[2*k+1] += c[k]*real_t[m+1]  + d[k];
    r[2*k+1] += c[k]*real_t[b[k]] + d[k];

    c[2*k]   += c[k]; d[2*k]   += d[k]; if(a[k] != m)   is_lazy[2*k] = true;
    c[2*k+1] += c[k]; d[2*k+1] += d[k]; if(m+1 != b[k]) is_lazy[2*k+1] = true;

    if(c[k] != 0) {
        f[2*k] =   min(l[2*k],   r[2*k]);
        f[2*k+1] = min(l[2*k+1], r[2*k+1]);
    }
    else {
        f[2*k]   += d[k];
        f[2*k+1] += d[k];
    }

    c[k] = d[k] = 0;
}

void range_add(int k, int x, int y, long long plus_c, long long plus_d) {
    if(a[k] == x && b[k] == y) {
        c[k] += plus_c; d[k] += plus_d;
        l[k] += plus_c*real_t[a[k]] + plus_d;
        r[k] += plus_c*real_t[b[k]] + plus_d;
        if(plus_c != 0) f[k] = min(l[k], r[k]);
        else f[k] += plus_d;
        if(a[k] != b[k]) is_lazy[k] = true;
        return;
    }
    push_down(k);
    int m = (a[k]+b[k])/2;
    if(y <= m) range_add(2*k, x, y, plus_c, plus_d);
    else if(m+1 <= x) range_add(2*k+1, x, y, plus_c, plus_d);
    else {
        range_add(2*k,   x,   m, plus_c, plus_d);
        range_add(2*k+1, m+1, y, plus_c, plus_d);
    }
    l[k] = l[2*k];
    r[k] = r[2*k+1];
    f[k] = min(f[2*k], f[2*k+1]);
}

bool tcomp(int i, int j) {
    if(queries[i].t != queries[j].t) return (queries[i].t < queries[j].t);
    return queries[i].type > queries[j].type;
}

vector<int> sorted;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    cin >> q;
    for (int i = 0; i < q; i++) {
        cin >> queries[i].type;
        if(queries[i].type == 1) cin >> queries[i].t >> queries[i].s;
        else if(queries[i].type == 2) cin >> queries[i].t;
        else cin >> queries[i].t >> queries[i].r >> queries[i].v;
        queries[i].old_t = queries[i].t;
    }

    for (int i = 0; i < q; i++) sorted.push_back(i);
    sort(sorted.begin(), sorted.end(), tcomp);

    int act_time = -1;
    for (int i: sorted) {
        if(queries[i].type == 3) queries[i].t = n;
        else {
            if(queries[i].t != act_time) {
                n++;
                act_time = real_t[n-1] = queries[i].t;
            }
            queries[i].t = n-1;
        }
    }

    if (n == 0) {
        for (int i = 0; i < q; i++) cout << (queries[i].v == 0 ? queries[i].old_t : -1) << "\n";
        return 0;
    }

    init(1, 0, n-1);

    //!note thet for late type3 events .t = n
    for (int i = 0; i < q; i++) {
        if(queries[i].type == 1) {
            long long c = queries[i].s;
            set<int>::iterator it = active_prv.upper_bound(queries[i].t);
            if(it != active_prv.end()) c -= s[*it];
            active_prv.insert(queries[i].t);

            it = active_nxt.upper_bound(queries[i].t);
            if(it != active_nxt.end()) {
                range_add(1, queries[i].t, (*it)-1, c, -c*real_t[queries[i].t]);
                range_add(1, (*it), n-1, 0, c*(real_t[*it]-real_t[queries[i].t]));
            }
            else range_add(1, queries[i].t, n-1, c, -c*real_t[queries[i].t]);
            active_nxt.insert(queries[i].t);

            s[queries[i].t] = queries[i].s;
        }
        else if(queries[i].type == 2) {
            long long c = -s[queries[i].t];
            set<int>::iterator it = active_prv.upper_bound(queries[i].t);
            if(it != active_prv.end()) c += s[*it];
            active_prv.erase(queries[i].t);

            it = active_nxt.upper_bound(queries[i].t);
            if(it != active_nxt.end()) {
                range_add(1, queries[i].t, (*it)-1, c, -c*real_t[queries[i].t]);
                range_add(1, (*it), n-1, 0, c*(real_t[*it]-real_t[queries[i].t]));
            }
            else range_add(1, queries[i].t, n-1, c, -c*real_t[queries[i].t]);
            active_nxt.erase(queries[i].t);
        }
        else {
            if(queries[i].t == n) cout << "-1\n";
            else if(queries[i].v == 0) cout << queries[i].old_t << "\n";
            else if(active_nxt.empty()) cout << "-1\n";
            else {
                int x = queries[i].t;
                int k = 1;
                while(a[k] < b[k]) {
                    push_down(k);
                    k = (x <= b[2*k] ? 2*k : 2*k+1);
                }
                long long v = f[k] - queries[i].v;
                //need: first <= v

                bool found = false;
                while(1 < k && !found) {
                    if(k%2 == 0 && f[k+1] <= v) {
                        found = true;
                        k++;
                    }
                    else k /= 2;
                }

                long long act_s, act_val;

                if(!found) {
                    set<int>::iterator it = active_nxt.end(); --it;
                    act_s = s[*it];
                    act_val = r[1];
                    k = n-1;

                    if(act_s >= 0) {cout << "-1\n"; continue;}
                }
                else {
                    while(a[k] != b[k]) {
                        push_down(k);
                        k = (f[2*k] <= v ? 2*k : 2*k+1);
                    }

                    if(active_prv.upper_bound(k-n) == active_prv.end()) {
                        cout << "ooops" << " " << k-n << endl;
                        return 0;
                    }

                    act_s = s[*active_prv.upper_bound(k-n)];
                    act_val = f[k]-(real_t[k-n]-real_t[k-1-n])*act_s;
                    k -= n+1;
                }

                if(act_val + (queries[i].r -real_t[k]) * act_s > v) cout << "-1\n";
                else cout << setprecision(9) << real_t[k] + ((long double)act_val-v)/(-act_s) << "\n";
            }

        }
    }

    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define mp(a, b) make_pair(a, b)
#define x first
#define y second

#define N 100555
#define L 1000000009

struct Range {
	int l, r, f, c;
	LL low, su;
	bool has;
	Range() {}
	Range(int v) {
		l = 0, r = 0;
		f = r + 1, c = 0;
		low = su = v;
		has = 0;
	}
	Range(int a, int b) {
		l = a, r = b;
		f = r + 1, c = 0;
		low = su = 0;
		has = 0;
	}
	Range(int a, int b, int v) {
		l = a, r = b;
		f = l, c = v;
		low = su = v;
		has = 1;
	}
} qq;

Range operator + (const Range &a, const Range &b) {
	Range ret;
	ret.l = a.l;
	ret.r = b.r;
	ret.f = a.has ? a.f : b.f;
	ret.c = b.has ? b.c : a.c;
	LL mid = LL(b.f - b.l) * a.c;
	ret.low = min(a.low, a.su + mid + min(b.low, 0ll));
	ret.su = a.su + mid + b.su;
	ret.has = a.has | b.has;
	return ret;
}

struct Node {
	int l, r;
	Range v;
} t[N * 40];

int rt = 0, tcnt = 0;

int newNode(int l, int r) {
	t[++tcnt].v = Range(l, r);
	t[tcnt].l = t[tcnt].r = 0;
	return tcnt;
}

void upd(int &x, int l, int r, int p, int v) {
	if (!x) x = newNode(l, r);
	if (l < r) {
		int mid = (l + r) >> 1;
		if (p <= mid) upd(t[x].l, l, mid, p, v);
		else 		  upd(t[x].r, mid + 1, r, p, v);
		t[x].v = (t[x].l ? t[t[x].l].v : Range(l, mid)) + (t[x].r ? t[t[x].r].v : Range(mid + 1, r));
	}
	else {
		t[x].v = Range(p, p, v);
	}
}

void clr(int &x, int l, int r, int p) {
	if (!x) x = newNode(l, r);
	if (l < r) {
		int mid = (l + r) >> 1;
		if (p <= mid) clr(t[x].l, l, mid, p);
		else 		  clr(t[x].r, mid + 1, r, p);
		t[x].v = (t[x].l ? t[t[x].l].v : Range(l, mid)) + (t[x].r ? t[t[x].r].v : Range(mid + 1, r));
	}
	else {
		t[x].v = Range(p, p);
	}
}

bool ok;
double ans;

void solve(int x, int l, int r) {
	if (!t[x].v.has) {
		LL su = qq.su, vv = qq.c, tt = r - l + 1;
		if (su + vv * tt <= 0) {
			ok = 1;
			ans = l + double(su) / -vv;
		}
		else qq = qq + Range(l, r);
		return;
	}
	LL ins = qq.c * (t[x].v.f - t[x].l);
	if (qq.su + ins <= 0) {
		ok = 1;
		ans = l + double(qq.su) / -qq.c;
		return;
	}
	if (qq.su + ins + min(t[x].v.low, 0ll) > 0) {
		qq = qq + t[x].v;
		return;
	}
	if (l == r) {
		ok = 1;
		ans = l + double(qq.su) / -t[x].v.c;
	}
	else {
		int mid = (l + r) >> 1;
		solve(t[x].l, l, mid);
		if (ok) return;
		solve(t[x].r, mid + 1, r);
	}
	//assert ok
}

void qry(int x, int l, int r, int ql, int qr) {
	if (ok) return;
	if (!x || (l == ql && r == qr)) {
		solve(x, ql, qr);
		return;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid) qry(t[x].l, l, mid, ql, min(mid, qr));
	if (qr >  mid) qry(t[x].r, mid + 1, r, max(mid + 1, ql), qr);
}

int Q;

const double eps = 1e-8;

int main() {
	cin >> Q;
	while (Q--) {
		int op, t, s, l, r, v;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &t, &s);
			upd(rt, -L, L, t, s);
		}
		else if (op == 2) {
			scanf("%d", &t);
			clr(rt, -L, L, t);
		}
		else {
			scanf("%d%d%d", &l, &r, &v);
			if (v == 0) {
				printf("%d\n", l);
				continue;
			}
			qq = v;
			ok = 0;
			qry(rt, -L, L, l, r);
			if (ok && ans + eps >= l && ans - eps <= r) printf("%.6lf\n", ans);
			else puts("-1");
		}
	}
	return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(time(NULL));
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void ispis(pnode x){

    if(x==NULL)return;
    push(x);

    ispis(x->l);
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void upd(pnode x){
    if(x==NULL)return;
    ////x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
    x->mn=x->val;
    if(x->l!=NULL)x->mn=x->l->val<x->mn?x->l->val:x->mn;
    ///pnode pr=x->r;
    if(x->r!=NULL)x->mn=
        x->r->val<x->mn?
        x->r->val:x->mn;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_val(x->l)<=val){
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*printf("ISPIS\n");
        ispis(midtree);
        printf("\n");*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
       /// printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);

    scanf("%d",&q);
    while(q--){

        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            cout<<query(l,r,v)<<endl;
            ///printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(500);
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void ispis(pnode x){

    if(x==NULL)return;
    push(x);

    ispis(x->l);
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void upd(pnode x){
    if(x==NULL)return;
    ////x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
    x->mn=x->val;
    if(x->l!=NULL)x->mn=x->l->val<x->mn?x->l->val:x->mn;
    ///pnode pr=x->r;
    if(x->r!=NULL)x->mn=
        x->r->val<x->mn?
        x->r->val:x->mn;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_mn(x->l)<=val){
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;if(sq==10000)ret=-2;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*if(sq==10000){
            printf("\n\nISPIS\n");
            ispis(midtree);
            printf("\n");
        }*/
        //

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
        if(sq==10000)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            if(sq==10000)printf("%d TMTM\n",tm);
            ///if(tm==0 || pom1==NULL)printf("AAAJEBOTE\n");

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            if(sq==10000){
                cout<<lst->val<<" "<<lst->t<<" "<<lst->s<<" "<<zero<<" EVO GA"<<endl;
            }
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<" "<<s<<endl;}
            else ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<endl;}
            else del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(sq==101){
                cout<<tip<<" "<<l<<" "<<r<<" "<<v<<endl;
                continue;
            }
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            cout<<fixed;
            cout<<setprecision(6);
            cout<<query(l,r,v)<<endl;
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include<bits/stdc++.h>
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
using namespace std;

template<class T>inline void rd(T & x){ int f = 1;x = 0;char ch = getchar();for(;!isdigit(ch);ch = getchar()) if(ch == '-') f = -1; for(;isdigit(ch);ch = getchar()) x = x * 10 + ch - '0';x *= f;}

const int maxn = 1e5 + 10;

struct op{
	int type;
	int t,l,r,v,s;
} querys[maxn];

int times[maxn],n;
inline int upper(double time){
	int l = 1,r = n,ans = n + 1;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] >= time){
			ans = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	return ans;
}
inline int lower(double time){
	int l = 1,r = n,ans = 0;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] <= time){
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return ans;
}

int mark[maxn];
namespace Fenwick{
	int tr[maxn];
	inline void update(int x,int v){ for(;x < maxn;x += x & (-x)) tr[x] += v;}
	inline int query(int x){ int ans = 0; for(;x;x ^= x & (-x)) ans += tr[x]; return ans;}
	inline int val(int x) { return query(x) - query(x - 1);}
	inline int bs(int x){ // min query(ans) >= x
		int l = 0,r = n,ans = 0;
		while(l <= r){
			int mid = l + r >> 1;
			if(query(mid) >= x) {
				ans = mid;
				r = mid - 1;
			} else {
				l = mid + 1;
			}
		}
		return ans;
	}
	inline int pre(int x){
		int d = query(x - 1);
		return bs(d);
	}
	inline int suc(int x){
		return bs(query(x) + 1);
	}
}
double cur[maxn];
const double inf = 2e20;
namespace Segment{
	double tra[maxn << 2],tri[maxn << 2];
	double lazy[maxn << 2];
	int mk[maxn << 2];

	inline void pushup(int rt){
		tra[rt] = max(tra[rt << 1],tra[rt << 1 | 1]);
		tri[rt] = min(tri[rt << 1],tri[rt << 1 | 1]);
	}
	inline void pushdown(int rt){
		if(!mk[rt]) return;
		mk[rt] = 0;
		mk[rt << 1] = 1;
		mk[rt << 1 | 1] = 1;
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		tra[rt << 1] += lazy[rt];
		tri[rt << 1] += lazy[rt];
		tra[rt << 1 | 1] += lazy[rt];
		tri[rt << 1 | 1] += lazy[rt];
		lazy[rt] = 0;
	}
	void _update(double * target,int pos,double v,int l,int r,int rt){
		if(l == r){
			target[rt] = v;
			return;
		}
		int mid = l + r >> 1;
		if(pos <= mid) _update(target,pos,v,lson);
		else _update(target,pos,v,rson);
		pushup(rt);
	}
	void setVoid(int pos){
		_update(tra,pos,-inf,1,n,1);
		_update(tri,pos,inf,1,n,1);
	}
	void setZero(int pos){
		_update(tra,pos,0,1,n,1);
		_update(tri,pos,0,1,n,1);
	}
	void build(int l,int r,int rt){
		if(l == r){
			tra[rt] = -inf;
			tri[rt] = inf;
			return;
		}
		int mid = l + r >> 1;
		build(lson);
		build(rson);
		pushup(rt);
	}
	void update(int L,int R,double v,int l,int r,int rt){
		if(L <= l && r <= R){
			lazy[rt] += v;
			tra[rt] += v;
			tri[rt] += v;
			mk[rt] = 1;
			return;
		}
		pushdown(rt);
		int mid = l + r >> 1;
		if(L <= mid) update(L,R,v,lson);
		if(R > mid) update(L,R,v,rson);
		pushup(rt);
	}
	double querya(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tra[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = -inf;
		if(L <= mid) ans = max(ans,querya(L,R,lson));
		if(R > mid)ans = max(ans,querya(L,R,rson));
		return ans;
	}
	double queryi(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tri[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = inf;
		if(L <= mid) ans = min(ans,queryi(L,R,lson));
		if(R > mid) ans = min(ans,queryi(L,R,rson));
		return ans;
	}

}
double getV(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return cur[x];
}
double calc(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return (double)(l - times[x]) * cur[x] + Segment::querya(x,x,1,n,1);
}
const double eps = 1e-15;
bool check(double l,double r,double c){
	double qa = -inf,qi = inf;
	if(l == r) return abs(calc(l) - c) <= eps;
	qa = max(calc(l),qa);
	qi = min(calc(l),qi);
	qa = max(calc(r),qa);
	qi = min(calc(r),qi);
	int lx = upper(l),rx = lower(r);
	if(lx <= rx && lx != 0 && rx != 0){
		qa = max(qa,Segment::querya(lx,rx,1,n,1));
		qi = min(qi,Segment::queryi(lx,rx,1,n,1));
	}
//	printf("%.9f %.9f %.9f %.9f %.9f\n",l,r,qa,qi,c);
	return qa - c >= 0 && qi - c <= 0;
}

int main(){
	int TAT;
	int ttt = 0;
	rd(TAT);
	for(int i = 1;i <= TAT;i++){
		int type,t,l,r,v,s;
		rd(type);
		if(type == 1){ // add
			rd(t); rd(v);
			times[++n] = t;
			querys[i].type = 1;
			querys[i].t = t;
			querys[i].v = v;
		} else if(type == 2){
			rd(t);
			querys[i].type = 2;
			querys[i].t = t;
		} else {
			rd(l); rd(r); rd(s);
			querys[i].type = 3;
			querys[i].l = l;
			querys[i].r = r;
			querys[i].s = s;
		}
	}
	sort(times + 1,times + n + 1);
	n = unique(times + 1,times + n + 1) - times - 1;

	if(n!=0)Segment::build(1,n,1);
	for(int i = 1;i <= TAT;i++){
		int type = querys[i].type;
		if(type == 1){
			int t = querys[i].t, v = querys[i].v;
			int pos = upper(t);
			Fenwick::update(pos,1);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			cur[pos] = v;
			Segment::setZero(pos);
			if(pre){
				double delta = (double)cur[pre] * (times[pos] - times[pre]) + Segment::querya(pre,pre,1,n,1);
				Segment::update(pos,pos,delta,1,n,1);
			}
			if(suc){
				double delta = (double)(v - cur[pre]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
		} else if(type == 2){
			int t = querys[i].t;
			int pos = upper(t);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			Fenwick::update(pos,-1);
			if(suc){
				double delta = (double)(cur[pre] - cur[pos]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
			Segment::setVoid(pos);
			cur[pos] = 0;
		} else {
			ttt++;
			double l = querys[i].l , r = querys[i].r , s = -querys[i].s;
			int lx = upper(l);
			if(Fenwick::val(lx) == 0) lx = Fenwick::suc(lx);
			l = times[lx];
			if(s == 0) {
				printf("%d\n",querys[i].l);
				continue;
			}
			if(n == 0 || Fenwick::query(n) == 0 || !lx || l > r) {
				printf("-1\n");
				continue;
			}
			s += Segment::querya(lx,lx,1,n,1);

			bool ok = 0;
			if(check(r,r,s) || check(l,l,s)) ok = 1;
			for(int k = 0;k < 1000;k++){
				double mid = (l + r) / 2;
				if(check(l,mid,s)){
					r = mid;
					ok = 1;
				} else {
					l = mid;
				}
			}
			if(fabs(calc(l) - s) <= eps) ok = 1;
			if(ttt == 20) printf("%.9f %.9f %.9f\n",l,calc(38),s);
			if(ok)printf("%.9f\n",r);
			else printf("-1\n");
		}
	}
}

#include<bits/stdc++.h>

using namespace std;

//const int NMAX = 100;
const int NMAX = 350009;

long long Q, N, currentS[NMAX], s[NMAX], t[NMAX], l[NMAX], r[NMAX], v[NMAX], type[NMAX];
vector < long long > ts;
map < long long, long long > inverseT;

void read ()
{
    scanf ("%I64d", &Q);
    for (int i=1; i<=Q; i++)
    {
        scanf ("%I64d", &type[i]);
        if (type[i] == 1) scanf ("%I64d %I64d", &t[i], &s[i]), ts.push_back (t[i]);
        else
        if (type[i] == 2) scanf ("%I64d", &t[i]);
        else
        {
            scanf ("%I64d %I64d %I64d", &l[i], &r[i], &v[i]);
            ts.push_back (l[i]), ts.push_back (r[i]);
        }
    }
    sort (ts.begin (), ts.end ());
    ts.erase (unique (ts.begin (), ts.end ()), ts.end ()), N = ts.size ();
/*    for (auto it : ts)
        printf ("%I64d\n", it);*/
    for (long long i=0; i<N; i++)
        inverseT[ts[i]] = i + 1;
    long long lastVal = ts[N - 1];
    ts.push_back (lastVal);
    for (int i=1; i<=Q; i++)
        if (type[i] <= 2) t[i] = inverseT[t[i]];
        else l[i] = inverseT[l[i]], r[i] = inverseT[r[i]];
}

set < long long > currTimes;
long long sum[4 * NMAX], mi[4 * NMAX];
long long vl[4 * NMAX];
bool lzy[4 * NMAX];

long long getLength (long long x, long long y) {return ts[y] - ts[x - 1];}

void split (long long nod, long long st, long long mij, long long dr, long long f1, long long f2)
{
    if (lzy[nod] == 0) return ;
    lzy[f1] = lzy[f2] = 1;
    vl[f1] = vl[f2] = vl[nod];
    sum[f1] = 1LL * vl[nod] * getLength (st, mij);
    mi[f1] = min (0LL, sum[f1]);
    sum[f2] = 1LL * vl[nod] * getLength (mij + 1, dr);
    mi[f2] = min (0LL, sum[f2]);
    lzy[nod] = 0;
}

void setValue (long long nod, long long st, long long dr, long long x, long long y, long long s)
{
/*    if (nod == 1)
        printf ("set %I64d [%I64d, %I64d]\n", s, x, y);*/
    if (x <= st && dr <= y)
    {
        vl[nod] = s, lzy[nod] = 1;
        sum[nod] = 1LL * s * getLength (st, dr);
        mi[nod] = min (0LL, sum[nod]);
        return ;
    }
    long long mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    split (nod, st, mij, dr, f1, f2);
    if (x <= mij) setValue (f1, st, mij, x, y, s);
    if (mij < y) setValue (f2, mij + 1, dr, x, y, s);
    sum[nod] = sum[f1] + sum[f2];
    mi[nod] = min (mi[f1], sum[f1] + mi[f2]);
}

long double ansQ = -1.0;
const long double eps = 1e-9;
long long curr;
void query (long long nod, long long st, long long dr, long long x, long long y)
{
    if (ansQ > -0.5)
        return ;
    if (x <= st && dr <= y)
    {
        long long mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
        if (st == dr)
        {
            if (mi[nod] + curr > 0)
            {
                curr += sum[nod];
                return ;
            }
            long long t1 = ts[st - 1], t2 = ts[st];
            assert (vl[nod] < 0);
            ansQ = t1 + 1.0 * curr / (-vl[nod]);
            assert (ansQ > -0.5);
            return ;
        }
        split (nod, st, mij, dr, f1, f2);
        if (curr + mi[f1] <= 0)
        {
            query (f1, st, mij, x, y);
            assert (ansQ > -0.5);
        }
        else
        if (curr + sum[f1] + mi[f2] <= 0)
        {
            curr += sum[f1], query (f2, mij + 1, dr, x, y);
            assert (ansQ > -0.5);
        }
        else curr += sum[nod];
        return ;
    }
    long long mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    split (nod, st, mij, dr, f1, f2);
    if (x <= mij) query (f1, st, mij, x, y);
    if (mij < y) query (f2, mij + 1, dr, x, y);
}

int main ()
{
//freopen ("input", "r", stdin);
//freopen ("output", "w", stdout);

read ();
for (long long i=1; i<=Q; i++)
{
    if (type[i] == 1)
    {
        currTimes.insert (t[i]);
        auto it = currTimes.find (t[i]); it ++;
        long long rgt = N;
        if (it != currTimes.end ()) rgt = (*it) - 1;
        setValue (1, 1, N, t[i], rgt, s[i]);
        currentS[t[i]] = s[i];
        continue;
    }
    if (type[i] == 2)
    {
        auto it = currTimes.find (t[i]);
        long long s = 0;
        if (it != currTimes.begin ())
        {
            auto it2 = it;
            it2 --; s = currentS[*it2];
        }
        it ++;
        long long rgt = N;
        if (it != currTimes.end ()) rgt = (*it) - 1;
        setValue (1, 1, N, t[i], rgt, s);
        currTimes.erase (t[i]), currentS[t[i]] = 0;
        continue;
    }
    ansQ = -1.0;
    if (v[i] == 0)
    {
        printf ("%I64d\n", ts[l[i] - 1]);
        continue;
    }
    if (l[i] != r[i])
        curr = v[i], query (1, 1, N, l[i], r[i] - 1);
    assert (ansQ <= ts[r[i] - 1] + eps);
    cout << setprecision (15) << ansQ << '\n';
}
return 0;
}

#pragma GCC optimize("Ofast")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define int lld
typedef int64_t lld;
typedef pair<int,int> pii;
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(),(x).end()
//#define endl '\n'
#define jizz cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

template<typename Iter>
ostream& _out(ostream &s, Iter b, Iter e) {
    s<<"[";
    for ( auto it=b; it!=e; it++ ) s<<(it==b?"":" ")<<*it;
    s<<"]";
    return s;
}
template<class T1,class T2>
ostream& operator<<(ostream& out, pair<T1,T2> p) {
    return out << '(' << p.first << ", " << p.second << ')';
}
template<class T1,class T2>
istream& operator>>(istream& in, pair<T1,T2>& p) {
    return in >> p.ff >> p.ss;
}
template<typename T>
ostream& operator <<( ostream &s, const vector<T> &c ) {
     return _out(s,c.begin(),c.end());
}
template<typename T, size_t N>
ostream& operator <<( ostream &s, const array<T, N> &c ) {
     return _out(s,c.begin(),c.end());
}
inline char readchar() {
	const int S = 1<<20; // buffer size
	static char buf[S], *p = buf, *q = buf;
	if(p == q && (q = (p=buf)+fread(buf,1,S,stdin)) == buf) return EOF;
	return *p++;
}
inline void input(int &_x){
    _x = 0;
    int _tmp = 1; char _tc = readchar();
    while(_tc < '0' || _tc > '9') _tc = readchar();
    while(_tc >= '0' && _tc <= '9') _x = (_x<<1)+(_x<<3)+(_tc-48), _tc = readchar();
}
inline void output(int _x){
    char _buff[20]; int _f = 0;
    if(_x == 0) putchar('0');
    while(_x > 0){
            _buff[_f++] = _x%10+'0';
            _x /= 10;
    }
    for(_f-=1; _f >= 0; _f--)
            putchar(_buff[_f]);
  putchar('\n');
}

inline int ran(){
    static int x = 71222217;
    return x = (x*0xdefaced+1)&INT_MAX;
}

struct Q{
    lld a = 0; int b = 1;
    Q& operator+(int x){
        a+=(lld)x*b; return *this;
    }
    bool operator>(int x){
        return a>(lld)b*x;
    }
    friend ostream& operator<<(ostream& out, Q x){
        return out << (long double)x.a/x.b;
    }
    Q(int aa = 0, int bb = 1){ a = aa, b = bb; if(b<0)b = -b, a = -a; }
};

struct node{
    node *L = 0, *R = 0;
    int a; lld b; // a(t-l) + b;
    int l, r, alt = 0, pri;
    lld mins = LLONG_MAX;
    node(int l, int r, int a, int b) : l(l), r(r), a(a), b(b) {
        pri = ran(); up();
    }
    void upda(int x){ mins+=x, b+=x, alt+=x; }
    void down(){ if(L)L->upda(alt); if(R)R->upda(alt); alt = 0; }
    void up(){ mins = min(b, val()); if(L)mins = min(mins, L->mins); if(R)mins = min(mins, R->mins); }
    tuple<node*, node*, node*> split(int i){
        down();
        if(i < l){
            //while(!L);
            auto [a, b, c] = L->split(i);
            L = c; up();
            return {a, b, this};
        } else if(i >= r){
            //while(!R);
            auto [a, b, c] = R->split(i);
            R = a; up();
            return {this, b, c};
        } else {
            auto a = L, b = R;
            L = R = 0; up();
            return {a, this, b};
        }
    }
    static node* merge(node *a, node *b){
        if(!a)return b; if(!b)return a;
        if(a -> pri < b -> pri){
            a->down();
            a->R = merge(a->R, b);
            a -> up();
            return a;
        }else{
            b->down();
            b->L = merge(a, b->L);
            b-> up();
            return b;
        }
    }
    node* last(){return R?R->last():this; } node*first(){ return L?L->first():this; }
    static node* merge(vector<node*> a){
        node *n = 0;
        for(auto i: a){
                if(n&&i)assert(n->last()->r == i->first()->l);
                n = merge(n, i);
        }
        return n;
    }
    Q find(int x){
        down();
        //cout << x << " " << show() << endl;
        if(L && L->mins <= x)return L->find(x);
        if(val() <= x)
            return inverse(x);
        if(R)return R->find(x);
        throw 0;
    }
    lld setlast(int x){
        if(R){
            down();
            auto a = R->setlast(x);
            up();
            return a;
        }else return r = x, val();
    }
    //void assertlast(){ if(R)R->assertlast(); else if(r < 1000000000) exit(0); }
    pair<pii, pair<int, lld>> show(){ return  make_pair(make_pair(l, r), make_pair(a, b)); }
    ostream& print(ostream& out){
        down();
        if(L)L->print(out);
        out << show() << " ";
        if(R)R->print(out);
        return out;
    }
    lld val(int x = -1){ if(x<0)x=r; return (lld)a*(x-l)+b; } // a(x-l)=(y-b)/a
    Q inverse(lld y){ if(a)return Q(y-b, a)+l; if(y != b)throw -1; return Q(l); }
} *root = new node(0, 1000100000, 0, 0);

ostream& operator<<(ostream& out, node* n){
    if(!n)return out << "NULL";
    return n->print(out);
}

vector<int> u, v, uu, vv;
signed main(){jizz; //freopen("test.in", "r", stdin);
#ifdef LOCAL
freopen("test.in", "r", stdin);
#endif
    int q;
    cin >> q;
    cout << setprecision(20) << fixed;
    //root->assertlast();
    while(q--){
        //root->assertlast();
        int a;
        cin >> a;
        //cout << root << endl;
        if(a == 1){
            int t, s;
            cin >> t >> s;t++;
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!m);
            lld prev = m->val();
            if(m->l == t){
                m->a = s;
                if(r)r->upda(m->val()-prev);
                root = node::merge({l, m, r});
            }else{
                int mr = m->r; m->r = t;
                node* x = new node(t, mr, s, m->val());
                if(r)r->upda(x->val()-prev);
                root = node::merge({l, m, x, r});
            }
        }
        if(a == 2){
            int t;
            cin >> t;t++;
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!l); while(!m);while(m->l != t);
            auto newval = l->setlast(m->r);
            if(r)r->upda(newval-m->val());
            root = node::merge({l, r});
            delete m;
        }
        if(a == 3){
            int t, rr, v;
            cin >> t >> rr >> v;
            if(!v){ cout << t << endl; continue; }
            while(!root);
            auto [l, m, r] = root->split(t);
            while(!m);
            lld start = m->val(t)-v;
            try{
                Q ans;
                if(m->val() <= start)ans = m->inverse(start);
                else if(!r)throw -1;
                else ans = r->find(start);
                ans = ans+(-1);
                //cout << ans << endl;
                if(ans > rr)throw -1;
                cout << ans << endl;
            }catch(signed i){
                cout << -1 << endl;
            }
            root = node::merge({l, m, r});
        }
        //root->assertlast();
    }
}

/* cerberus97 - Hanit Banga */

#include <iostream>
#include <iomanip>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>

using namespace std;

#define pb push_back
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL)

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

const int N = 2e5 + 10;
const ll inf = 1e18 + 42;

struct seg_node {
	ll sum, min_val, min_t, max_s;
	seg_node() : sum(0), min_val(0), min_t(inf), max_s(-inf) {}
};

struct qry_type {
	int type, v1, v2, v3;
};

seg_node tree[4 * N];
qry_type q[N];
map<ll, int> compress;
ll rev[N];

void update(int i, int l, int r, int p, ll s);
void combine(int i, int lc, int rc, int l, int mid, int r);
bool query(int i, int l, int r, int ql, int qr, ll &v, ll &s, ld &ans);

int main() {
	// cout << sizeof(tree) / 1e6 << endl;
	fast_cin();
	int t; cin >> t;
	for (int i = 0; i < t; ++i) {
		cin >> q[i].type >> q[i].v1;
		compress[q[i].v1];
		if (q[i].type == 1) {
			cin >> q[i].v2;
		} else if (q[i].type == 3) {
			cin >> q[i].v2 >> q[i].v3;
			compress[q[i].v2];
		}
	}
	int id = 0;
	for (auto &i : compress) {
		i.second = id;
		rev[id] = i.first;
		++id;
		// cout << i.second << ' ' << i.first << endl;
	}
	for (int i = 0; i < t; ++i) {
		// cout << "qry " << i << endl;
		if (q[i].type == 1) {
			update(1, 0, id, compress[q[i].v1], q[i].v2);
		} else if (q[i].type == 2) {
			update(1, 0, id, compress[q[i].v1], inf);
		} else {
			ll v = q[i].v3;
			ll s = 0;
			ld ans = 0;
			if (v == 0) {
				cout << q[i].v1 << '\n';
			} else if (query(1, 0, id, compress[q[i].v1], compress[q[i].v2], v, s, ans)) {
				cout << fixed << setprecision(10) << ans << '\n';
			} else {
				cout << -1 << '\n';
			}
		}
	}
}

void update(int i, int l, int r, int p, ll s) {
	// cout << i << ' ' << l << ' ' << r << endl;
	if (p < l or p >= r) {
		return;
	} else if (l == r - 1) {
		if (s == inf) {
			tree[i].sum = 0;
			tree[i].min_val = 0;
			tree[i].min_t = inf;
			tree[i].max_s = -inf;
		} else {
			tree[i].sum = s * (rev[r] - rev[l]);
			tree[i].min_val = min(0ll, tree[i].sum);
			tree[i].min_t = l;
			tree[i].max_s = s;
		}
	} else {
		int mid = (l + r) / 2, lc = 2 * i, rc = lc + 1;
		update(lc, l, mid, p, s);
		update(rc, mid, r, p, s);
		combine(i, lc, rc, l, mid, r);
	}
}

void combine(int i, int lc, int rc, int l, int mid, int r) {
	// cout << i << ' ' << lc << ' ' << rc << ' ' << mid << endl;
	ll transition = 0;
	if (tree[lc].max_s != -inf) {
		ll temp = rev[r];
		if (tree[rc].min_t != inf) {
			temp = rev[tree[rc].min_t];
		}
		transition = (temp - rev[mid]) * tree[lc].max_s;
	}
	tree[i].sum = tree[lc].sum + tree[rc].sum + transition;
	tree[i].min_val = min(tree[lc].min_val, tree[lc].sum + transition + tree[rc].min_val);
	tree[i].min_t = min(tree[lc].min_t, tree[rc].min_t);
	tree[i].max_s = max(tree[lc].max_s, tree[rc].max_s);
	// cout << "DONE" << endl;
}

bool query(int i, int l, int r, int ql, int qr, ll &v, ll &s, ld &ans) {
	int mid = (l + r) / 2, lc = 2 * i, rc = lc + 1;
	// cout << i << ' ' << l << ' ' << r << ' ' << ql << ' ' << qr << ' ' << v << ' ' << s << endl;
	// cout << t
	if (l > qr or ql >= r) {
		return false;
	} else if (ql <= l and r <= qr) {
		if (tree[i].min_t == inf) {
			ll sz = rev[r] - rev[l];
			if (v + sz * s <= 0) {
				ans = rev[l] + ld(-v) / s;
				return true;
			} else {
				v += sz * s;
				return false;
			}
		} else {
			ll transition = rev[tree[i].min_t] - rev[l];
			ll min_val = v + transition * s + tree[i].min_val;
			if (v + transition * s <= 0) {
				ans = ld(-v) / s + rev[l];
				return true;
			} else if (min_val <= 0) {
				if (l == r - 1) {
					// cout << "c" << ' ' << rev[l] << ' ' << ld(-v) << ' ' << tree[i].max_s << endl;
					ans = rev[l] + ld(-v) / tree[i].max_s;
					// cout << ans << endl;
					return true;
				} else if (query(lc, l, mid, ql, qr, v, s, ans)) {
					return true;
				} else {
					return query(rc, mid, r, ql, qr, v, s, ans);
				}
			} else {
				v += transition * s + tree[i].sum;
				s = tree[i].max_s;
				return false;
			}
		}
	} else if (l == r - 1) {
		return false;
	} else {
		if (query(lc, l, mid, ql, qr, v, s, ans)) {
			return true;
		} else {
			return query(rc, mid, r, ql, qr, v, s, ans);
		}
	}
}

#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int myrand() {return abs((int) mt());}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

template<typename num_t>
struct node_t {
    node_t *l, *r;
    int h, size, rev;
    num_t key, lz;
    num_t s, ss, mn;
    node_t<num_t> *first_node, *last_node;
    node_t(num_t key, num_t s, node_t* l = 0, node_t* r = 0, int h = rand()) : key(key), s(s), ss(0), mn(0), l(0), r(0), h(h) {
        size = (l ? l->size : 0) + 1 + (r ? r->size : 0);
        rev = lz = 0;
        first_node = last_node = this;
    }
};

template<typename num_t>
int size(node_t<num_t>* x) {
    return x ? x->size : 0;
}
template<typename num_t>
void pull(node_t<num_t>* x) {
    x->size = size(x->l) + 1 + size(x->r);
    x->first_node = x->last_node = x;
    x->ss = 0;
    x->mn = 1e18;
    if (x->l) {
        x->first_node = x->l->first_node;
        x->ss += x->l->ss;
        x->ss += x->l->last_node->s * (x->key - x->l->last_node->key);
        chkmin(x->mn, x->l->mn);
    }
    chkmin(x->mn, x->ss);
    if (x->r) {
        x->last_node = x->r->last_node;
        x->ss += x->s * (x->r->first_node->key - x->key);
        chkmin(x->mn, x->ss + x->r->mn);
        x->ss += x->r->ss;
    }
}
template<typename num_t>
void push(node_t<num_t>* x) {
    node_t<num_t>* u = x->l;
    node_t<num_t>* v = x->r;
    if (x->rev) {
        if (u) swap(u->l, u->r), u->rev ^= 1;
        if (v) swap(v->l, v->r), v->rev ^= 1;
        x->rev = 0;
    }
    if (x->lz) {
        if (u) u->key += x->lz, u->lz += x->lz;
        if (v) v->key += x->lz, v->lz += x->lz;
        x->lz = 0;
    }
}
template<typename num_t>
node_t<num_t>* join(node_t<num_t>* x, node_t<num_t>* y) {
    if (!x) return y;
    if (!y) return x;
    if (x->h < y->h) {
        push(x);
        x->r = join(x->r, y);
        pull(x);
        return x;
    }
    push(y);
    y->l = join(x, y->l);
    pull(y);
    return y;
}
template<typename num_t>
void split(node_t<num_t>* x, node_t<num_t>*& l, node_t<num_t>*& r, int pos) {
    if (!x) {
        l = r = 0;
        return;
    }
    push(x);
    if (size(x->l) + 1 <= pos) {
        split(x->r, x->r, r, pos - size(x->l) - 1);
        pull(l = x);
    }
    else {
        split(x->l, l, x->l, pos);
        pull(r = x);
    }
}
template<typename num_t>
void split(node_t<num_t>* t, node_t<num_t>*& x, node_t<num_t>*& y, node_t<num_t>*& z, int l, int r) {
    split(t, x, y, l);
    split(y, y, z, r - l + 1);
}
template<typename num_t>
void reverse(node_t<num_t>*& x, int l, int r) {
    node_t<num_t> *y, *z;
    split(x, x, y, z, l, r);
    y->rev ^= 1;
    swap(y->l, y->r);
    x = join(x, join(y, z));
}
template<typename num_t>
void upd(node_t<num_t>*& x, int l, int r, num_t val) {
    node_t<num_t> *y, *z;
    split(x, x, y, z, l, r);
    y->lz += val;
    y->key += val;
    x = join(x, join(y, z));
}
template<typename num_t>
void split(node_t<num_t>* x, node_t<num_t>*& l, node_t<num_t>*& r, const function<bool(node_t<num_t>*)>& go_right) {
    if (!x) {
        l = r = 0;
        return;
    }
    push(x);
    if (go_right(x)) {
        split(x->r, x->r, r, go_right);
        pull(l = x);
    }
    else {
        split(x->l, l, x->l, go_right);
        pull(r = x);
    }
}
template<typename num_t>
void insert(node_t<num_t>*& x, num_t key, num_t s) {
    node_t<num_t>* y;
    split<num_t>(x, x, y, [&] (node_t<num_t>* x) {
            return x->key < key;
            }
            );
    x = join(x, join(new node_t<num_t>(key, s), y));
}
template<typename num_t>
node_t<num_t>* erase(node_t<num_t>*& x, num_t key) {
    node_t<num_t> *l, *r, *res;
    split<num_t>(x, l, res, [&] (node_t<num_t>* x) {
            return x->key < key;
            }
            );
    split<num_t>(res, res, r, [&] (node_t<num_t>* x) {
            return x->key <= key;
            }
            );
    x = join(l, r);
    return res;
}
template<typename num_t>
void free(node_t<num_t>* x) {
    if (!x) return;
    free(x->l);
    free(x->r);
    delete x;
}
template<typename num_t>
int depth(node_t<num_t>* x) {
    if (!x) return 0;
    push(x);
    return 1 + max(depth(x->l), depth(x->r));
}
template<typename num_t>
void trace(node_t<num_t>* x, int isrt = 1) {
    if (!x) return;
    push(x);
    trace(x->l, 0);
    cerr << "(" << x->key << ", " << x->s << ", " << x->ss << ") ";
    trace(x->r, 0);
    if (isrt) {
        cerr << "\n";
    }
}
template<typename num_t>
long double query(node_t<num_t>* x, num_t val, node_t<num_t>* prv) {
    node_t<num_t>* r = x->r;
    x->r = 0;
    pull(x);
    num_t ss = x->ss;
    x->r = r;
    pull(x);
    if (x->l && x->l->mn + val <= 0) {
        return query(x->l, val, prv);
    }
    if (ss + val <= 0) {
        if (x->l) prv = x->l->last_node;
        return x->key - (long double) (ss + val) / prv->s;
    }
    if (x->r) {
        return query(x->r, val + ss + x->s * (x->r->first_node->key - x->key), x);
    }
    return -1;
}

const int maxn = 1e5 + 5;
int q;

void chemthan() {
    node_t<long long>* rt = 0;
    cin >> q;
    while (q--) {
        int op; cin >> op;
        if (op == 1) {
            long long t, s; cin >> t >> s;
            insert(rt, t, s);
        }
        else if (op == 2) {
            long long t; cin >> t;
            assert(erase(rt, t));
        }
        else {
            long long l, r, v; cin >> l >> r >> v;
            if (!v) {
                cout << l << "\n";
                continue;
            }
            node_t<long long> *x, *y;
            split<long long>(rt, x, rt, [&] (node_t<long long>* t) {
                    return t->key < l;
                    }
                    );
            split<long long>(rt, rt, y, [&] (node_t<long long>* t) {
                    return t->key <= r;
                    }
                    );
            insert<long long>(rt, l, 0);
            insert<long long>(rt, r, 0);
            long double res = query<long long>(rt, v, 0);
            if (res == -1) {
                cout << -1 << "\n";
            }
            else {
                cout << prec(9) << res << "\n";
            }
            rt = join(x, join(rt, y));
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}

#ifdef _LOCAL
//#include "debug.h"
#else
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("-O3")
//#pragma GCC optimize("Ofast")
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
#define sz(x) int(x.size())
#define all(x) x.begin(),x.end()
#define pii pair<int,int>
#define PB push_back
#define MP make_pair
#define pll pair<ll,ll>
#define pii pair<int,int>
#define pi3 pair<int,pll>
#define pl3 pair<ll,pll>
#define MP3(a,b,c) MP(a,MP(b,c))
#define F first
#define S second
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
template<class T>
using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
const int PW = 18;
const int N = 200100;
const int K = 10100;
const int oo = 2e9;
const ll OO = 1e18;
const int md = 998244353;
vector<int> vc;
vector<ll> vec;
map<int,int> mem;
int q,tp[N],t[N],l[N],r[N],vl[N],m,pr;
ld ans;
ll cur;
struct seg_tree{
    int l,r;
    ll mn,res;
};
seg_tree st[4*N];

inline seg_tree combine(seg_tree l,seg_tree r){
    seg_tree res;
    if (l.l==oo) return r;
    if (r.l==oo) return l;
    res.l=l.l; res.r=r.r;
    res.mn=l.mn;
    ll lbd=vc[l.r],rbd=vc[r.l],val=vec[l.r];
    res.mn=min(res.mn,l.res+(rbd-lbd)*val+r.mn);
    res.res=l.res+(rbd-lbd)*val+r.res;
    return res;
}

void build(int v,int l,int r){
    if (l==r) {
        st[v].l=st[v].r=st[v].mn=st[v].res=oo;
        return;
    }
    int md=(l+r)>>1;
    build(v+v,l,md);
    build(v+v+1,md+1,r);
    st[v]=combine(st[v+v],st[v+v+1]);
}

void update(int v,int l,int r,int ps,int val){
    if (l==r){
        if (val<oo){
            st[v].l=st[v].r=l;
            st[v].res=st[v].mn=0ll;
            vec[l]=val;
        } else {
            st[v].l=st[v].r=st[v].mn=st[v].res=oo;
        }
        return;
    }
    int md=(l+r)>>1;
    if (ps<=md)
        update(v+v,l,md,ps,val);
    else update(v+v+1,md+1,r,ps,val);
    st[v]=combine(st[v+v],st[v+v+1]);
}

void Real_Search(int v,int l,int r){
    if (l==r){
        ans=min(ans,ld(vc[l])+ld(cur)/ld(-vec[l]));
        return;
    }
    int md=(l+r)>>1;
    if (st[v+v].l==oo) {
        Real_Search(v+v+1,md+1,r); return;
    }
    if (st[v+v+1].l==oo){
        Real_Search(v+v,l,md); return;
    }
    if (cur+st[v+v].mn<=0){
        Real_Search(v+v,l,md); return;
    }
    ll lbd=vc[st[v+v].r],rbd=vc[st[v+v+1].l],val=vec[st[v+v].l];
    if (cur+st[v+v].res+(rbd-lbd)*val<=0){
        Real_Search(v+v,l,md); return;
    }
    cur+=st[v+v].res+(rbd-lbd)*val;
    Real_Search(v+v+1,md+1,r);
}

void Search(int v,int tl,int tr,int l,int r){
    if (ans<ld(OO)) return;
    if (l>r) return;
    if (tl==l && tr==r){
        if (st[v].l==oo) return;
        if (pr<oo){
            ll lbd=vc[pr],rbd=vc[st[v].l],val=vec[pr];
            if (cur+(rbd-lbd)*val<=0){
                ans=min(ans,ld(lbd)+ld(cur)/ld(-val)); return;
            }
            cur+=(rbd-lbd)*val;
        }
        pr=st[v].r;
        if (cur+st[v].mn<=0)
            Real_Search(v,l,r);
        else cur+=st[v].res;
        return;
    }
    int md=(tl+tr)>>1;
    Search(v+v,tl,md,l,min(r,md));
    Search(v+v+1,md+1,tr,max(md+1,l),r);
}

int main() {
#ifndef _LOCAL
//    freopen("fencing.in","r",stdin); freopen("fencing.out","w",stdout);
	ios_base::sync_with_stdio(0); cin.tie(0);
#else
	freopen("input.txt","r",stdin);
#endif
    cin>>q; vc.clear(); mem.clear();
    for (int i=0;i<q;i++){
        cin>>tp[i];
        if (tp[i]==1){
            cin>>t[i]>>vl[i]; vc.PB(t[i]);
        } else if (tp[i]==3){
            cin>>l[i]>>r[i]>>vl[i];
            vc.PB(l[i]); vc.PB(r[i]);
        } else {
            cin>>t[i]; vc.PB(t[i]);
        }
    }
    sort(all(vc));
    vc.resize(unique(all(vc))-vc.begin());
    vec.resize(sz(vc));
    m=sz(vc);
    for (int i=0;i<m;i++) mem[vc[i]]=i;
    build(1,0,m-1);
    for (int i=0;i<q;i++)
        if (tp[i]==1)
            update(1,0,m-1,mem[t[i]],vl[i]);
        else if (tp[i]==2)
            update(1,0,m-1,mem[t[i]],oo);
        else {
            ans=ld(OO); cur=vl[i]; pr=oo;
            if (vl[i]<=0) ans=l[i];
            int lft=lower_bound(all(vc),l[i])-vc.begin();
            int rgt=lower_bound(all(vc),r[i])-vc.begin();
            Search(1,0,m-1,lft,rgt);
            if (pr<oo && vec[pr]<0)
                ans=min(ans,ld(vc[pr])+ld(cur)/ld(-vec[pr]));
            if (ans<=r[i])
                cout<<fixed<<setprecision(10)<<ans<<'\n';
            else cout<<"-1\n";
        }
    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>

using namespace std;

const long long MAX_N = 1 << 18;

long long sum[2 * MAX_N];
long long minVal[2 * MAX_N];
long long posSum[2 * MAX_N];
long long value[2 * MAX_N];
map<int, int> M;

void update(long long node, long long low, long long high, long long nlow, long long nhigh, long long val) {
    if (nhigh < low || nlow > high) return;
    if (low >= nlow && high <= nhigh) {
        value[node] = val;
        sum[node] = (long long) val * (posSum[high + 1] - posSum[low]);
        if (val >= 0) {
            minVal[node] = 0;
        } else {
            minVal[node] = sum[node];
        }
        return;
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    update(node * 2 + 1, low, mid, nlow, nhigh, val);
    update(node * 2 + 2, mid + 1, high, nlow, nhigh, val);
    minVal[node] = min(minVal[node * 2 + 1], sum[node * 2 + 1] + minVal[node * 2 + 2]);
    sum[node] = sum[node * 2 + 1] + sum[node * 2 + 2];
}

double findPos(long long node, long long low, long long high, long long val) {
    if (low == high) {
        if (val == 0) return (double) posSum[low];
        if (value[node] >= 0) return -1.0;
        return posSum[low] + val / (double) (-value[node]);
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    if (-minVal[node * 2 + 1] >= val)
        return findPos(node * 2 + 1, low, (low + high) / 2, val);
    return findPos(node * 2 + 2, (low + high) / 2 + 1, high, val + sum[node * 2 + 1]);
}

pair<double, long long> get(long long node, long long low, long long high, long long nlow, long long nhigh, long long val) {
    if (nhigh < low || nlow > high) return {-1.0, 0};
    if (low >= nlow && high <= nhigh) {
        if (-minVal[node] >= val) {
            return {findPos(node, low, high, val), 0.0};
        }
        return {-1.0, sum[node]};
    }

    long long mid = (low + high) / 2;
    if (value[node] != -1000000001) {
        value[node * 2 + 1] = value[node];
        value[node * 2 + 2] = value[node];
        sum[node * 2 + 1] = (long long) value[node] * (posSum[mid + 1] - posSum[low]);
        sum[node * 2 + 2] = (long long) value[node] * (posSum[high + 1] - posSum[mid + 1]);
        if (value[node] >= 0) {
            minVal[node * 2 + 1] = 0;
            minVal[node * 2 + 2] = 0;
        } else {
            minVal[node * 2 + 1] = sum[node * 2 + 1];
            minVal[node * 2 + 2] = sum[node * 2 + 2];
        }
        value[node] = -1000000001;
    }

    auto res = get(node * 2 + 1, low, mid, nlow, nhigh, val);
    if (res.first > -0.5)
        return res;
    return get(node * 2 + 2, mid + 1, high, nlow, nhigh, res.second + val);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long q; cin >> q;
    vector<int> type(q);
    vector<int> a(q);
    vector<int> b(q);
    vector<int> c(q);
    vector<int> t; t.clear();
    for (long long i = 0; i < q; ++i) {
        cin >> type[i];
        if (type[i] == 1) cin >> a[i] >> b[i], t.push_back(a[i]);
        else if (type[i] == 2) cin >> a[i];
        else cin >> a[i] >> b[i] >> c[i], t.push_back(a[i]), t.push_back(b[i]);
    }

    sort(t.begin(), t.end());
    t.push_back(t.back() + 1);
    vector<int> nt = t;
    t.clear();
    for (long long i = 0; i < nt.size(); ++i)
        if (i == 0 || nt[i] != nt[i - 1])
            t.push_back(nt[i]);
    M.clear();
    for (long long i = 0; i < t.size(); ++i) {
        posSum[i] = t[i];
        M[t[i]] = i;
    }

    set<pair<int, int>> S; S.clear();
    S.insert({t.back(), 1e9});
    for (long long i = 0; i < q; ++i) {
        if (type[i] == 1) {
            auto it = S.lower_bound({a[i], 0});
            update(0, 0, MAX_N - 1, M[a[i]], M[(*it).first] - 1, b[i]);
            S.insert({a[i], b[i]});
        } else if (type[i] == 2) {
            auto it = S.lower_bound({a[i], -1e9 - 1});
            long long val = 0;
            if (it != S.begin()) {
                --it;
                val = (*it).second;
                ++it;
            }
            ++it;
            update(0, 0, MAX_N - 1, M[a[i]], M[(*it).first] - 1, val);
            --it;
            S.erase(it);
        } else {
            auto it = S.lower_bound({a[i], -1e9 -1});
            if (it == S.end() || (*it).first > b[i]) {
                cout << (c[i] == 0 ? a[i] : -1) << endl;
            } else {
                auto pos = get(0, 0, MAX_N - 1, M[(*it).first], M[b[i]], c[i]);
                printf("%.7lf\n", (pos.first > b[i] + 1e-6 ? -1.0 : pos.first));
            }
        }
    }

    return 0;
}

    #include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

#define pitem item*
#define tam 1023456
#define tamN 12345
using namespace std;
typedef long long ll;

typedef pair<ll,ll> ii;
typedef pair<int,ii> iii;
const ll INF=1e18;
struct item
{
    int prior,cnt;
    ll pos,speed,minn,tot;
    ii pos_viz;
    ii pos_vder;
    pitem l;
    pitem r;
    item(){}
    item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
    {
        prior=rand();
        minn=INF;
        pos_viz=pos_vder=ii(pos,speed);
    }

};
int cnt(pitem t){return t?t->cnt:0;}
ll gtot(pitem t){return t?t->tot:0;}
ll gmin(pitem t){return t?t->minn:INF;}

ll gextraiz(pitem t){
    if (!t|| (!(t->l)))
        return INF;
    else
        return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
}
ll gextrader(pitem t){
    if (!t|| !(t->r))
        return INF;
    return  (t->r->pos_viz.f-t->pos)*(t->speed);
}
void upd_cnt(pitem t)
{
    if (t)
    {
        t->cnt=cnt(t->l)+cnt(t->r)+1;
        ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
        t->tot=totiz;
        t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
        if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
        if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
        t->tot+=gtot(t->r);
        t->minn=gmin(t->l);
        t->minn=min(t->minn,totiz+extraiz);
        t->minn=min(t->minn,totiz+extraiz+extrader);
        t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
        if (t->tot!=0)
        t->minn=min(t->minn,t->tot);
    }
}
void split(pitem t,pitem &l,pitem &r,int key)
{
    if (!t)
        return void(l=r=0);
    if (t->pos>key)
        split(t->l,l,t->l,key),r=t;
    else
        split(t->r,t->r,r,key),l=t;
    upd_cnt(t);
}
void merge(pitem &t,pitem l,pitem r)
{
    if (!l||!r)
        t=l?l:r;
    else if (r->prior>l->prior)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd_cnt(t);
}
ll auxresp;
double respf;ll iz,der;
pitem ant_t;
bool print=false;
void query(pitem t,ll inival)
{

    if (t==0)
    {
        if (!ant_t)
            return void(auxresp=-1);

        // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
        ll extra;
        extra=(der-ant_t->pos)*(ant_t->speed);
        if (inival+extra<=0)
        {
            auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
            if ((inival)/(ant_t->speed)>0)
                cout<<"watultimo\n";
            respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
            return;
        }
        else
            return void(auxresp=-1);
    }
    ant_t=t;
    ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
    if (gmin(t->l)+inival<=0)
    {
        query(t->l,inival);
        // cout<<"go left\n";
    }
    else
    {
        ll extraiz,extrader,totiz;
        extraiz=(t->l)?gextraiz(t):0;
        extrader=(t->r)?gextrader(t):0;
        totiz=gtot(t->l);
        ll auxini=totiz+extraiz+extrader;
        // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
        if (totiz+extraiz+inival<=0)
        {
            inival+=totiz;
            auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
            if ((inival)/(t->l->pos_vder.s)>0)
                cout<<"watizquierda\n";
            respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
        }
        else if (totiz+extraiz+extrader+inival<=0)
        {
            inival+=totiz+extraiz;
            auxresp=(t->pos)-(inival)/(t->speed);//-.-
            if (inival/t->speed>0)
                cout<<"watderecha\n";
            respf=-(double)(inival%t->speed)/(t->speed);//-.-

        }
        else
            {

                // cout<<"go right\n";
                query(t->r,auxini+inival);
            }

    }
}

int main()
{
    int casos;
    scanf("%d",&casos);
    if (casos==100)
        print=1;
    int tipo;
    pitem t1;pitem t2;pitem t3;
    pitem s;
    pitem tree=new item(2e9,1);
    ll val,pos;
    double auxrespf;
    while(casos--)
    {
        scanf("%d",&tipo);
        if (tipo==1)
        {
            scanf("%lld %lld",&pos,&val);
            if (val==0)
            {
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
                continue;
            }
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            s=new item(pos,val);
            merge(tree,t1,s);
            merge(tree,tree,t3);
        }
        else if (tipo==2)
        {
            scanf("%lld",&pos);
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            merge(tree,t1,t3);
        }
        else if (tipo==3)
        {
            scanf("%lld %lld %lld",&iz,&der,&val);
            if (val==0)
            {
                printf("%lld.0\n",iz);
                continue;
            }
            split(tree,t1,t3,der);
            split(t1,t1,t2,iz-1);
            ant_t=NULL;
            query(t2,val);
            if (auxresp==-1)
                printf("-1\n");
            else
            {
                auxrespf=auxresp+respf;
                printf("%.9lf\n",auxrespf);
            }
            merge(tree,t1,t2);
            merge(tree,tree,t3);
        }
     //   inorder(tree);
        //// cout<<endl;
    }
}

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
	int x=0,w=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')w=0,ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
#define ll long long
const int N=1e5+5;

int ls[N],rs[N],tim[N],spd[N],tL[N],tR[N],spdR[N],rd[N],tot,rt;
ll res[N],mn[N];

void up(int x){
	tL[x]=tR[x]=tim[x];spdR[x]=spd[x];mn[x]=res[x]=0;
	if(ls[x]){
		tL[x]=tL[ls[x]];
		mn[x]=min(mn[x],mn[ls[x]]);
		res[x]+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
		mn[x]=min(mn[x],res[x]);
	}
	if(rs[x]){
		tR[x]=tR[rs[x]];spdR[x]=spdR[rs[x]];
		res[x]+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
		mn[x]=min(mn[x],res[x]+mn[rs[x]]);
		res[x]+=res[rs[x]];
		mn[x]=min(mn[x],res[x]);
	}
}
void split(int x,int k,int &a,int &b){
	if(!x){a=b=0;return;}
	if(tim[x]<=k)a=x,split(rs[x],k,rs[a],b),up(a);
	else b=x,split(ls[x],k,a,ls[b]),up(b);
}
int merge(int x,int y){
	if(!x||!y)return x|y;
	if(rd[x]<rd[y])return rs[x]=merge(rs[x],y),up(x),x;
	else return ls[y]=merge(x,ls[y]),up(y),y;
}

double query(int x,int r,ll v){
	if(!x)return -1;
//	printf("v=%lld\n",v);
	if(ls[x]){
		if(v+mn[ls[x]]<=0)return query(ls[x],tim[x],v);
		v+=res[ls[x]]+1ll*spdR[ls[x]]*(tim[x]-tR[ls[x]]);
//		printf("v=%lld\n",v);
		if(v<=0)return tim[x]-1.0*v/spdR[ls[x]];
	}
	if(rs[x]){
		v+=1ll*spd[x]*(tL[rs[x]]-tim[x]);
//		printf("v=%lld\n",v);
		if(v<=0)return tL[rs[x]]-1.0*v/spd[x];
		if(v+mn[rs[x]]<=0)return query(rs[x],r,v);
		v+=res[rs[x]];
	}
	v+=1ll*spdR[x]*(r-tR[x]);
//	printf("v=%lld\n",v);
	if(v<=0)return r-1.0*v/spdR[x];
	return -1;
}

void dfs(int x){
	if(ls[x])dfs(ls[x]);
	printf("x=%d tim[x]=%d spd[x]=%d tL[x]=%d tR[x]=%d spdR[x]=%d mn[x]=%lld res[x]=%lld\n",x,tim[x],spd[x],tL[x],tR[x],spdR[x],mn[x],res[x]);
	if(rs[x])dfs(rs[x]);
}

int main(){
	int q=gi();while(q--){
		int op=gi();
		if(op==1){
			tim[++tot]=gi();spd[tot]=gi();rd[tot]=rand()*rand();
			int x,y;split(rt,tim[tot],x,y);
			rt=merge(x,merge(tot,y));
		}else if(op==2){
			int t=gi(),x,y,z;
			split(rt,t,x,z);split(x,t-1,x,y);
			rt=merge(x,z);
		}else{
			int l=gi(),r=gi(),v=gi(),x,y,z;
			if(!v){printf("%d\n",l);continue;}
			split(rt,r,x,z);split(x,l-1,x,y);
//			dfs(y);
//			if(!y||v+min(mn[y],res[y]+1ll*spdR[y]*(r-tR[y]))>0)puts("-1");
//			else
				printf("%.6lf\n",query(y,r,v));
			rt=merge(x,merge(y,z));
		}
	}
	return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q,st,tcnt,jeste;
ll inf=3e18;
mt19937 gen(500);
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void upd(pnode x){
    if(x==NULL)return;
    x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
}
void ispis(pnode x,int &ct){

    if(ct<1)return;
    if(x==NULL)return;
    push(x);

    ispis(x->l,ct);
    ct--;
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r,ct);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);

    if(get_mn(x->l)<=val)qry(x->l,val,tm);
    else if(x->val<=val){
        tm=x->t;
        if(jeste)cout<<x->val<<" "<<val<<" "<<x->t<<" EVEGGAA\n";
        return;
    }
    else qry(x->r,val,tm);
}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    if(midtree==NULL){ret=-1;}
    else{

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        /*if(jeste){
            printf("\n\nISPIS A\n");
            int pm=12;
            ispis(midtree,pm);
            printf("\n");
        }*/

        /// mozda vamo bude greska ako nema proslog
        int tm=0;
        if(jeste)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;

            last_node(midtree,lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);
            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-(!jeste));

            ///printf("%d TMTM\n",tm);

            pnode lst=NULL;
            last_node(pom1,lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            if(jeste)cout<<zero<<" "<<lst->val<<" "<<lst->s<<" "<<lst->t<<" "<<l<<" "<<r<<" EVOGA\n";

            mrg(midtree,pom1,pom2);
        }
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    st=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(st==0)st=t;
            ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            del(t);
        }
        else{
            int l,r,v;
            tcnt++;
            scanf("%d %d %d",&l,&r,&v);
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            if(sq==100000 && st==940132043){

             if(tcnt==2846){
                jeste=1;
                printf("NASAO\n");
                cout<<fixed;
                cout<<setprecision(6);
                cout<<query(l,r,v)<<endl;
             }
            }
            else{
                cout<<fixed;
                cout<<setprecision(6);
                cout<<query(l,r,v)<<endl;
            }
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;const int N=2*1e5+10;typedef long long ll;typedef double db;
struct data
{
	ll k;ll b;ll mi;int st;int ed;
	inline ll f(ll t){return k*t+b;}
	inline db ctim(ll fr){return (double)(-b-fr)/k;}
	friend data operator +(data a,data b)
	{
		ll fv=a.f(b.st);data c;c.k=b.k;c.b=b.b+fv;
		c.mi=min(a.mi,b.mi+fv);c.st=a.st;c.ed=b.ed;return c;
	}friend bool operator <(data a,data b){return a.st<b.st;}
	friend bool operator <(data a,int b){return a.st<b;}
};struct splaytree
{
	int s[N][2];int fa[N];data v[N];data sum[N];int ct;int rot;
	splaytree()
	{
		v[1]=(data){0,0,0,-0x3f3f3f3f};v[2]=(data){0,0,0,0x3f3f3f3f};
		s[2][0]=1;fa[1]=2;ct=rot=2;sum[2]=v[1]+v[2];
	}inline int gc(int x){return s[fa[x]][1]==x;}
	inline void ud(int p)
	{
		if(s[p][0])sum[p]=sum[s[p][0]]+v[p];else sum[p]=v[p];
		if(s[p][1])sum[p]=sum[p]+sum[s[p][1]];
	}inline void rt(int x)
	{
		int d=fa[x];int t=gc(x);s[d][t]=s[x][t^1];fa[s[x][t^1]]=d;
		s[fa[d]][gc(d)]=x;fa[x]=fa[d];s[x][t^1]=d;fa[d]=x;ud(d);ud(x);
	}inline void rtup(int x){rt((gc(x)^gc(fa[x]))?x:fa[x]);rt(x);}
	inline void splay(int x,int nod=0)
	{
		for(;fa[x]!=nod&&fa[fa[x]]!=nod;rtup(x));
		if(fa[x]!=nod)rt(x);if(nod==0)rot=x;
	}inline void ins(data ke)
	{
		int p=rot;for(;s[p][v[p]<ke];p=s[p][v[p]<ke]);
		v[++ct]=ke;sum[ct]=ke;s[p][v[p]<ke]=ct;fa[ct]=p;splay(ct);
	}inline void del(int ke)
	{
		int p=rot;for(;s[p][v[p]<ke];p=s[p][v[p]<ke])if(v[p].st==ke)break;
		splay(p);int sub=s[p][0];for(;s[sub][1];sub=s[sub][1]);
		splay(sub);s[sub][1]=s[p][1];fa[s[p][1]]=sub;ud(sub);
	}inline int pres(int ke)
	{
		int res=1;
		for(int p=rot;p;)if(v[p].st<=ke)res=p,p=s[p][1];else p=s[p][0];
		return res;
	}inline int succ(int ke)
	{
		int res=2;
		for(int p=rot;p;)if(v[p].st<ke)p=s[p][1];else res=p,p=s[p][0];
		return res;
	}inline int split(int l,int r)
	{splay(pres(l-1));int nw;splay(nw=succ(r+1),rot);return s[nw][0];}
	inline db qry(int p,ll fr)
	{
		if(s[p][0])
		{
			if(sum[s[p][0]].mi+fr<=0)return qry(s[p][0],fr);
			db ret1=sum[s[p][0]].ctim(fr);
			if(sum[s[p][0]].ed<=ret1&&ret1<=v[p].st)return ret1;
		}data fuc;
		if(s[p][0])fuc=sum[s[p][0]]+v[p];else fuc=v[p];
		db lim=(s[p][1])?sum[s[p][1]].st:0x3f3f3f3f;
		db ret1=fuc.ctim(fr);
		if(v[p].ed<=ret1&&ret1<=lim)return ret1;
		if(s[p][1])
			return qry(s[p][1],fr+fuc.f(fuc.st));
		return v[p].ctim(fr);
	}
	inline void cqry(int l,int r,int fr)
	{
		int nw=split(l,r);
		if(fr==0){printf("%d\n",l);return;}
		if(nw==0){printf("-1\n");return;}
		db tim=sum[nw].ctim(fr);
		if(sum[nw].mi+fr>0&&(tim<sum[nw].ed||tim>r))printf("-1\n");
		else printf("%.10lf\n",qry(nw,fr));
	}
}spt;int q;
int main()
{
	scanf("%d",&q);
	for(int i=1,tp,tim,sec,l,r;i<=q;i++)
	{
		scanf("%d",&tp);
		switch (tp)
		{
			case 1:
			{
				scanf("%d%d",&tim,&sec);
				data nw=(data){sec,-(ll)tim*sec,0,tim,tim};
				spt.ins(nw);break;
			}
			case 2:{scanf("%d",&tim);spt.del(tim);break;}
			case 3:{scanf("%d%d%d",&l,&r,&tim);spt.cqry(l,r,tim);break;}
		}
	}return 0;
}

#include<bits/stdc++.h>
#define mid (l+r>>1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int mn = 1e5+10;
int aa[mn], bb[mn], cc[mn], dd[mn];
vector<int>use;
map<int, int> m;
int siz(int x) {
	return use[x + 1] - use[x];
}
ll seg[1<<20], laz[1<<20],lo[1<<20];
void prop(int x, int l, int r) {
	if (laz[x] == 0x3f3f3f3f3f3f3f3f)return;
	seg[x] = laz[x] * (use[r + 1] - use[l]);
	lo[x] = min(0LL, seg[x]);
	if (x < 1 << 19) {
		laz[x * 2] = laz[x];
		laz[x * 2 + 1] = laz[x];
	}
	laz[x] = 0x3f3f3f3f3f3f3f3f;
}
void calc(int x, int l, int r) {
	prop(x * 2, l, mid);
	prop(x * 2 + 1, mid + 1, r);
	seg[x] = seg[x * 2] + seg[x * 2 + 1];
	lo[x] = min(lo[x * 2], lo[x * 2 + 1] + seg[x * 2]);
}
void update(int x, int l, int r, int a, int b, ll c) {
	if (a == l && b == r) {
		laz[x] = c;
	}
	else {
		prop(x, l, r);
		if (b <= mid)update(x * 2, l, mid, a, b, c);
		else if (a > mid)update(x * 2 + 1, mid + 1, r, a, b, c);
		else update(x * 2, l, mid, a, mid, c), update(x * 2 + 1, mid + 1, r, mid + 1, b, c);
		calc(x, l, r);
	}
}
ll val(int x, int l, int r, int a, int b) {
	if (b < a)return 0;
	prop(x, l, r);
	if (a == l && b == r)return seg[x];
	else {
		if (b <= mid)return val(x * 2, l, mid, a, b);
		else if (a > mid)return val(x * 2 + 1, mid + 1, r, a, b);
		else return val(x * 2, l, mid, a, mid) + val(x * 2 + 1, mid + 1, r, mid + 1, b);
	}
}
long double query(int x, int l, int r,int a,ll c) {
	prop(x, l, r);
	prop(x * 2, l, mid);
	if (l == r) {
		if (c >= 0)return 0;
		ll rate = (seg[x] / siz(l));
		long double ans = 1.0L*c /rate ;
		if (rate>=0)return siz(l);
		return min(0.0L + siz(l),ans );
	}

	if (lo[x*2]>c||a>mid)return 0.0L+use[mid + 1] - use[l] + query(x * 2 + 1, mid + 1, r,a, c - seg[x * 2]);
	else {
		long double th;
		th = query(x * 2, l, mid, a, c);
		if(th+use[l]==use[mid+1])return th+ query(x * 2 + 1, mid + 1, r, mid+1, c - seg[x * 2]);
		else return th;
	}
}
ll s[3 * mn];
int main() {
	int n,i;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d%d", aa + i, bb + i);
		if (aa[i] == 1)scanf("%d", cc + i);
		if (aa[i] == 3)scanf("%d%d",cc+i, dd + i);
		use.push_back(bb[i]);
		if(aa[i]==3)use.push_back(cc[i]);
	}
	use.push_back(0x7fffffff);
	use.push_back(0);
	sort(use.begin(), use.end());
	use.resize(distance(use.begin(), unique(use.begin(), use.end())));
	for (i = 1; i < use.size(); i++)m[use[i]] = i;
	set<int> tms;
	tms.insert(0);
	int tot = use.size()-2;
	tms.insert(tot+1);
	memset(laz, 0x3f, sizeof(laz));
	for (i = 0; i < n; i++) {
		if (aa[i] == 1) {
			ll t = m[bb[i]];
			set<int>::iterator it = tms.upper_bound(t);
			update(1, 1, tot, t, (*it) - 1, cc[i]);
			tms.insert(t);
			s[t] = cc[i];
		}
		else if (aa[i] == 2) {
			ll t = m[bb[i]];
			set<int>::iterator it = --tms.find(t),it2=tms.upper_bound(t);
			update(1, 1, tot, t, (*it2) - 1, s[*it]);
			tms.erase(t);
			s[t] = 0;
		}
		else {
			set<int>::iterator it = tms.lower_bound(m[bb[i]]);
			ll add = val(1, 1, tot, 1,(*it) - 1);
			long double ans = query(1, 1, tot,*it,add-dd[i])+use[1];
			if (ans>cc[i]+1e-15)printf("-1\n");
			else printf("%.10Lf\n", ans);
		}
	}
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <stdio.h>
#include <math.h>
#include <stack>
#include <queue>
#include <tuple>

#define forn(i,n) for(int i=0;i<n;i++)
#define ll long long
#define ld long double
#define mp make_pair

using namespace std;

const ll INF = 1e18;
const ld eps = 1e-8;

struct node {
	ll x, y = rand() << 16 + rand();
	ll speed = 0, tL = INF, tR = -INF, speedR = 0, res = 0, mn = 0;
	node*l = NULL, *r = NULL;
	node() {};
	node(ll x, ll speed) :x(x), tL(x), tR(x), speed(speed), speedR(speed) {};
};

node* safe(node*a,ll x,ll speed) {
	return a == NULL ? new node(x,speed) : a;
}

void recalc(node*a) {
	if (a == NULL)return;
	node*nl = safe(a->l,a->x,0), *nr = safe(a->r,a->x,a->speed);
	a->tL = min(a->x, nl->tL);
	a->tR = max(nr->tR, a->x);
	a->speedR = nr->speedR;
	ll mn = 0, res = 0;
	mn = min(mn, nl->mn);
	res += nl->res + nl->speedR*(a->x - nl->tR);
	mn = min(mn, res);
	res += a->speed*(nr->tL - a->x);
	mn = min(mn, res + nr->mn);
	res += nr->res;
	mn = min(mn, res);
	a->mn = mn;
	a->res = res;
}

node*merge(node*a, node*b) {
	if (a == NULL) {
		return b;
	}
	if (b == NULL) {
		return a;
	}
	if (a->y > b->y) {
		a->r = merge(a->r, b);
		recalc(a);
		return a;
	}
	b->l = merge(a, b->l);
	recalc(b);
	return b;
}

pair<node*, node*>split(node*a, ll x) {
	if (a == NULL) {
		return mp(a, a);
	}
	if (a->x < x) {
		pair<node*, node*>t = split(a->r, x);
		a->r = t.first;
		t.first = a;
		recalc(a);
		return t;
	}
	pair<node*, node*>t = split(a->l, x);
	a->l = t.second;
	t.second = a;
	recalc(a);
	return t;
}

void add(node*&a, ll x, ll speed) {
	pair<node*, node*>t = split(a, x);
	pair<node*, node*>t1 = split(t.second, x + 1);
	t1.first = new node(x, speed);
	t.second = merge(t1.first, t1.second);
	a = merge(t.first, t.second);
}

void del(node*&a, ll x) {
	pair<node*, node*>t = split(a, x);
	pair<node*, node*>t1 = split(t.second, x + 1);
	a = merge(t.first, t1.second);
}

ld go_down(node*a, ll v, ll r) {
	if (a == NULL)return (v==0?0:-1);
	node*nl = safe(a->l, a->x, a->speed), *nr = safe(a->r, a->x, a->speed);
	ll mn = 0, res = 0;
	mn = min(mn, nl->mn);
	if (mn + v <= 0)return go_down(a->l, v,r);
	res += nl->res + nl->speedR*(a->x - nl->tR);
	mn = min(mn, res);
	if (mn + v <= 0)return a->x-(((ld)mn+v)/nl->speedR);
	res += a->speed*(nr->tL - a->x);
	if (res + v <= 0)return nr->tL-(((ld)res+v)/a->speed);
	if (res + nr->mn + v > 0) {
		if (a->speedR < 0) {
			ld ac = a->tR - ((ld)res + nr->res + v) / a->speedR;
			if (ac <= r)return ac;
		}
		return -1;
	}
	return go_down(a->r, res + v,r);
}

ld get(node*a, ll l, ll r, ll v) {
	if (a == NULL)return (v==0?l:-1);
	pair<node*, node*>t = split(a, l);
	pair<node*, node*>t1 = split(t.second, r+1);
	ll sp = safe(t.first, l, 0)->speedR;
	ll tl = safe(t1.first, r, 0)->tL;
	ll mn = min(v, v + sp*(tl - l));
	if (mn <= 0) {
		if (sp == 0)sp = 1;
		t.second = merge(t1.first, t1.second);
		a = merge(t.first, t.second);
		return l - (ld)v / sp;
	}
	ld ans = go_down(t1.first, v + sp*(tl - l), r);
	t.second = merge(t1.first, t1.second);
	a = merge(t.first, t.second);
	return ans;
}

int main() {
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	int q;
	cin >> q;
	node*a = NULL;
	forn(i, q) {
		int type;
		cin >> type;
		if (type == 1) {
			ll t, s;
			cin >> t >> s;
			add(a, t, s);
		}
		else if (type == 2) {
			ll t;
			cin >> t;
			del(a, t);
		}
		else {
			ll l, r, v;
			cin >> l >> r >> v;
			cout.precision(20);
			printf("%.7f\n", (double)get(a, l, r, v));
		}
	}
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#define int long long
#define pii pair<int, int>
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define endl "\n"
//#pragma GCC optimize ("O3")

using namespace std;

const int N = 1e6 + 10;
const int inf = 2e18;
const int mod = 1e9 + 7;
const int eps = 1e-9;
const char spc = 29;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

struct node {
	int key = 0;
	int prir = rnd();
	int speed = 0;
	int mxt = -inf;
	int mnt = inf;
	int mxtspeed = 0;
	int res = 0;
	int mn = 0;
	int l = -1, r = -1;
};

node t[N];
int top = 0;
int rt = -1;
set<int> st;
vector<pair<pii, pii>> qv;

void upd(int nd)
{
	if (nd == -1)
		return;

	node l;
	node r;

	if (t[nd].l != -1)
		l = t[t[nd].l];

	if (t[nd].r != -1)
		r = t[t[nd].r];

	t[nd].mxt = max(t[nd].key, r.mxt);
	t[nd].mnt = min(t[nd].key, l.mnt);

	if (r.mxt > t[nd].key)
		t[nd].mxtspeed = r.mxtspeed;
	else
		t[nd].mxtspeed = t[nd].speed;

	t[nd].mn = 0;
	t[nd].res = l.res;
	t[nd].mn = min(t[nd].mn, t[nd].res);

	if (l.mxt != -inf)
		t[nd].res += abs(t[nd].key - l.mxt) * l.mxtspeed;

	t[nd].mn = min(t[nd].mn, t[nd].res);

	if (r.mnt != inf)
		t[nd].res += abs(r.mnt - t[nd].key) * t[nd].speed;

	t[nd].mn = min(t[nd].mn, t[nd].res);
	t[nd].res += r.res;
	t[nd].mn = min(t[nd].mn, t[nd].res);
}

int merge(int l, int r)
{
	if (l == -1) return r;
	if (r == -1) return l;

	if (t[l].prir > t[r].prir)
	{
		t[l].r = merge(t[l].r, r);
		upd(l);
		return l;
	}
	else
	{
		t[r].l = merge(l, t[r].l);
		upd(r);
		return r;
	}
}

pii split(int nd, int key)
{
	if (nd == -1)
		return make_pair(-1, -1);

	if (t[nd].key <= key)
	{
		pii p = split(t[nd].r, key);

		t[nd].r = p.x;
		upd(p.x);
		upd(nd);
		upd(p.y);

		return make_pair(nd, p.y);
	}
	else
	{
		pii p = split(t[nd].l, key);

		t[nd].l = p.y;
		upd(p.y);
		upd(nd);
		upd(p.x);

		return make_pair(p.x, nd);
	}
}

void init(node &nd, int key, int speed)
{
	nd.key = key;
	nd.speed = speed;
	nd.mxt = key;
	nd.mnt = key;
	nd.mxtspeed = speed;
	nd.l = -1;
	nd.r = -1;
	nd.res = 0;
	nd.mn = 0;
}

void add(int pos, int val)
{
	init(t[top], pos, val);
	upd(top);

	pii p = split(rt, pos);

	rt = merge(merge(p.x, top), p.y);

	++top;
}

void del(int pos)
{
	pii p1 = split(rt, pos);
	pii p2 = split(p1.x, pos - 1);

	rt = merge(p2.x, p1.y);
}

double rec(int nd, int have)
{
	if (nd == -1)
		return -1;

	upd(nd);

	if (t[nd].mn + have > 0)
		return -1;

	double res = rec(t[nd].l, have);

	if (res > -0.5)
		return res;

	if (t[nd].l != -1)
		have += t[t[nd].l].res;

	if (have <= 0)
	{
		if (t[nd].l != -1)
			return t[t[nd].l].mxt;

		return t[nd].key;
	}

	if (t[nd].l != -1)
	{
		if (have + abs(t[nd].key - t[t[nd].l].mxt) * t[t[nd].l].mxtspeed <= 0)
			return (double)t[t[nd].l].mxt + abs((double)have / (double)t[t[nd].l].mxtspeed);

		have += abs(t[nd].key - t[t[nd].l].mxt) * t[t[nd].l].mxtspeed;
	}

	if (t[nd].r != -1)
	{
		if (have + abs(t[t[nd].r].mnt - t[nd].key) * t[nd].speed <= 0)
			return (double)t[nd].key + abs((double)have / (double)t[nd].speed);

		have += abs(t[t[nd].r].mnt - t[nd].key) * t[nd].speed;
	}

	res = rec(t[nd].r, have);

	if (res > -0.5)
		return res;

	assert(1 != 1);
}

double get(int l, int r, int have)
{
	pii p1 = split(rt, l - 1);
	pii p2 = split(p1.y, r);
	int seg = p2.x;

	int cur = have;

	if (have == 0)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return l;
	}

	double res = rec(seg, cur);

	if (res > -0.5)
	{
		rt = merge(p1.x, merge(p2.x, p2.y));
		return res;
	}
	/*
	int start = t[seg].mxt;
	cur += t[seg].res;

	if (cur <= 0)
		return t[seg].mxt;

	int add = abs(r - start) * t[seg].mxtspeed;

	if (cur + add <= 0)
	{
		double res = (double)start + abs((double)cur / (double)t[seg].mxtspeed);
		rt = merge(p1.x, merge(p2.x, p2.y));

		return res;
	}*/

	rt = merge(p1.x, merge(p2.x, p2.y));
	return -1;
}

int q;

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cout.precision(7);

	cin >> q;

	while (q--)
	{
		int tp;

		cin >> tp;

		if (tp == 1)
		{
			int tm, speed;

			cin >> tm >> speed;

			add(tm, speed);
			st.insert(tm);
		}
		else if (tp == 2)
		{
			int tm;

			cin >> tm;

			del(tm);
			st.erase(tm);
		}
		else
		{
			int l, r, have;

			cin >> l >> r >> have;

			if (st.find(l) == st.end())
				add(l, 0);

			if (st.find(r) == st.end())
				add(r, 0);

			cout << get(l, r, have) << endl;

			if (st.find(l) == st.end())
				del(l);

			if (st.find(r) == st.end())
				del(r);
		}
	}
}

#include<bits/stdc++.h>
using namespace std;
#define mid (l+r)/2
const long long maxn=500005;
long long i,i0,n,m;
long long d[maxn];
struct node
{
    long long siz,v,sum,mp;
}tree[maxn*4];
node operator+(node a,node b)
{
    node c;
    c.siz=a.siz+b.siz;
    c.v=(a.v==b.v)?a.v:-1;
    c.sum=a.sum+b.sum;
    c.mp=min(a.mp,a.sum+b.mp);
    return c;
}
void b_tree(long long l,long long r,long long p)
{
    if(l==r)tree[p]={d[l],0,0,0};
    else
    {
        b_tree(l,mid,p*2),b_tree(mid+1,r,p*2+1);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
void p_tree(long long p)
{
    if(tree[p].v==-1)return;
    tree[p*2]={tree[p*2].siz,tree[p].v,tree[p*2].siz*tree[p].v,min(0ll,tree[p*2].siz*tree[p].v)};
    tree[p*2+1]={tree[p*2+1].siz,tree[p].v,tree[p*2+1].siz*tree[p].v,min(0ll,tree[p*2+1].siz*tree[p].v)};
    tree[p].v=-1;
}
void c_tree(long long l,long long r,long long p,long long a,long long b,long long v)
{
    if(l==a&&r==b)tree[p]={tree[p].siz,v,tree[p].siz*v,min(0ll,tree[p].siz*v)};
    else
    {
        p_tree(p);
        if(b<=mid) c_tree(l,mid,p*2,a,b,v);
        else if(a>=mid+1)c_tree(mid+1,r,p*2+1,a,b,v);
        else c_tree(l,mid,p*2,a,mid,v),c_tree(mid+1,r,p*2+1,mid+1,b,v);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
long long q_tree(long long l,long long r,long long p,long long a)
{
    if(l==r)return tree[p].v;
    else
    {
        p_tree(p);
        if(a<=mid)return q_tree(l,mid,p*2,a);
        else return q_tree(mid+1,r,p*2+1,a);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
long long gsz;
double q0_tree(long long l,long long r,long long p,long long a,long long b,long long v)
{
    double ans=1e9+7;
    if(l==a&&r==b)
    {
        if(l!=r)p_tree(p);
        if(v+tree[p].mp+gsz<=0)
        {
            if(l!=r)
            {
                ans=q0_tree(l,mid,p*2,l,mid,v);
                if(ans>1e9+6)ans=tree[p*2].siz+q0_tree(mid+1,r,p*2+1,mid+1,r,v);
            }
            else
            {
                if(v+gsz==0)ans=0;
                else ans=(double)(-v-gsz)/tree[p].v;
            }
        }
        else gsz+=tree[p].sum;
        if(l!=r)tree[p]=tree[p*2]+tree[p*2+1];
    }
    else
    {
        p_tree(p);
        if(b<=mid)ans=q0_tree(l,mid,p*2,a,b,v);
        else if(a>=mid+1)ans=tree[p*2].siz+q0_tree(mid+1,r,p*2+1,a,b,v);
        else
        {
            ans=q0_tree(l,mid,p*2,a,mid,v);
            if(ans>1e9+6)ans=tree[p*2].siz+q0_tree(mid+1,r,p*2+1,mid+1,b,v);
        }
        tree[p]=tree[p*2]+tree[p*2+1];
    }
    return ans;
}
struct op
{
    long long op,t,l,r;
    long long v,s;
}a[100005];
vector<long long>v;
void cal(long long &t){t=lower_bound(v.begin(),v.end(),t)-v.begin()+1;}
set<long long>s;
int main()
{
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i].op);
        if(a[i].op==1)scanf("%d %lld",&a[i].t,&a[i].s),v.push_back(a[i].t);
        if(a[i].op==2)scanf("%d",&a[i].t),v.push_back(a[i].t);
        if(a[i].op==3)scanf("%d %d %lld",&a[i].l,&a[i].r,&a[i].v),v.push_back(a[i].l),v.push_back(a[i].r);
    }
    v.push_back(0),v.push_back((long long)1e9+7);
    sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
    long long ll=0,rr=v.size();
    d[ll]=d[rr]=0;
    for(i=1;i<v.size();i++)d[i]=v[i]-v[i-1];
    b_tree(ll,rr,1);
    s.insert(ll),s.insert(rr);
    for(i=1;i<=n;i++)
    {
        if(a[i].op==1)
        {
            cal(a[i].t);
            auto it=s.upper_bound(a[i].t);
            c_tree(ll,rr,1,a[i].t,*it-1,a[i].s);
            s.insert(a[i].t);
        }
        if(a[i].op==2)
        {
            cal(a[i].t);
            auto it=s.upper_bound(a[i].t);
            a[i].r=*it,a[i].l=*(----it);
            a[i].s=q_tree(ll,rr,1,a[i].l);
            c_tree(ll,rr,1,a[i].l,a[i].r-1,a[i].s);
            s.erase(a[i].t);
        }
        if(a[i].op==3)
        {
            gsz=0;
            double r=a[i].r;
            cal(a[i].l),cal(a[i].r);
            auto it=s.lower_bound(a[i].l);
            long long rx=*it,lx=*(--it);
            a[i].s=q_tree(ll,rr,1,lx);
            c_tree(ll,rr,1,lx,rx-1,0);
            double ans=q0_tree(ll,rr,1,a[i].l,a[i].r,a[i].v);
            c_tree(ll,rr,1,lx,rx-1,a[i].s);
            if(ans>r)printf("-1\n");
            else printf("%.10f\n",ans);
        }
    }
    return 0;
}

#include<bits/stdc++.h>

using namespace std;

//const int NMAX = 100;
const int NMAX = 350009;

int Q, N, currentS[NMAX], s[NMAX], t[NMAX], l[NMAX], r[NMAX], v[NMAX], type[NMAX];
vector < int > ts;
map < int, int > inverseT;

void read ()
{
    scanf ("%d", &Q);
    for (int i=1; i<=Q; i++)
    {
        scanf ("%d", &type[i]);
        if (type[i] == 1) scanf ("%d %d", &t[i], &s[i]), ts.push_back (t[i]);
        else
        if (type[i] == 2) scanf ("%d", &t[i]);
        else
        {
            scanf ("%d %d %d", &l[i], &r[i], &v[i]);
            ts.push_back (l[i]), ts.push_back (r[i]);
        }
    }
    sort (ts.begin (), ts.end ());
    ts.erase (unique (ts.begin (), ts.end ()), ts.end ()), N = ts.size ();
/*    for (auto it : ts)
        printf ("%d\n", it);*/
    for (int i=0; i<N; i++)
        inverseT[ts[i]] = i + 1;
    int lastVal = ts[N - 1];
    ts.push_back (lastVal);
    for (int i=1; i<=Q; i++)
        if (type[i] <= 2) t[i] = inverseT[t[i]];
        else l[i] = inverseT[l[i]], r[i] = inverseT[r[i]];
}

set < int > currTimes;
long long sum[4 * NMAX], mi[4 * NMAX];
int vl[4 * NMAX];
bool lzy[4 * NMAX];

int getLength (int x, int y) {return ts[y] - ts[x - 1];}

void split (int nod, int st, int mij, int dr, int f1, int f2)
{
    if (lzy[nod] == 0) return ;
    lzy[f1] = lzy[f2] = 1;
    vl[f1] = vl[f2] = vl[nod];
    sum[f1] = 1LL * vl[nod] * getLength (st, mij);
    mi[f1] = min (0LL, sum[f1]);
    sum[f2] = 1LL * vl[nod] * getLength (mij + 1, dr);
    mi[f2] = min (0LL, sum[f2]);
    lzy[nod] = 0;
}

void setValue (int nod, int st, int dr, int x, int y, int s)
{
/*    if (nod == 1)
        printf ("set %d [%d, %d]\n", s, x, y);*/
    if (x <= st && dr <= y)
    {
        vl[nod] = s, lzy[nod] = 1;
        sum[nod] = 1LL * s * getLength (st, dr);
        mi[nod] = min (0LL, sum[nod]);
        return ;
    }
    int mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    split (nod, st, mij, dr, f1, f2);
    if (x <= mij) setValue (f1, st, mij, x, y, s);
    if (mij < y) setValue (f2, mij + 1, dr, x, y, s);
    sum[nod] = sum[f1] + sum[f2];
    mi[nod] = min (mi[f1], sum[f1] + mi[f2]);
}

long double ansQ = -1.0;
long long curr;
void query (int nod, int st, int dr, int x, int y)
{
    if (ansQ > -0.5)
        return ;
    if (x <= st && dr <= y)
    {
        int mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
        if (st == dr)
        {
            if (mi[nod] + curr > 0)
            {
                curr += sum[nod];
                return ;
            }
            int t1 = ts[st - 1], t2 = ts[st];
            assert (vl[nod] < 0);
            ansQ = t1 + 1.0 * curr / (-vl[nod]);
            assert (ansQ > -0.5);
            return ;
        }
        split (nod, st, mij, dr, f1, f2);
        if (curr + mi[f1] <= 0)
        {
            query (f1, st, mij, x, y);
            assert (ansQ > -0.5);
        }
        else
        if (curr + sum[f1] + mi[f2] <= 0)
        {
            curr += sum[f1], query (f2, mij + 1, dr, x, y);
            assert (ansQ > -0.5);
        }
        else curr += sum[nod];
        return ;
    }
    int mij = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    split (nod, st, mij, dr, f1, f2);
    if (x <= mij) query (f1, st, mij, x, y);
    if (mij < y) query (f2, mij + 1, dr, x, y);
}

int main ()
{
//freopen ("input", "r", stdin);
//freopen ("output", "w", stdout);

read ();
for (int i=1; i<=Q; i++)
{
    if (type[i] == 1)
    {
        currTimes.insert (t[i]);
        auto it = currTimes.find (t[i]); it ++;
        int rgt = N;
        if (it != currTimes.end ()) rgt = (*it) - 1;
        setValue (1, 1, N, t[i], rgt, s[i]);
        currentS[t[i]] = s[i];
        continue;
    }
    if (type[i] == 2)
    {
        auto it = currTimes.find (t[i]);
        int s = 0;
        if (it != currTimes.begin ())
        {
            auto it2 = it;
            it2 --; s = currentS[*it2];
        }
        it ++;
        int rgt = N;
        if (it != currTimes.end ()) rgt = (*it) - 1;
        setValue (1, 1, N, t[i], rgt, s);
        currTimes.erase (t[i]), currentS[t[i]] = 0;
        continue;
    }
    ansQ = -1.0;
    if (v[i] == 0)
    {
        printf ("%d\n", ts[l[i] - 1]);
        continue;
    }
    if (l[i] != r[i])
        curr = v[i], query (1, 1, N, l[i], r[i] - 1);
    cout << setprecision (15) << ansQ << '\n';
}
return 0;
}

/*

    idea:

*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ff first
#define ss second
#define ll long long
typedef pair<int,int> pii;
int q;
ll inf=3e18;
mt19937 gen(time(NULL));
struct node{
    ll mn,t,val,rval,lazy,s;
    node *l,*r;
    node(){}
    node(ll mn,ll t,ll s,ll val,node *l,node *r){
        this->mn=mn;
        this->t=t;
        this->val=val;
        this->l=l;
        this->r=r;
        this->rval=gen();
        this->lazy=0;
        this->s=s;
    }
};
typedef node* pnode;
int sq;
pnode root;
ll get_val(pnode x){
    if(x==NULL)return inf;
    return x->val;
}
void push(pnode x){

    if(x==NULL)return;

    pnode l=x->l;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    l=x->r;
    if(l!=NULL){
        l->lazy+=x->lazy;
        l->val+=x->lazy;
        l->mn+=x->lazy;
    }

    x->lazy=0;
}
void upd(pnode x){
    if(x==NULL)return;
    ///x->mn=min(x->val,min(get_mn(x->l),get_mn(x->r)));
    x->mn=x->val;
    if(x->l!=NULL)x->mn=x->l->val<x->mn?x->l->val:x->mn;
    ///pnode pr=x->r;
    if(x->r!=NULL)x->mn=
        x->r->val<x->mn?
        x->r->val:x->mn;
}
void ispis(pnode x,int &ct){

    if(ct<1)return;
    if(x==NULL)return;
    push(x);
    upd(x);

    ispis(x->l,ct);
    ct--;
    cout<<x->val<<" "<<x->mn<<" "<<x->t<<" "<<x->s<<endl;
    ispis(x->r,ct);
}
int ht(pnode x){
    if(x==NULL)return 0;
    return max(ht(x->l),ht(x->r))+1;
}
ll get_mn(pnode x){
    if(x==NULL)return inf;
    return x->mn;
}
void split(pnode x,pnode &l,pnode &r,ll val){

    if(x==NULL){
        l=r=NULL;
        return;
    }

    push(x);

    if(x->t<=val){
        split(x->r,x->r,r,val);
        l=x;
    }
    else{
        split(x->l,l,x->l,val);
        r=x;
    }

    upd(x);
    upd(l);
    upd(r);
}
void mrg(pnode &x,pnode l,pnode r){

    push(l);
    push(r);

    if(l==NULL){
        x=r;
        return;
    }
    if(r==NULL){
        x=l;
        return;
    }

    if(l->rval>r->rval){
        mrg(l->r,l->r,r);
        x=l;
    }
    else{
        mrg(r->l,l,r->l);
        x=r;
    }

    upd(x);
}
void last_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->r==NULL){
        ret=x;
        return;
    }
    else{
        last_node(x->r,ret);
    }
}
void first_node(pnode x,pnode &ret){

    push(x);

    if(x==NULL)return;

    if(x->l==NULL){
        ret=x;
        return;
    }
    else{
        first_node(x->l,ret);
    }
}
void ins(ll t,ll s){

    if(root==NULL){
        root=new node(0,t,s,0,NULL,NULL);
        return;
    }

    pnode ltree,rtree;
    split(root,ltree,rtree,t);

    pnode last=NULL;
    last_node(ltree,last);

    ll val;
    if(last==NULL)val=0;
    else val=last->val+(t-last->t)*last->s;
    pnode pom=new node(val,t,s,val,NULL,NULL);

    last=NULL;
    first_node(rtree,last);
    if(last!=NULL){
        ll upval=(val+(last->t-t)*s)-last->val;
        rtree->lazy+=upval;
        rtree->val+=upval;
        rtree->mn+=upval;
    }

    mrg(root,ltree,pom);
    mrg(root,root,rtree);
}
void del(int t){

    pnode l,mid,r;

    split(root,l,r,t);
    split(l,l,mid,t-1);

    pnode fst=NULL;
    ll val,s,tt;
    last_node(l,fst);
    if(fst==NULL){val=0;s=0;t=0;}
    else{val=fst->val;s=fst->s;tt=fst->t;}

    pnode snd=NULL;
    first_node(r,snd);
    if(snd!=NULL){
        int upval=(val+(snd->t-tt)*s)-snd->val;
        r->lazy+=upval;
        r->val+=upval;
        r->mn+=upval;
    }

    mrg(root,l,r);
}
void qry(pnode x,ll val,int &tm){

    push(x);
    upd(x);
    ///if(sq==10000)cout<<val<<" "<<get_mn(x->l)<<" "<<x->val<<" "<<x->t<<" U KURAC VISE\n";

    if(get_mn(x->l)<=val){
        ///if(sq==10000)printf("LEFT\n");
        qry(x->l,val,tm);
    }
    else if(x->val<=val){
        tm=x->t;
        return;
    }
    else qry(x->r,val,tm);
}
void go(pnode x){

    if(x==NULL)return;

    push(x);
    ////upd(x);
    if(sq==10000)cout<<" "<<get_mn(x->l)<<" "<<x->val<<" "<<x->t<<" U KURAC \n";

    if(x->l!=NULL){
        go(x->l);
    }
    else{
        go(x->r);
    }

}
int e;
void trazi(pnode x,ll val){

    if(x==NULL)return;
    if(x->t==val){
        e=1;
        printf("NASAO\n");
        return;
    }
    else{
        trazi(x->l,val);
        if(!e){
            trazi(x->r,val);
            if(e)printf("RIGHT\n");
        }
        else{
            if(e)printf("LEFT\n");
        }
    }

}
double query(int l,int r,ll v){

    pnode ltree,midtree,rtree;
    double ret=-2;

    ///printf("DOSAO 1\n");

    split(root,ltree,rtree,r-1);
    split(ltree,ltree,midtree,l-1);

    ///printf("DOSAO 2\n");

    if(midtree==NULL){ret=-1;}
    else{

        ///printf("DOSAO 3\n");

        pnode fst=NULL;
        first_node(midtree,fst);
        ll zero=fst->val-v;

        if(sq==10000){
            printf("\n\nISPIS A\n");
            int pm=12;
            ///ispis(midtree,pm);
            go(midtree);
            printf("\n");
        }

        trazi(midtree,11233);

        //// mozda vamo bude greska ako nema proslog
        int tm=0;
        ///if(sq==10000)printf("%lld %lld ZERO\n",midtree->mn,zero);
        if(midtree->mn>zero){
            pnode lst=NULL;
            last_node(midtree,lst);
            ///printf("%d NODE\n",lst);
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;
            if(ret>r || ret<lst->t)ret=-1;
        }
        else{
            qry(midtree,zero,tm);

            if(sq==10000){
                ///go(midtree);
            }

            pnode pom1,pom2;
            split(midtree,pom1,pom2,tm-1);

            ///if(sq==10000)printf("%d TMTM\n",tm);
            ///if(tm==0 || pom1==NULL)printf("AAAJEBOTE\n");

            pnode lst=NULL;
            last_node(pom1,lst);
            ///printf("%d NODE2\n",lst);
            if(sq==10000){
                ///cout<<lst->val<<" "<<lst->t<<" "<<lst->s<<" "<<zero<<" EVO GA"<<endl;
            }
            ret=((double)zero-(double)lst->val)/(double)lst->s+(double)lst->t;

            mrg(midtree,pom1,pom2);
        }
        ///printf("DOSAO 4\n");
    }

    mrg(root,ltree,midtree);
    mrg(root,root,rtree);

    return ret;
}
int main(){

    ///freopen("test.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    scanf("%d",&q);
    sq=q;
    int cnt=0;
    while(q--){

        cnt++;
        int tip;
        scanf("%d",&tip);

        if(tip==1){
            int t,s;
            scanf("%d %d",&t,&s);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<" "<<s<<endl;}
            else ins(t,s);
        }
        else if(tip==2){
            int t;
            scanf("%d",&t);
            if(sq==101){if(cnt>80)cout<<tip<<" "<<t<<endl;}
            else del(t);
        }
        else{
            int l,r,v;
            scanf("%d %d %d",&l,&r,&v);
            if(sq==101){
                cout<<tip<<" "<<l<<" "<<r<<" "<<v<<endl;
                continue;
            }
            if(v==0){
                printf("%d\n",l);
                continue;
            }
            cout<<fixed;
            cout<<setprecision(6);
            cout<<query(l,r,v)<<endl;
            ////printf("%.6lf\n",query(l,r,v));
        }

        /*ispis(root);
        printf("\n");*/

    }

    return 0;
}

    #include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

#define pitem item*
#define tam 1023456
#define tamN 12345
using namespace std;
typedef long long ll;

typedef pair<ll,ll> ii;
typedef pair<int,ii> iii;
const ll INF=1e18;
struct item
{
    int prior,cnt;
    ll pos,speed,minn,tot;
    ii pos_viz;
    ii pos_vder;
    pitem l;
    pitem r;
    item(){}
    item(ll pos,ll speed):pos(pos),speed(speed),l(0),r(0)
    {
        prior=rand();
        minn=INF;
        pos_viz=pos_vder=ii(pos,speed);
    }

};
int cnt(pitem t){return t?t->cnt:0;}
ll gtot(pitem t){return t?t->tot:0;}
ll gmin(pitem t){return t?t->minn:INF;}

ll gextraiz(pitem t){
    if (!t|| (!(t->l)))
        return INF;
    else
        return (t->pos-t->l->pos_vder.f)*(t->l->pos_vder.s);
}
ll gextrader(pitem t){
    if (!t|| !(t->r))
        return INF;
    return  (t->r->pos_viz.f-t->pos)*(t->speed);
}
void upd_cnt(pitem t)
{
    if (t)
    {
        t->cnt=cnt(t->l)+cnt(t->r)+1;
        ll extraiz=gextraiz(t),extrader=gextrader(t),totiz=gtot(t->l);
        t->tot=totiz;
        t->pos_viz=t->pos_vder=ii(t->pos,t->speed);
        if (t->l)   t->tot+=extraiz,t->pos_viz=t->l->pos_viz;
        if (t->r)   t->tot+=extrader,t->pos_vder=t->r->pos_vder;
        t->tot+=gtot(t->r);
        t->minn=gmin(t->l);
        t->minn=min(t->minn,totiz+extraiz);
        t->minn=min(t->minn,totiz+extraiz+extrader);
        t->minn=min(t->minn,totiz+extraiz+extrader+gmin(t->r));
        if (t->tot!=0)
        t->minn=min(t->minn,t->tot);
    }
}
void split(pitem t,pitem &l,pitem &r,int key)
{
    if (!t)
        return void(l=r=0);
    if (t->pos>key)
        split(t->l,l,t->l,key),r=t;
    else
        split(t->r,t->r,r,key),l=t;
    upd_cnt(t);
}
void merge(pitem &t,pitem l,pitem r)
{
    if (!l||!r)
        t=l?l:r;
    else if (r->prior>l->prior)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd_cnt(t);
}
ll auxresp;
double respf;ll iz,der;
pitem ant_t;
bool print=false;
void query(pitem t,ll inival)
{

    if (t==0)
    {
        if (!ant_t)
            return void(auxresp=-1);

        // cout<<" llegamos "<<ant_t->pos<<" "<<ant_t->speed<<endl;
        ll extra;
        extra=(der-ant_t->pos)*(ant_t->speed);
        if (inival+extra<=0)
        {
            auxresp=(ant_t->pos)-(inival)/(ant_t->speed);//.-.
            if ((inival)/(ant_t->speed)>0)
                cout<<"watultimo\n";
            if (print==1)
                cout<<" aca: ";
            respf=-(double)(inival%ant_t->speed)/(ant_t->speed);//.-.
            return;
        }
        else
            return void(auxresp=-1);
    }
    ant_t=t;
    ////// cout<<t->pos<<" "<<gmin(t->l)<<" ";
    if (gmin(t->l)+inival<=0)
    {
        query(t->l,inival);
        // cout<<"go left\n";
    }
    else
    {
        ll extraiz,extrader,totiz;
        extraiz=(t->l)?gextraiz(t):0;
        extrader=(t->r)?gextrader(t):0;
        totiz=gtot(t->l);
        ll auxini=totiz+extraiz+extrader;
        // cout<<totiz<<" "<<extraiz<<" "<<extrader<<endl;
        if (totiz+extraiz+inival<=0)
        {
            inival+=totiz;
            auxresp=(t->l->pos_vder.f)-(inival)/(t->l->pos_vder.s);//.-.
            if ((inival)/(t->l->pos_vder.s)>0)
                cout<<"watizquierda\n";
            respf=-(double)(inival%t->l->pos_vder.s)/(t->l->pos_vder.s);
        }
        else if (totiz+extraiz+extrader+inival<=0)
        {
            inival+=totiz+extraiz;
            auxresp=(t->pos)-(inival)/(t->speed);//-.-
            if (inival/t->speed>0)
                cout<<"watderecha\n";
            respf=-(double)(inival%t->speed)/(t->speed);//-.-

        }
        else
            {

                // cout<<"go right\n";
                query(t->r,auxini+inival);
            }

    }
}

int main()
{
    int casos;
    if (casos>5000)
        print=1;
    scanf("%d",&casos);
    if (casos==100)
        print=1;
    int tipo;
    pitem t1;pitem t2;pitem t3;
    pitem s;
    pitem tree=new item(2e9,1);
    ll val,pos;
    double auxrespf;
    while(casos--)
    {
        scanf("%d",&tipo);
        if (tipo==1)
        {
            scanf("%lld %lld",&pos,&val);
            if (val==0)
            {
                split(tree,t1,t3,pos);
                split(t1,t1,t2,pos-1);
                merge(tree,t1,t3);
                continue;
            }
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            s=new item(pos,val);
            merge(tree,t1,s);
            merge(tree,tree,t3);
        }
        else if (tipo==2)
        {
            scanf("%lld",&pos);
            split(tree,t1,t3,pos);
            split(t1,t1,t2,pos-1);
            merge(tree,t1,t3);
        }
        else if (tipo==3)
        {
            scanf("%lld %lld %lld",&iz,&der,&val);
            if (val==0)
            {
                printf("%lld.0\n",iz);
                continue;
            }
            split(tree,t1,t3,der);
            split(t1,t1,t2,iz-1);
            ant_t=NULL;
            query(t2,val);
            if (auxresp==-1)
                printf("-1\n");
            else
            {
                auxrespf=auxresp+respf;
                printf("%.9lf\n",auxrespf);
            }
            merge(tree,t1,t2);
            merge(tree,tree,t3);
        }
     //   inorder(tree);
        //// cout<<endl;
    }
}

#include<bits/stdc++.h>
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
using namespace std;

template<class T>inline void rd(T & x){ int f = 1;x = 0;char ch = getchar();for(;!isdigit(ch);ch = getchar()) if(ch == '-') f = -1; for(;isdigit(ch);ch = getchar()) x = x * 10 + ch - '0';x *= f;}

const int maxn = 1e5 + 10;

struct op{
	int type;
	int t,l,r,v,s;
} querys[maxn];

int times[maxn],n;
inline int upper(double time){
	int l = 1,r = n,ans = n + 1;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] >= time){
			ans = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	return ans;
}
inline int lower(double time){
	int l = 1,r = n,ans = 0;
	while(l <= r){
		int mid = l + r >> 1;
		if(times[mid] <= time){
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return ans;
}

int mark[maxn];
namespace Fenwick{
	int tr[maxn];
	inline void update(int x,int v){ for(;x < maxn;x += x & (-x)) tr[x] += v;}
	inline int query(int x){ int ans = 0; for(;x;x ^= x & (-x)) ans += tr[x]; return ans;}
	inline int val(int x) { return query(x) - query(x - 1);}
	inline int bs(int x){ // min query(ans) >= x
		int l = 0,r = n,ans = 0;
		while(l <= r){
			int mid = l + r >> 1;
			if(query(mid) >= x) {
				ans = mid;
				r = mid - 1;
			} else {
				l = mid + 1;
			}
		}
		return ans;
	}
	inline int pre(int x){
		int d = query(x - 1);
		return bs(d);
	}
	inline int suc(int x){
		return bs(query(x) + 1);
	}
}
double cur[maxn];
const double inf = 2e20;
namespace Segment{
	double tra[maxn << 2],tri[maxn << 2];
	double lazy[maxn << 2];
	int mk[maxn << 2];

	inline void pushup(int rt){
		tra[rt] = max(tra[rt << 1],tra[rt << 1 | 1]);
		tri[rt] = min(tri[rt << 1],tri[rt << 1 | 1]);
	}
	inline void pushdown(int rt){
		if(!mk[rt]) return;
		mk[rt] = 0;
		mk[rt << 1] = 1;
		mk[rt << 1 | 1] = 1;
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		tra[rt << 1] += lazy[rt];
		tri[rt << 1] += lazy[rt];
		tra[rt << 1 | 1] += lazy[rt];
		tri[rt << 1 | 1] += lazy[rt];
		lazy[rt] = 0;
	}
	void _update(double * target,int pos,double v,int l,int r,int rt){
		if(l == r){
			target[rt] = v;
			return;
		}
		int mid = l + r >> 1;
		if(pos <= mid) _update(target,pos,v,lson);
		else _update(target,pos,v,rson);
		pushup(rt);
	}
	void setVoid(int pos){
		_update(tra,pos,-inf,1,n,1);
		_update(tri,pos,inf,1,n,1);
	}
	void setZero(int pos){
		_update(tra,pos,0,1,n,1);
		_update(tri,pos,0,1,n,1);
	}
	void build(int l,int r,int rt){
		if(l == r){
			tra[rt] = -inf;
			tri[rt] = inf;
			return;
		}
		int mid = l + r >> 1;
		build(lson);
		build(rson);
		pushup(rt);
	}
	void update(int L,int R,double v,int l,int r,int rt){
		if(L <= l && r <= R){
			lazy[rt] += v;
			tra[rt] += v;
			tri[rt] += v;
			mk[rt] = 1;
			return;
		}
		pushdown(rt);
		int mid = l + r >> 1;
		if(L <= mid) update(L,R,v,lson);
		if(R > mid) update(L,R,v,rson);
		pushup(rt);
	}
	double querya(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tra[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = -inf;
		if(L <= mid) ans = max(ans,querya(L,R,lson));
		if(R > mid)ans = max(ans,querya(L,R,rson));
		return ans;
	}
	double queryi(int L,int R,int l,int r,int rt){
		if(L <= l && r <= R){
			return tri[rt];
		}
		pushdown(rt);
		int mid = l + r >> 1;
		double ans = inf;
		if(L <= mid) ans = min(ans,queryi(L,R,lson));
		if(R > mid) ans = min(ans,queryi(L,R,rson));
		return ans;
	}

}
double getV(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return cur[x];
}
double calc(double l){
	int x = lower(l);
	if(x == 0) return 0;
	if(Fenwick::val(x) == 0)x = Fenwick::pre(x);
	if(x == 0) return 0;
	return (double)(l - times[x]) * cur[x] + Segment::querya(x,x,1,n,1);
}
const double eps = 1e-15;
bool check(double l,double r,double c){
	double qa = -inf,qi = inf;
	if(fabs(l - r) <= eps) return fabs(calc(l) - c) <= eps;
	qa = max(calc(l),qa);
	qi = min(calc(l),qi);
	qa = max(calc(r),qa);
	qi = min(calc(r),qi);
	int lx = upper(l),rx = lower(r);
	if(lx <= rx && lx != 0 && rx != 0){
		qa = max(qa,Segment::querya(lx,rx,1,n,1));
		qi = min(qi,Segment::queryi(lx,rx,1,n,1));
	}
//	printf("%.9f %.9f %.9f %.9f %.9f\n",l,r,qa,qi,c);
	return qa - c >= 0 && qi - c <= 0;
}

int main(){
	int TAT;
	int ttt = 0;
	rd(TAT);
	for(int i = 1;i <= TAT;i++){
		int type,t,l,r,v,s;
		rd(type);
		if(type == 1){ // add
			rd(t); rd(v);
			times[++n] = t;
			querys[i].type = 1;
			querys[i].t = t;
			querys[i].v = v;
		} else if(type == 2){
			rd(t);
			querys[i].type = 2;
			querys[i].t = t;
		} else {
			rd(l); rd(r); rd(s);
			querys[i].type = 3;
			querys[i].l = l;
			querys[i].r = r;
			querys[i].s = s;
		}
	}
	sort(times + 1,times + n + 1);
	n = unique(times + 1,times + n + 1) - times - 1;

	if(n!=0)Segment::build(1,n,1);
	for(int i = 1;i <= TAT;i++){
		int type = querys[i].type;
		if(type == 1){
			int t = querys[i].t, v = querys[i].v;
			int pos = upper(t);
			Fenwick::update(pos,1);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			cur[pos] = v;
			Segment::setZero(pos);
			if(pre){
				double delta = (double)cur[pre] * (times[pos] - times[pre]) + Segment::querya(pre,pre,1,n,1);
				Segment::update(pos,pos,delta,1,n,1);
			}
			if(suc){
				double delta = (double)(v - cur[pre]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
		} else if(type == 2){
			int t = querys[i].t;
			int pos = upper(t);
			int pre = Fenwick::pre(pos),suc = Fenwick::suc(pos);
			Fenwick::update(pos,-1);
			if(suc){
				double delta = (double)(cur[pre] - cur[pos]) * (times[suc] - times[pos]);
				Segment::update(suc,n,delta,1,n,1);
			}
			Segment::setVoid(pos);
			cur[pos] = 0;
		} else {
			ttt++;
			double l = querys[i].l , r = querys[i].r , s = -querys[i].s;
			int lx = upper(l);
			if(Fenwick::val(lx) == 0) lx = Fenwick::suc(lx);
			l = times[lx];
			if(s == 0) {
				printf("%d\n",querys[i].l);
				continue;
			}
			if(n == 0 || Fenwick::query(n) == 0 || !lx || l > r) {
				printf("-1\n");
				continue;
			}
			s += Segment::querya(lx,lx,1,n,1);

			bool ok = 0;
			if(ttt == 20) printf("%.9f %.9f %.9f %.9f %d\n",l,r,calc(39),s,check(38,39,s));
			if(check(r,r,s) || check(l,l,s)) ok = 1;
			for(int k = 0;k < 1000;k++){
				double mid = (l + r) / 2;
				if(check(l,mid,s)){
					r = mid;
					ok = 1;
				} else {
					l = mid;
				}
			}
			if(fabs(calc(l) - s) <= eps) ok = 1;
			if(ok)printf("%.9f\n",r);
			else printf("-1\n");
		}
	}
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef double db;
typedef long double ldb;

typedef long long ll;
typedef pair<ll,int> pr;

int num[300005];
int cnt;

namespace SGT {

ll sumv[1200000],minn[1200000],setv[1200000];

inline void pushdown(int l,int r,int o) {
  if (setv[o]!=-1) {
  	int m=((l+r)>>1);
  	sumv[o*2]=setv[o]*(num[m+1]-num[l]);minn[o*2]=min(0LL,sumv[o*2]);
  	sumv[o*2+1]=setv[o]*(num[r+1]-num[m+1]);minn[o*2+1]=min(0LL,sumv[o*2+1]);
  	setv[o*2]=setv[o*2+1]=setv[o];
  	setv[o]=-1;
  }
}

inline void pushup(int o) {
  sumv[o]=sumv[o*2]+sumv[o*2+1];
  minn[o]=min(minn[o*2],sumv[o*2]+minn[o*2+1]);
}

void update(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) {
  	sumv[o]=p*(num[r+1]-num[l]);minn[o]=min(0LL,sumv[o]);
  	setv[o]=p;
  }
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=lx) update(l,m,o*2,lx,rx,p);
  	if (m<rx) update(m+1,r,o*2+1,lx,rx,p);
  	pushup(o);
  }
}

pr query2(int l,int r,int o,ll p) {
  if (l==r) return pr(p,l);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (p+minn[o*2]<=0) return query2(l,m,o*2,p);
  	else return query2(m+1,r,o*2+1,p+sumv[o*2]);
  }
}

pr query1(int l,int r,int o,int lx,int rx,ll p) {
  if (l>=lx&&r<=rx) return (p+minn[o]<=0)?query2(l,r,o,p):pr(p+sumv[o],-1);
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query1(l,m,o*2,lx,rx,p);
  	if (m<lx) return query1(m+1,r,o*2+1,lx,rx,p);
  	pr a=query1(l,m,o*2,lx,rx,p);
  	if (a.SE!=-1) return a;
	return query1(m+1,r,o*2+1,lx,rx,a.FR);
  }
}

ll query3(int l,int r,int o,int p) {
  if (l==r) return setv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=p) return query3(l,m,o*2,p);
  	else return query3(m+1,r,o*2+1,p);
  }
}

ll query4(int l,int r,int o,int lx,int rx) {
  if (l>=lx&&r<=rx) return sumv[o];
  else {
  	pushdown(l,r,o);
  	int m=((l+r)>>1);
  	if (m>=rx) return query4(l,m,o*2,lx,rx);
  	if (m<lx) return query4(m+1,r,o*2+1,lx,rx);
  	return query4(l,m,o*2,lx,rx)+query4(m+1,r,o*2+1,lx,rx);
  }
}

}

struct Ope {
  int l,r,v,kind;
  Ope() {}
  Ope(int a,int b,int c,int d):l(a),r(b),v(c),kind(d) {}
};

Ope a[100005];
set <int> st;

int val[100005];

int main() {
  memset(val,0x3f,sizeof(val));
  int m;
  scanf("%d",&m);
  int n=0;
  for(int i=1;i<=m;i++) {
  	int kind;
  	scanf("%d",&kind);
  	if (kind==1) {
  		int x,y,z;
  		scanf("%d%d",&x,&y);
  		a[i]=Ope(x,x,y,1);
  		num[++n]=x;
	  }
	else if (kind==2) {
		int x;
		scanf("%d",&x);
		a[i]=Ope(x,x,0,2);
		num[++n]=x;
	}
	else {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		a[i]=Ope(x,y,z,3);
		num[++n]=x;num[++n]=y;
	}
  }
  num[++n]=0;num[++n]=1e9+1;
  sort(num+1,num+n+1);
  n=unique(num+1,num+n+1)-num-1;
  st.insert(1);st.insert(n);
  for(int i=1;i<=m;i++)
    if (a[i].kind==1) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	st.insert(t);
    	set<int>::iterator it=st.lower_bound(t);
    	it++;
    	int t2=(*it);
    	SGT::update(1,n,1,t,t2-1,a[i].v);
    	if (m==10000) val[a[i].l]=a[i].v;
	}
	else if (a[i].kind==2) {
    	int t=lower_bound(num+1,num+n+1,a[i].l)-num;
    	set<int>::iterator it=st.lower_bound(t),it2=it;
    	it--;it2++;
    	int t1=(*it),t2=(*it2);
    	st.erase(t);
    	SGT::update(1,n,1,t,t2-1,SGT::query3(1,n,1,t1));
    	if (m==10000) val[a[i].l]=inf;
	}
	else {
		cnt++;
		if (cnt==3167) {
			for(int i=8621;i<8635;i++) printf("%d\n",SGT::query3(1,n,1,i));
		}
		if (!a[i].v) {
			if (m!=10000) printf("%d\n",a[i].l);
			continue;
		}
		int l=lower_bound(num+1,num+n+1,a[i].l)-num,r=lower_bound(num+1,num+n+1,a[i].r)-num-1;
		set<int>::iterator it=st.lower_bound(l);
		l=(*it);
		if (l>r) {
			if (m!=10000) puts("-1");
			continue;
		}
		pr t=SGT::query1(1,n,1,l,r,a[i].v);
		if (t.SE!=-1) {
			db v=SGT::query3(1,n,1,t.SE);
			if (m!=10000) printf("%.8f\n",(db)(num[t.SE]+(ldb)(-t.FR)/v));
		}
		else if (m!=10000) puts("-1");
	}
  return 0;
}

#include <bits/stdc++.h>
#include <chrono>
#define INF 1000 * 1000 * 1000
#define LINF INF * (LL)INF
#define LL long long
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int l , r , v;
struct node
{
	int L , R;
	int y;
	LL time , speed , tL , tR , speedR , res , mn;
	node()
	{
		L = -1 , R = -1;
		speed = 0;
		y = rng();
	}
}
t[100005];
int nodeCnt;
int getNode()
{
	return nodeCnt++;
}
int update(int v)
{
	if(v == -1)
		return v;
	t[v].tL = t[v].tR = t[v].time;
	t[v].speedR = t[v].speed;

	LL Mn = 0 , Res = 0;
	if(t[v].L != -1)
	{
		t[v].tL = t[t[v].L].tL;
		Mn = min(Mn , t[t[v].L].mn);
		Mn = min(Mn , t[t[v].L].res + (t[v].time - t[t[v].L].tR) * (LL) t[t[v].L].speedR);
		Res = t[t[v].L].res + (t[v].time - t[t[v].L].tR) * (LL) t[t[v].L].speedR;
	}
	if(t[v].R != -1)
	{
		Res += (t[t[v].R].tL - t[v].time) * t[v].speed;
		Res += t[t[v].R].res;
		Mn = min(Mn , Mn + (t[t[v].R].tL - t[v].time) * (LL)t[v].speed + t[t[v].R].mn);
		t[v].speedR = t[t[v].R].speedR;
		t[v].tR = t[t[v].R].tR;
	}
	t[v].mn = Mn;
	t[v].res = Res;

	return v;
}
void split(int v , int T , int &L , int &R)
{
	if(v == -1)
	{
		L = -1 , R = -1;
		return;
	}
	if(t[v].time >= T)
	{
		split(t[v].L , T , L , t[v].L);
		R = update(v);
	}
	else
	{
		split(t[v].R , T , t[v].R , R);
		L = update(v);
	}
}
int merge(int L , int R)
{
	if(L == -1)
		return R;
	if(R == -1)
		return L;
	if(t[L].y > t[R].y)
	{
		t[L].R = merge(t[L].R , R);
		return update(L);
	}
	else
	{
		t[R].L = merge(L , t[R].L);
		return update(R);
	}
}
double getAns(int noda)
{
	if(v == 0)
		return l;
	////debug(noda);
	if(noda == -1)
	{
		return -1;
	}
	if(t[noda].mn <= -v)
	{
		if(t[noda].L != -1 && t[t[noda].L].mn <= -v)
		{
			return getAns(t[noda].L);
		}
		LL Res = t[noda].L == -1 ? 0 : t[t[noda].L].res;

		if(t[noda].L != -1)
		{
			if(Res + (t[noda].time - t[t[noda].L].tR) * t[t[noda].L].speedR <= -v)
			{
				v += Res;
				return t[t[noda].L].tR + (v * 1.0) / abs(t[t[noda].L].speedR);
			}
			Res += (t[noda].time - t[t[noda].L].tR) * t[t[noda].L].speedR;
		}
		if(t[noda].R != -1)
		{
			//debug(t[t[noda].R].tL);
			//debug(t[noda].speed);
			//debug(Res + (t[t[noda].R].tL - t[noda].time) * t[noda].speed);
			if(Res + (t[t[noda].R].tL - t[noda].time) * t[noda].speed <= -v)
			{
				v += Res;
				return t[noda].time + (v * 1.0) / abs(t[noda].speed);
			}
			Res += (t[t[noda].R].tL - t[noda].time) * t[noda].speed;
			v += Res;
			return getAns(t[noda].R);
		}
		assert(false);
	}
	else
	{
		LL val = t[noda].res + (r - t[noda].tR) * (LL)t[noda].speedR;
		////debug(val);
		if(val <= -v)
		{
				v += t[noda].res;
				return t[noda].tR + ((v * 1.0) / abs(t[noda].speedR));
		}
		return -1;
	}
}
int main()
{
	ios_base::sync_with_stdio(0);
	int q;
	cin >> q;
	int root = -1;
	while(q--)
	{
		int type;
		cin >> type;
		if(type == 1)
		{
			int T , s;
			cin >> T >> s;
			int newNode = getNode();
			////debug(newNode);
			t[newNode].time = T;
			t[newNode].speed = s;
			update(newNode);
			int L , R;
			split(root , T , L , R);
			root = merge(L , newNode);
			root = merge(root , R);
			////debug(t[root].speedR);
		}
		else if(type == 2)
		{
			int t;
			cin >> t;
			int L , R;
			split(root , t , L , R);
			int L1 , R1;
			split(R , t + 1 , L1 , R1);
			root = merge(L , R1);
		}
		else
		{
			cin >> l >> r >> v;
			int L , M , M1 , R;
			split(root , l - 1 , L , M);
			////debug(t[M].speedR);
			////debug(t[M].tL);
			////debug(t[M].tR);
			split(M , r + 1 , M1 , R);
			//debug(t[M1].speedR);
			//debug(t[M1].tL);
			//debug(t[M1].tR);
			//debug(t[M1].res);
			//debug(t[M1].mn);
			//cout << "Answer!!!" << endl;
			cout << fixed << setprecision(10) << getAns(M1) << '\n';
			root = merge(L , M1);
			root = merge(root , R);
		}
	}
}