2 8
2 15 400
1 13 100
3 26
3 27
3 28
3 29
3 30
3 31
3 32
3 33
 3 8
2 15 400
1 1 200
1 13 100
3 26
3 27
3 28
3 29
3 30
3 31
3 32
3 33

400
400
500
500
800
800
800
800
 600
600
600
700
800
1000
1000
1000

#include <bits/stdc++.h>
using namespace std;
struct fast_ios {
  fast_ios() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  };
} fast_ios_;
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (long long i = 0; i < v.size(); i++) {
    cout << v[i];
    if (i != v.size() - 1) cout << endl;
  };
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, pair<T1, T2> p) {
  cout << '(' << p.first << ',' << p.second << ')';
  return os;
}
template <typename T>
void Out(T x) {
  cout << x << endl;
}
template <typename T1, typename T2>
void chOut(bool f, T1 y, T2 n) {
  if (f)
    Out(y);
  else
    Out(n);
}
using vec = vector<long long>;
using mat = vector<vec>;
using Pii = pair<long long, long long>;
using v_bool = vector<bool>;
using v_Pii = vector<Pii>;
using PPi = pair<Pii, long long>;
using v_PPi = vector<PPi>;
const long long mod = 1000000007;
struct SegmentTree {
  using T = long long;
  long long N;
  vector<T> dat;
  T id = 0;
  T F(T &a, T &b) { return a + b; }
  SegmentTree(long long n) {
    N = 1;
    while (n > N) N = N << 1;
    dat = vector<T>(2 * N - 1, id);
  }
  SegmentTree(long long n, vector<T> &v) {
    N = 1;
    while (n > N) N = N << 1;
    dat = vector<T>(2 * N - 1, id);
    for (long long i = 0; i < n; i++) dat[i + N - 1] = v[i];
    for (long long i = N - 2; i >= 0; i--)
      dat[i] = F(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  SegmentTree() {}
  void update(long long k, T a) {
    k += N - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = F(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  void reset() { fill(dat.begin(), dat.end(), id); }
  T get(long long a, long long b, long long k, long long l, long long r) {
    if (r <= a || b <= l) return id;
    if (a <= l && r <= b)
      return dat[k];
    else {
      T vl = get(a, b, k * 2 + 1, l, (l + r) / 2);
      T vr = get(a, b, k * 2 + 2, (l + r) / 2, r);
      return F(vl, vr);
    }
  }
  T get(long long a, long long b) { return get(a, b, 0, 0, N); }
  T val(long long k) { return dat[k + N - 1]; }
};
signed main() {
  long long n, q;
  cin >> n >> q;
  vec a(n), w(n), v(n);
  v_PPi p(n);
  for (long long i = (0); i < (n); i++) {
    cin >> a[i] >> w[i] >> v[i];
    p[i] = PPi(Pii(-v[i], w[i]), i);
  }
  sort(p.begin(), p.end());
  vec pos(n);
  for (long long i = (0); i < (n); i++) pos[p[i].second] = i;
  SegmentTree STv(n), STw(n);
  for (long long i = (0); i < (n); i++) {
    long long i0 = pos[i];
    STv.update(i0, a[i] * v[i]);
    STw.update(i0, a[i] * w[i]);
  }
  for (long long _ = (0); _ < (q); _++) {
    long long t;
    cin >> t;
    if (t == 1 || t == 2) {
      long long k, d;
      cin >> k >> d;
      d--;
      if (t == 1)
        a[d] += k;
      else
        a[d] -= k;
      long long i0 = pos[d];
      STv.update(i0, a[d] * v[d]);
      STw.update(i0, a[d] * w[d]);
    } else {
      long long c;
      cin >> c;
      long long ok = 0, ng = n + 1;
      while (ng - ok > 1) {
        long long x = (ok + ng) / 2;
        if (STw.get(0, x) <= c)
          ok = x;
        else
          ng = x;
      }
      long long ans = STv.get(0, ok);
      c -= STw.get(0, ok);
      if (ok < n) {
        long long i = p[ok].second;
        ans += v[i] * (c / w[i]);
      }
      cout << ans << '\n';
    }
  }
  return 0;
}
