#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long INFF = 0x3f3f3f3f3f3f3f3fll;
const long long M = 1e9 + 7;
const long long maxn = 1e5 + 107;
const double pi = acos(-1.0);
const double eps = 0.0000000001;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
template <typename T>
inline void pr2(T x, int k = 64) {
  long long i;
  for (i = 0; i < k; i++) fprintf(stderr, "%d", (x >> i) & 1);
  putchar(' ');
}
template <typename T>
inline void add_(T &A, int B, long long MOD = M) {
  A += B;
  (A >= MOD) && (A -= MOD);
}
template <typename T>
inline void mul_(T &A, long long B, long long MOD = M) {
  A = (A * B) % MOD;
}
template <typename T>
inline void mod_(T &A, long long 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 = (long long)a * a % M)
    if (b & 1) ret = (long long)ret * a % M;
  return ret;
}
int startTime;
void startTimer() { startTime = clock(); }
void printTimer() {
  fprintf(stderr, "/--- Time: %ld milliseconds ---/\n", clock() - startTime);
}
struct node {
  int l, r;
  int lpos, rm, value;
  long long maxused, used;
  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) {
  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 + (long long)(B.rm - A.lpos) * A.value + B.maxused);
  ret.lpos = B.lpos;
  ret.value = B.value;
  ret.rm = A.rm;
  ret.used = A.used + (long long)(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) {
  if (!x) x = ++tot;
  if (L == R) {
    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]);
}
double ans;
node now;
void query(int x, int L, int R) {
  if (ans >= 0) return;
  if (l <= L && R <= r) {
    if (T[x].lpos) {
      if (now.used + (long long)(T[x].rm - now.lpos) * now.value >= v) {
        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]);
      if (tmp.maxused >= v) {
        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 + (long long)(R - now.lpos) * now.value >= v) {
      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; i <= q; i++) {
    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("%.10f\n", ans);
    }
  }
}
