#include <bits/stdc++.h>
using namespace std;
struct Block {
  long long start, end, add;
  long long AtEnd(long long s) { return s + (end - start + 1) * add; }
  long long Min(long long s) { return min(s, AtEnd(s)); }
  double Zero(long long s) { return start + (s + 0.0) / abs(add); }
};
struct Node {
  int key, h;
  Block bl;
  Node *l, *r;
  long long low, at_end;
  Node(const Block& _bl) {
    bl = _bl;
    key = bl.start;
    h = rand();
    l = r = NULL;
    low = bl.Min(0);
    at_end = bl.AtEnd(0);
  }
};
void Update(Node* vr) {
  if (!vr) return;
  long long last = 0;
  long long low = 1E18;
  if (vr->l) {
    (low) = min((low), (vr->l->low + last));
    last = vr->l->at_end + last;
  }
  (low) = min((low), (vr->bl.Min(last)));
  last = vr->bl.AtEnd(last);
  if (vr->r) {
    (low) = min((low), (vr->r->low + last));
    last = vr->r->at_end + last;
  }
  vr->low = low;
  vr->at_end = last;
}
void Print(Node* vr) {
  if (!vr) return;
  cout << "Left\n";
  Print(vr->l);
  cout << "End\n";
  cout << vr->bl.start << ' ' << vr->bl.end << ' ' << vr->bl.add << endl;
  cout << "Right\n";
  Print(vr->r);
  cout << endl;
}
Node* Merge(Node* le, Node* ri) {
  if (!le || !ri) return le ? le : ri;
  if (le->h < ri->h) {
    le->r = Merge(le->r, ri);
    Update(le);
    return le;
  } else {
    ri->l = Merge(le, ri->l);
    Update(ri);
    return ri;
  }
}
void Split(Node* vr, int on, Node*& le, Node*& ri) {
  if (!vr) return void(le = ri = NULL);
  if (vr->bl.start >= on) {
    Split(vr->l, on, le, vr->l);
    ri = vr;
    Update(ri);
  } else {
    Split(vr->r, on, vr->r, ri);
    le = vr;
    Update(le);
  }
}
map<int, pair<int, int> > ival;
Node* tree;
void Erase(int start) {
  Node *l, *m, *r;
  Split(tree, start, l, m);
  Split(m, start + 1, m, r);
  delete m;
  tree = Merge(l, r);
}
void Insert(const Block& bl) {
  Node *l, *r;
  Split(tree, bl.start, l, r);
  tree = Merge(l, Merge(new Node(bl), r));
}
double Get(Node* vr, long long base) {
  if (!vr) return -1;
  if (vr->l) {
    if (base + vr->l->low <= 0) return Get(vr->l, base);
    base += vr->l->at_end;
  }
  if (vr->bl.Min(base) <= 0) return vr->bl.Zero(base);
  base = vr->bl.AtEnd(base);
  if (vr->r) {
    if (base + vr->r->low > 0) return -1;
    return Get(vr->r, base);
  }
  return -1;
}
double GetFirst(int start, int end, int val) {
  if (val == 0) return start;
  Node *l, *m, *r;
  Split(tree, start, l, m);
  Split(m, end + 1, m, r);
  double ans = Get(m, val);
  if (ans > end + 1E-9) ans = -1;
  tree = Merge(l, Merge(m, r));
  return ans;
}
void RemoveEvent(int tim) {
  auto me = ival.lower_bound(tim);
  auto par = me;
  --par;
  int me_f = me->first, me_t = me->second.first, me_a = me->second.second;
  int he_f = par->first, he_t = par->second.first, he_a = par->second.second;
  Erase(me_f);
  Erase(he_f);
  ival.erase(me_f);
  ival.erase(he_f);
  ival[he_f] = make_pair(me_t, he_a);
  Insert(Block{he_f, me_t, he_a});
}
void InsertEvent(int tim, int add) {
  auto fg = ival.lower_bound(tim + 1);
  auto fl = fg;
  --fl;
  int he_f = fl->first, he_t = fl->second.first, he_a = fl->second.second;
  Erase(he_f);
  ival.erase(he_f);
  ival[he_f] = make_pair(tim - 1, he_a);
  Insert(Block{he_f, tim - 1, he_a});
  ival[tim] = make_pair(he_t, add);
  Insert(Block{tim, he_t, add});
}
int main() {
  tree = new Node(Block{0, (long long)1E9 + 10, 0});
  ival[0] = make_pair((long long)1E9 + 10, 0);
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int t, s;
      scanf("%d%d", &t, &s);
      InsertEvent(t, s);
    } else if (op == 2) {
      int t;
      scanf("%d", &t);
      RemoveEvent(t);
    } else {
      int l, r, v;
      scanf("%d%d%d", &l, &r, &v);
      double ans = GetFirst(l, r, v);
      if (ans < -0.5)
        printf("-1\n");
      else
        printf("%.12f\n", ans);
    }
  }
  return 0;
}
