#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 (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[rchild] == INF) return query(l, m, v, ss, rr, x * 2, nl, m);
			if (mn[lchild] == 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, rr, x * 2, nl, m);
			ll diff = e[lchild].second * (mmin((ll)rr, 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[rchild] == INF) return query(l, mmin(m, r), v, ss, rr, x * 2, nl, m);
		if (mn[lchild] == INF) return query(mmax(l, m + 1), r, v, ss, rr, x * 2 + 1, m + 1, nr);
		node res = query(l, mmin(r, m), v, ss, mmin(f[x * 2 + 1].first, (ll)rr), 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) - added.begin();
				cout << st.query(l, r, q.vol, q.l, q.r, 1, 1, m).to << '\n';
			}
		}
	}

	//system("pause");
	return 0;
}

/**
 * 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;
#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 <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 <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;
    }
  }
}

#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;
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;
}

#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;
}

#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>                                                                                //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<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>
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;
}

/*----------------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 <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();
}

#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;
}

// #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;
}

/*----------------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;
}

/*----------------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 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>
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>
#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);
        }
    }
}

#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<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 <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);
}

#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<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;
}

#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 <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");
		}
	}
}

#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;
}

#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);
		}
	}
}

#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;
}

#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;
}

#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>

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;
}

/*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';
		}
	}
}

#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 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>

#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;
}

#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;

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 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 <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;
        }
    }

//时间节点离散化，用线段树维护时间区间上的二次函数，最终线段树上应当存了一些互不相交的函数区间。
//修改操作：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 <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;
}

#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;

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;
}

#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 <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>
#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");
        }
    }
}

#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;
}

#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);
		}
	}
}

#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<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 <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 <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;
}

#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 <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;

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 <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 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<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 <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;
}

#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;
}

/*

    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<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 ;
}

#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<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);
			}
		}
	}
}

#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;
}

#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 <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 <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 <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 <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<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);}}}}

#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 <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;

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>

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;
//#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<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
#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>
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);
		}
	}
}