#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long t = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c <= '9' && c >= '0') t = t * 10LL + c - 48LL, c = getchar();
  return t * f;
}
long long po[20];
long long n, q;
long long mn[500001], same[500001], tag[500001], tr[500001], a[500001];
inline long long get(long long x) {
  for (long long i = 0; i <= 11; ++i)
    if (po[i] > x) return i;
}
inline void push(long long x) {
  if (same[x]) {
    same[x << 1] = same[x << 1 | 1] = 1;
    mn[x << 1 | 1] = mn[x << 1] = mn[x];
    tr[x << 1] = tr[x << 1 | 1] = tr[x];
    tag[x] = 0;
    same[x] = 0;
  } else if (tag[x]) {
    tag[x << 1] += tag[x];
    tag[x << 1 | 1] += tag[x];
    mn[x << 1] -= tag[x];
    mn[x << 1 | 1] -= tag[x];
    tag[x] = 0;
  }
}
inline void up(long long x) { mn[x] = min(mn[x << 1], mn[x << 1 | 1]); }
inline void build(long long x, long long l, long long r) {
  if (l == r) {
    mn[x] = (tr[x] = po[get(a[l])]) - a[l];
    return;
  }
  long long mid = l + r >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
  up(x);
}
inline void cover(long long x, long long l, long long r, long long ql,
                  long long qr, long long del) {
  if (ql <= l && r <= qr) {
    same[x] = 1;
    mn[x] = get(del);
    tr[x] = po[mn[x]];
    mn[x] = po[mn[x]] - del;
    return;
  }
  push(x);
  long long mid = l + r >> 1;
  if (ql <= mid) cover(x << 1, l, mid, ql, qr, del);
  if (qr > mid) cover(x << 1 | 1, mid + 1, r, ql, qr, del);
  up(x);
}
inline bool add(long long x, long long l, long long r, long long ql,
                long long qr, long long del) {
  if (ql <= l && r <= qr && (del < mn[x] || same[x] || l == r)) {
    tag[x] += del;
    mn[x] -= del;
    if (mn[x] <= 0) {
      bool flag = 0;
      long long tmp = get(tr[x] - mn[x]);
      if (po[tmp - 1] == tr[x] - mn[x]) flag = 1;
      mn[x] = po[tmp] - (tr[x] - mn[x]);
      tr[x] = po[tmp];
      return flag;
    }
    return 0;
  }
  push(x);
  long long mid = l + r >> 1;
  bool tmp = 0;
  if (ql <= mid) tmp |= add(x << 1, l, mid, ql, qr, del);
  if (qr > mid) tmp |= add(x << 1 | 1, mid + 1, r, ql, qr, del);
  up(x);
  return tmp;
}
inline long long ask(long long x, long long l, long long r, long long to) {
  if (l == r || same[x]) return tr[x] - mn[x];
  push(x);
  long long mid = l + r >> 1;
  if (to <= mid)
    return ask(x << 1, l, mid, to);
  else
    return ask(x << 1 | 1, mid + 1, r, to);
}
long long opt, l, r, x;
int main() {
  n = read();
  q = read();
  po[0] = 1LL;
  for (long long i = 1; i <= 11; ++i) po[i] = po[i - 1] * 42LL;
  for (long long i = 1; i <= n; ++i) a[i] = read();
  build(1, 1, n);
  for (long long i = 1; i <= q; ++i) {
    opt = read();
    if (opt == 1) {
      x = read();
      printf("%I64d\n", ask(1, 1, n, x));
    } else {
      l = read();
      r = read();
      x = read();
      if (opt == 2) cover(1, 1, n, l, r, x);
      if (opt == 3)
        while (1)
          if (add(1, 1, n, l, r, x) == 0) break;
    }
  }
}
