#include <bits/stdc++.h>
using namespace std;
long long read() {
  long long x = 0, f = 1, ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
  return f * x;
}
const long long maxn = 1000100, inf = 1000000000000000LL, mod = 998244353;
long long n, m, a[maxn];
long long x, y, c;
long long f[maxn], d[maxn], g[maxn], del[maxn], Max[maxn], mi[20], flag[maxn],
    level;
pair<long long, long long> ch(long long x) {
  for (long long i = (0); i <= (11); i++)
    if (x < mi[i]) return make_pair(i, x - mi[i]);
}
void upp(long long o) {
  while (f[o] > 0) {
    g[o]++;
    Max[o] = f[o] = Max[o] + mi[g[o] - 1] - mi[g[o]];
  }
}
void pushdown(long long x) {
  if (del[x]) {
    Max[x << 1] += del[x], Max[x << 1 | 1] += del[x];
    if (d[x << 1])
      f[x << 1] += del[x], upp(x << 1);
    else
      del[x << 1] += del[x];
    if (d[x << 1 | 1])
      f[x << 1 | 1] += del[x], upp(x << 1 | 1);
    else
      del[x << 1 | 1] += del[x];
    del[x] = 0;
  }
  if (d[x]) {
    Max[x << 1] = Max[x << 1 | 1] = f[x];
    del[x << 1] = del[x << 1 | 1] = 0;
    g[x << 1] = g[x << 1 | 1] = g[x];
    d[x << 1] = d[x << 1 | 1] = 1;
    f[x << 1] = f[x << 1 | 1] = f[x];
    d[x] = 0;
    f[x] = 0;
  }
}
void updata(long long x) {
  Max[x] = max(Max[x << 1], Max[x << 1 | 1]);
  g[x] = (Max[x << 1] > Max[x << 1 | 1]) ? g[x << 1] : g[x << 1 | 1];
  if (flag[x << 1] && flag[x << 1 | 1] && Max[x << 1] == Max[x << 1 | 1] &&
      g[x << 1] == g[x << 1 | 1])
    flag[x] = 1;
  else
    flag[x] = 0;
}
long long query(long long l, long long r, long long o) {
  if (l > y || r < x) return -inf;
  if (l >= x && r <= y) {
    level = g[o];
    return Max[o];
  }
  pushdown(o);
  return max(query(l, ((l + r) >> 1), o << 1),
             query(((l + r) >> 1) + 1, r, o << 1 | 1));
}
void change(long long l, long long r, long long o) {
  if (l > y || r < x) return;
  if (l >= x && r <= y) {
    d[o] = 1;
    flag[o] = 1;
    del[o] = 0;
    pair<long long, long long> x = ch(c);
    f[o] = x.second;
    Max[o] = x.second;
    g[o] = x.first;
    return;
  }
  pushdown(o);
  change(l, ((l + r) >> 1), o << 1);
  change(((l + r) >> 1) + 1, r, o << 1 | 1);
  updata(o);
}
void Change(long long l, long long r, long long o) {
  if (l > y || r < x) return;
  if (l >= x && r <= y) {
    Max[o] += c;
    if (d[o]) {
      f[o] += c;
      if (f[o] > 0) {
        while (Max[o] > 0) {
          g[o]++;
          Max[o] = f[o] = Max[o] + mi[g[o] - 1] - mi[g[o]];
        }
      }
    } else
      del[o] += c;
    return;
  }
  pushdown(o);
  Change(l, ((l + r) >> 1), o << 1);
  Change(((l + r) >> 1) + 1, r, o << 1 | 1);
  updata(o);
}
void upgrade(long long l, long long r, long long o) {
  if (flag[o]) {
    while (Max[o] > 0) {
      g[o]++;
      Max[o] = Max[o] + mi[g[o] - 1] - mi[g[o]];
    }
    return;
  }
  pushdown(o);
  if (Max[o << 1] > 0) upgrade(l, ((l + r) >> 1), o << 1);
  if (Max[o << 1 | 1] > 0) upgrade(((l + r) >> 1) + 1, r, o << 1 | 1);
  updata(o);
}
void build(long long l, long long r, long long o) {
  if (l == r) {
    flag[o] = 1;
    pair<long long, long long> x = ch(a[l]);
    Max[o] = x.second;
    g[o] = x.first;
    flag[o] = 1;
    return;
  }
  build(l, ((l + r) >> 1), o << 1);
  build(((l + r) >> 1) + 1, r, o << 1 | 1);
  updata(o);
}
int main() {
  n = read();
  m = read();
  mi[0] = 1;
  for (long long i = (1); i <= (11); i++) mi[i] = mi[i - 1] * 42;
  for (long long i = (1); i <= (n); i++) a[i] = read();
  build(1, n, 1);
  while (m--) {
    long long ch = read();
    if (ch == 1) {
      y = x = read();
      printf("%I64d\n", query(1, n, 1) + mi[level]);
    }
    if (ch == 2) {
      x = read(), y = read(), c = read();
      change(1, n, 1);
    }
    if (ch == 3) {
      x = read(), y = read(), c = read();
      do {
        Change(1, n, 1);
        upgrade(1, n, 1);
        if (Max[1] < 0) break;
      } while (1);
    }
  }
  return 0;
}
