#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read(register T& t) {
  register T f = 1;
  register char ch = getchar();
  t = 0;
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -f;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') t = t * 10 + ch - '0', ch = getchar();
  t *= f;
  return t;
}
template <typename T, typename... Args>
inline void read(T& t, Args&... args) {
  read(t);
  read(args...);
}
const long long p = 998244353;
inline long long power(register long long x, register long long k = p - 2) {
  register long long re = 1;
  for (; k; k >>= 1, x = x * x % p)
    if (k & 1) re = re * x % p;
  return re;
}
int n, Q;
inline pair<long long, long long> solve(pair<long long, long long> x) {
  long long tv = x.second - x.first;
  while (x.second < tv) x.second *= 42;
  return make_pair(x.second - tv, x.second);
}
inline pair<long long, long long> solve(long long x) {
  return solve(make_pair(1 - x, 1));
}
inline pair<long long, long long> solve(pair<long long, long long> x,
                                        long long y) {
  return solve(make_pair(x.first + y, x.second));
}
struct SGT {
  int lcs, rcs;
  pair<long long, long long> value;
  long long lazy;
  long long rever;
} v[200005];
int tot;
long long a[100005];
void build(int l, int r, int& p) {
  p = ++tot;
  v[p].rever = -1;
  v[p].lazy = 0;
  if (l == r) return v[p].value = solve(a[l]), void();
  build(l, ((l + r) >> 1), v[p].lcs);
  build(((l + r) >> 1) + 1, r, v[p].rcs);
  v[p].value = min(v[v[p].lcs].value, v[v[p].rcs].value);
}
void push_down(int l, int r, int p) {
  if (v[p].rever != -1) {
    v[v[p].lcs].lazy = 0;
    v[v[p].rcs].lazy = 0;
    v[v[p].lcs].rever = v[p].rever;
    v[v[p].rcs].rever = v[p].rever;
    v[v[p].lcs].value = solve(v[p].rever);
    v[v[p].rcs].value = solve(v[p].rever);
    v[p].rever = -1;
  }
  if (v[p].lazy != 0) {
    v[v[p].lcs].lazy += v[p].lazy;
    v[v[p].rcs].lazy += v[p].lazy;
    v[v[p].lcs].value = solve(v[v[p].lcs].value, v[p].lazy);
    v[v[p].rcs].value = solve(v[v[p].rcs].value, v[p].lazy);
    v[p].lazy = 0;
  }
}
void revise(int l, int r, int p, int nl, int nr, int vals) {
  if (nl <= l && r <= nr) {
    v[p].rever = vals;
    v[p].lazy = 0;
    v[p].value = solve(vals);
    return;
  }
  push_down(l, r, p);
  if (nl <= ((l + r) >> 1)) revise(l, ((l + r) >> 1), v[p].lcs, nl, nr, vals);
  if (((l + r) >> 1) + 1 <= nr)
    revise(((l + r) >> 1) + 1, r, v[p].rcs, nl, nr, vals);
  v[p].value = min(v[v[p].lcs].value, v[v[p].rcs].value);
}
void dfs(int l, int r, int p, int nl, int nr, int vals) {
  if (nl <= l && r <= nr) {
    if (v[p].value.first - vals >= 0) {
      v[p].lazy -= vals;
      v[p].value.first -= vals;
      return;
    }
    if (v[p].rever != -1 || l == r) {
      v[p].lazy -= vals;
      v[p].value.first -= vals;
      v[p].value = solve(v[p].value);
      return;
    }
  }
  push_down(l, r, p);
  if (nl <= ((l + r) >> 1)) dfs(l, ((l + r) >> 1), v[p].lcs, nl, nr, vals);
  if (((l + r) >> 1) + 1 <= nr)
    dfs(((l + r) >> 1) + 1, r, v[p].rcs, nl, nr, vals);
  v[p].value = min(v[v[p].lcs].value, v[v[p].rcs].value);
}
long long enquire(int l, int r, int p, int pos) {
  if (l == r) return v[p].value.second - v[p].value.first;
  push_down(l, r, p);
  return pos <= ((l + r) >> 1) ? enquire(l, ((l + r) >> 1), v[p].lcs, pos)
                               : enquire(((l + r) >> 1) + 1, r, v[p].rcs, pos);
}
int main() {
  read(n, Q);
  for (int i = 1; i <= n; i++) read(a[i]);
  int root;
  build(1, n, root);
  while (Q--) {
    int opt;
    read(opt);
    if (opt == 1) {
      int x;
      read(x);
      printf("%lld\n", enquire(1, n, 1, x));
    }
    if (opt == 2) {
      int l, r, x;
      read(l, r, x);
      revise(1, n, 1, l, r, x);
    }
    if (opt == 3) {
      int l, r, x;
      read(l, r, x);
      dfs(1, n, 1, l, r, x);
      while (v[1].value.first == 0) dfs(1, n, 1, l, r, x);
    }
  }
  return 0;
}
