#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 20;
const long long oo = 1e13 + 20;
const int MOD = 1e9 + 7;
struct line {
  long long m, b;
  long long eval(long long x) { return m * x + b; }
};
struct cht {
  vector<line> lines;
  vector<double> inter;
  int n, i;
  double get_inter(line &a, line &b) { return double(b.b - a.b) / (a.m - b.m); }
  inline bool ok(line &a, line &b, line &c) {
    return double(a.b - c.b) / (c.m - a.m) > double(a.b - b.b) / (b.m - a.m);
  }
  void add(line l) {
    n = lines.size();
    if (n && lines.back().m == l.m && lines.back().b >= l.b) return;
    if (n == 1 && lines.back().m == l.m && lines.back().b < l.b)
      lines.pop_back(), n--;
    while (n >= 2 && !ok(lines[n - 2], lines[n - 1], l)) {
      n--;
      lines.pop_back();
      inter.pop_back();
    }
    lines.push_back(l);
    n++;
    if (n >= 2) inter.push_back(get_inter(lines[n - 1], lines[n - 2]));
  }
  long long get_max(double x) {
    if (lines.size() == 0) return LLONG_MIN;
    if (lines.size() == 1) return lines[0].eval(x);
    int pos = lower_bound(inter.begin(), inter.end(), x) - inter.begin();
    return lines[pos].eval(x);
  }
};
struct st {
  st *left, *right;
  int l, r, m;
  cht trick;
  st(int l, int r) : l(l), r(r) {
    m = (l + r) / 2;
    if (l != r) {
      left = new st(l, m);
      right = new st(m + 1, r);
    }
  }
  void update(int a, int b, line &L) {
    if (a > b) return;
    if (a == l && b == r) {
      trick.add(L);
    } else {
      if (b <= m)
        left->update(a, b, L);
      else if (a > m)
        right->update(a, b, L);
      else
        left->update(a, m, L), right->update(m + 1, b, L);
    }
  }
  long long get(int a, long long x) {
    long long R = trick.get_max(x);
    if (l == r) return R;
    if (a <= m) return max(R, left->get(a, x));
    return max(R, right->get(a, x));
  }
};
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n;
  while (cin >> n) {
    vector<int> from(n, n + 1), to(n, n);
    vector<line> v(n);
    vector<pair<int, int> > queries;
    for (int i = 0; i < n; i++) {
      int cmd;
      cin >> cmd;
      if (cmd == 1) cin >> v[i].m >> v[i].b, from[i] = i;
      if (cmd == 2) {
        int j;
        cin >> j;
        j--;
        to[j] = i;
      }
      if (cmd == 3) {
        long long x;
        cin >> x;
        queries.push_back({x, i});
      }
    }
    vector<int> order(n);
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(),
         [&](int a, int b) { return v[a].m < v[b].m; });
    st tree(0, n);
    for (int i = 0; i < n; i++) {
      int I = order[i];
      tree.update(from[I], to[I], v[I]);
    }
    for (auto &q : queries) {
      long long ans = tree.get(q.second, q.first);
      if (ans == LLONG_MIN)
        cout << "EMPTY SET" << '\n';
      else
        cout << ans << '\n';
    }
  }
}
