#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 7, D = 10;
long long read() {
  long long w = 1, s = 0;
  char c;
  while (c = getchar(), c > '9' || c < '0')
    if (c == '-') w = -1;
  while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
  return w * s;
}
long long bin[20] = {1}, a[N];
long long n, m, flg;
struct tree {
  long long dw, tag;
  long long ad, mx;
} tr[N << 2], f;
void pushup(long long ts) {
  tr[ts].mx = min(tr[ts << 1].mx, tr[ts << 1 | 1].mx);
}
void pushdown(long long ts) {
  if (tr[ts].tag) {
    tr[ts << 1] = tr[ts << 1 | 1] = tr[ts];
    tr[ts].dw = tr[ts].mx = tr[ts].ad = tr[ts].tag = 0;
    return;
  }
  if (tr[ts].ad) {
    long long k = tr[ts].ad;
    tr[ts].ad = 0;
    tr[ts << 1].mx -= k;
    tr[ts << 1 | 1].mx -= k;
    tr[ts << 1].ad += k;
    tr[ts << 1 | 1].ad += k;
  }
}
void build(long long ts, long long l, long long r) {
  if (l == r) {
    long long k = lower_bound(bin, bin + D + 1, a[l]) - bin;
    tr[ts].dw = k;
    tr[ts].mx = bin[k] - a[l];
    tr[ts].tag = 1;
    return;
  }
  long long mid = (l + r) >> 1;
  build(ts << 1, l, mid);
  build(ts << 1 | 1, mid + 1, r);
  pushup(ts);
}
long long query(long long ts, long long l, long long r, long long k) {
  if (l == r || tr[ts].tag) return bin[tr[ts].dw] - tr[ts].mx;
  long long mid = (l + r) >> 1;
  pushdown(ts);
  if (k <= mid)
    return query(ts << 1, l, mid, k);
  else
    return query(ts << 1 | 1, mid + 1, r, k);
}
void change(long long ts, long long l, long long r, long long L, long long R,
            tree k) {
  if (l == L && r == R) {
    tr[ts] = k;
    return;
  }
  pushdown(ts);
  long long mid = (l + r) >> 1;
  if (R <= mid)
    change(ts << 1, l, mid, L, R, k);
  else if (L > mid)
    change(ts << 1 | 1, mid + 1, r, L, R, k);
  else
    change(ts << 1, l, mid, L, mid, k),
        change(ts << 1 | 1, mid + 1, r, mid + 1, R, k);
  pushup(ts);
}
bool change1(long long ts, long long l, long long r, long long L, long long R,
             long long k) {
  long long ans = 0;
  if (l == L && r == R) {
    if (tr[ts].mx > k) {
      tr[ts].mx -= k;
      tr[ts].ad += k;
      return 0;
    } else if (tr[ts].tag) {
      long long v = bin[tr[ts].dw] - tr[ts].mx + k,
                j = lower_bound(bin, bin + D + 1, v) - bin;
      tr[ts].mx = bin[j] - v;
      tr[ts].dw = j;
      if (tr[ts].mx == 0) ans = 1;
      return ans;
    }
  }
  pushdown(ts);
  long long mid = (l + r) >> 1;
  if (R <= mid)
    ans |= change1(ts << 1, l, mid, L, R, k);
  else if (L > mid)
    ans |= change1(ts << 1 | 1, mid + 1, r, L, R, k);
  else
    ans = change1(ts << 1, l, mid, L, mid, k) |
          change1(ts << 1 | 1, mid + 1, r, mid + 1, R, k);
  pushup(ts);
  return ans;
}
signed main() {
  for (long long i = 1; i <= 10; i++) bin[i] = bin[i - 1] * 42ll;
  n = read();
  m = read();
  for (long long i = 1; i <= n; i++) a[i] = read();
  build(1, 1, n);
  while (m--) {
    long long l, r, x, c;
    c = read();
    if (c == 1) {
      l = read();
      printf("%I64d\n", query(1, 1, n, l));
    } else if (c == 2) {
      l = read(), r = read(), x = read();
      long long k = lower_bound(bin, bin + D + 1, x) - bin;
      f.dw = k;
      f.mx = bin[k] - x;
      f.tag = 1;
      f.ad = 0;
      change(1, 1, n, l, r, f);
    } else {
      l = read(), r = read(), x = read();
      while (change1(1, 1, n, l, r, x))
        ;
    }
  }
}
