#include <bits/stdc++.h>
using namespace std;
const long long N = 100005;
struct data {
  long long s, add, d, pos;
} a[N * 4];
long long n, q, x, y, z, w, b[100];
inline void pushup(long long x) {
  if (a[x * 2].d < a[x * 2 + 1].d) {
    a[x].d = a[x * 2].d;
    a[x].pos = a[x * 2].pos;
  } else {
    a[x].d = a[x * 2 + 1].d;
    a[x].pos = a[x * 2 + 1].pos;
  }
}
void build(long long l, long long r, long long x) {
  if (l == r) {
    scanf("%I64d", &a[x].s);
    a[x].d = *lower_bound(b + 1, b + 1 + b[0], a[x].s) - a[x].s;
    a[x].pos = l;
    return;
  }
  long long mid = (l + r) / 2;
  build(l, mid, x * 2);
  build(mid + 1, r, x * 2 + 1);
  pushup(x);
}
inline void fg(long long y, long long x) {
  a[x].add = 0;
  a[x].s = y;
  a[x].d = *lower_bound(b + 1, b + 1 + b[0], a[x].s) - a[x].s;
}
inline void add(long long y, long long x) {
  if (a[x].s)
    fg(y + a[x].s, x);
  else {
    a[x].add += y;
    a[x].d -= y;
  }
}
inline void pushdown(long long x) {
  if (a[x].s) {
    fg(a[x].s, x * 2);
    fg(a[x].s, x * 2 + 1);
  } else {
    if (a[x].add) {
      add(a[x].add, x * 2);
      add(a[x].add, x * 2 + 1);
    }
  }
  a[x].add = a[x].s = 0;
  pushup(x);
}
long long getsum(long long l, long long r, long long k, long long x) {
  if (l == r) return a[x].s;
  pushdown(x);
  long long mid = (l + r) / 2;
  if (k <= mid)
    return getsum(l, mid, k, x * 2);
  else
    return getsum(mid + 1, r, k, x * 2 + 1);
}
void change(long long l, long long r, long long L, long long R, long long k,
            long long x) {
  if (l == L && r == R) {
    fg(k, x);
    return;
  }
  pushdown(x);
  long long mid = (l + r) / 2;
  if (R <= mid) change(l, mid, L, R, k, x * 2);
  if (L > mid) change(mid + 1, r, L, R, k, x * 2 + 1);
  if (R > mid && L <= mid) {
    change(l, mid, L, mid, k, x * 2);
    change(mid + 1, r, mid + 1, R, k, x * 2 + 1);
  }
  pushup(x);
}
void addto(long long l, long long r, long long L, long long R, long long k,
           long long x) {
  if (l == L && r == R) {
    add(k, x);
    return;
  }
  pushdown(x);
  long long mid = (l + r) / 2;
  if (R <= mid) addto(l, mid, L, R, k, x * 2);
  if (L > mid) addto(mid + 1, r, L, R, k, x * 2 + 1);
  if (R > mid && L <= mid) {
    addto(l, mid, L, mid, k, x * 2);
    addto(mid + 1, r, mid + 1, R, k, x * 2 + 1);
  }
  pushup(x);
}
void reset(long long l, long long r, long long y, long long x) {
  if (l <= y && y <= r && a[x].s) {
    a[x].d = *lower_bound(b + 1, b + 1 + b[0], a[x].s) - a[x].s;
    return;
  }
  pushdown(x);
  long long mid = (l + r) / 2;
  if (y <= mid)
    reset(l, mid, y, x * 2);
  else
    reset(mid + 1, r, y, x * 2 + 1);
  pushup(x);
}
long long getpos(long long l, long long r, long long L, long long R,
                 long long x) {
  if (l == L && r == R)
    return a[x].d < 0 ? -a[x].pos : a[x].d == 0 ? 0 : a[x].pos;
  pushdown(x);
  long long mid = (l + r) / 2;
  if (R <= mid) return getpos(l, mid, L, R, x * 2);
  if (L > mid) return getpos(mid + 1, r, L, R, x * 2 + 1);
  return min(getpos(l, mid, L, mid, x * 2),
             getpos(mid + 1, r, mid + 1, R, x * 2 + 1));
}
signed main() {
  scanf("%d%d", &n, &q);
  for (long long i = 1; i <= (long long)1e17; i *= 42LL) b[++b[0]] = i;
  build(1, n, 1);
  while (q--) {
    scanf("%d%d", &x, &y);
    if (x == 1) {
      printf("%I64d\n", getsum(1, n, y, 1));
    }
    if (x == 2) {
      scanf("%d%d", &z, &w);
      change(1, n, y, z, w, 1);
    }
    if (x == 3) {
      scanf("%d%d", &z, &w);
      long long k;
      do {
        addto(1, n, y, z, w, 1);
        k = getpos(1, n, y, z, 1);
        while (k < 0) {
          reset(1, n, -k, 1);
          k = getpos(1, n, y, z, 1);
        }
      } while (k == 0);
    }
  }
  return 0;
}
