#include <bits/stdc++.h>
using namespace std;
int n, m, lim;
int tot;
const int M = 100005;
struct Num {
  long long x, y;
  bool operator<(const Num& a) const { return x * a.y < y * a.x; }
};
struct node {
  int opt, id, to;
  Num val;
  bool operator<(const node& x) const { return val < x.val; }
} dat[M];
vector<node> G[M];
bool cmp1(node x, node y) {
  if (x.opt != y.opt) return x.opt < y.opt;
  return x.id < y.id;
}
int num[M];
int mark[M];
int use[M];
void solve() {
  priority_queue<node> Q;
  for (int u, v, w, i = 1; i <= m; i++) {
    Num val;
    scanf("%d%d%d", &u, &v, &w);
    if (u == 3) {
      val.x = w;
      val.y = 1;
      Q.push((node){u, i, v, val});
    } else {
      if (u == 1) val.x = w - num[v];
      if (u == 2) val.x = w;
      if (val.x < 0) continue;
      val.y = 1;
      G[v].push_back((node){u, i, v, val});
    }
  }
  for (int i = 1; i <= n; i++) {
    if (G[i].size()) {
      sort(G[i].begin(), G[i].end());
      use[i] = G[i].size();
      node pre = G[i][--use[i]];
      pre.val.y = num[i];
      pre.val.x += num[i];
      Q.push(pre);
    }
  }
  for (int i = 1; i <= min(lim, m); i++) {
    if (Q.empty()) break;
    node pre = Q.top();
    Q.pop();
    int to = pre.to;
    int opt = pre.opt;
    if (opt == 1 && mark[to]) continue;
    dat[tot++] = pre;
    if (opt != 3) {
      if (opt == 1) mark[to] = true;
      if (use[to]) {
        node nxt = G[to][--use[to]];
        nxt.val.y = pre.val.x;
        nxt.val.x += nxt.val.y;
        Q.push(nxt);
      }
    }
  }
  if (tot) sort(dat, dat + tot, cmp1);
  return;
}
int main() {
  scanf("%d%d%d", &n, &m, &lim);
  for (int i = 1; i <= n; i++) scanf("%d", &num[i]);
  solve();
  printf("%d\n", tot);
  for (int i = 0; i < tot; i++) printf("%d ", dat[i].id);
  return 0;
}
