#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
template <typename T>
inline T read() {
  T s = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    s = (s << 3) + (s << 1) + ch - 48;
    ch = getchar();
  }
  return s * f;
}
constexpr int N = 1e6 + 100;
constexpr int MAX = 1e6;
struct Segment {
  static const int N = 1e6 + 100;
  struct node {
    long long val, lazy, sum;
  } s[N * 4];
  void spread(int node, int l, int r) {
    if (s[node].lazy) {
      int mid = (l + r) >> 1;
      s[node << 1].lazy += s[node].lazy;
      s[node << 1 | 1].lazy += s[node].lazy;
      s[node << 1].val += s[node].lazy;
      s[node << 1 | 1].val += s[node].lazy;
      s[node << 1].sum += -s[node].lazy;
      s[node << 1 | 1].sum += -s[node].lazy;
      s[node].lazy = 0;
    }
  }
  void pushup(int node, int l, int r) {
    s[node].val = max(s[node << 1].val, s[node << 1 | 1].val);
  }
  void build(int node, int l, int r) {
    s[node].lazy = 0;
    if (l == r) {
      s[node].val = s[node].sum = 0;
      return;
    }
    int mid = (l + r) >> 1;
    build(node << 1, l, mid);
    build(node << 1 | 1, mid + 1, r);
    pushup(node, l, r);
  }
  void change(int node, int l, int r, int id, pair<long long, long long> num) {
    if (l == r) {
      s[node].val += num.first;
      s[node].sum += num.second;
      return;
    }
    spread(node, l, r);
    int mid = (l + r) >> 1;
    if (id <= mid)
      change(node << 1, l, mid, id, num);
    else
      change(node << 1 | 1, mid + 1, r, id, num);
    pushup(node, l, r);
  }
  void change(int node, int l, int r, int L, int R, long long val) {
    if (L <= l && R >= r) {
      s[node].val += val;
      s[node].lazy += val;
      s[node].sum += -val;
      return;
    }
    spread(node, l, r);
    int mid = (l + r) >> 1;
    if (L <= mid) change(node << 1, l, mid, L, R, val);
    if (R > mid) change(node << 1 | 1, mid + 1, r, L, R, val);
    pushup(node, l, r);
  }
  long long queryval(int node, int l, int r, int L, int R) {
    if (L == l && R == r) {
      return s[node].val;
    }
    spread(node, l, r);
    int mid = (l + r) >> 1;
    if (R <= mid)
      return queryval(node << 1, l, mid, L, R);
    else if (L > mid)
      return queryval(node << 1 | 1, mid + 1, r, L, R);
    else {
      long long val = 0;
      val = max(val, queryval(node << 1, l, mid, L, mid));
      val = max(val, queryval(node << 1 | 1, mid + 1, r, mid + 1, R));
      return val;
    }
  }
  long long querysum(int node, int l, int r, int id) {
    if (l == r) {
      return s[node].sum;
    }
    spread(node, l, r);
    int mid = (l + r) >> 1;
    if (id <= mid)
      return querysum(node << 1, l, mid, id);
    else
      return querysum(node << 1 | 1, mid + 1, r, id);
  }
} tree;
struct node {
  int t, d;
} s[N];
int main() {
  int q = read<int>();
  tree.build(1, 1, MAX);
  for (int i = 1; i <= q; ++i) {
    char ch;
    scanf(" %c", &ch);
    if (ch == '+') {
      int t = read<int>(), d = read<int>();
      tree.change(1, 1, MAX, t, {t, d});
      tree.change(1, 1, MAX, t + 1, MAX, -d);
      s[i] = {t, d};
    } else if (ch == '-') {
      int id = read<int>();
      int t = s[id].t, d = s[id].d;
      int val = tree.querysum(1, 1, MAX, t);
      tree.change(1, 1, MAX, t, {-t, -d});
      tree.change(1, 1, MAX, t + 1, MAX, d);
    } else {
      int t = read<int>();
      cout << max(0ll, tree.queryval(1, 1, MAX, 1, t) +
                           tree.querysum(1, 1, MAX, t) - t)
           << endl;
    }
  }
}
