#include <bits/stdc++.h>
const int M = 1e5 + 7;
using namespace std;
inline int ri() {
  int x = 0;
  bool f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = 0;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - 48;
  return f ? x : -x;
}
int k, n, m;
long long a[M];
struct frac {
  long long x, y;
  int id;
  frac(long long _x = 0, long long _y = 0, int _id = 0) {
    x = _x, y = _y;
    id = _id;
  }
  long long val() const { return x / y; }
  long long rm() const { return x - y * (x / y); }
  friend bool operator<(const frac &x, const frac &y) {
    if (x.val() != y.val())
      return x.val() < y.val();
    else
      return x.rm() * y.y < y.rm() * x.y;
  }
};
int opr[M];
struct node {
  long long d, id;
  node(long long _d = 0, int _id = 0) {
    d = _d;
    id = _id;
  }
  bool operator<(const node &y) const { return d < y.d; }
};
node ass[M];
vector<node> add[M];
priority_queue<frac> q;
int ans[M], tt = 0;
int main() {
  int i, j, ty, x, y;
  k = ri(), n = ri(), m = ri();
  for (i = 1; i <= k; i++) a[i] = ri();
  for (i = 1; i <= n; i++) {
    ty = ri(), x = ri(), y = ri();
    opr[i] = ty;
    if (ty == 1) ass[x] = max(ass[x], node(y, i));
    if (ty == 2) add[x].push_back(node(y, i));
    if (ty == 3) q.push(frac(y, 1, i));
  }
  for (i = 1; i <= k; i++) {
    if (ass[i].d > a[i]) add[i].push_back(node(ass[i].d - a[i], ass[i].id));
    sort(add[i].begin(), add[i].end());
    long long nw = a[i];
    for (j = add[i].size() - 1; j >= 0; j--) {
      q.push(frac(nw + add[i][j].d, nw, add[i][j].id));
      nw += add[i][j].d;
    }
  }
  for (i = 1; i <= m && !q.empty(); i++) {
    ans[++tt] = q.top().id;
    q.pop();
  }
  printf("%d\n", tt);
  for (i = 1; i <= tt; i++)
    if (opr[ans[i]] == 1) printf("%d ", ans[i]);
  for (i = 1; i <= tt; i++)
    if (opr[ans[i]] == 2) printf("%d ", ans[i]);
  for (i = 1; i <= tt; i++)
    if (opr[ans[i]] == 3) printf("%d ", ans[i]);
  puts("");
  return 0;
}
