#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,unroll-loops,fast-math")
using namespace std;
long long poww(long long a, long long b, long long md) {
  return (!b ? 1
             : (b & 1 ? a * poww(a * a % md, b / 2, md) % md
                      : poww(a * a % md, b / 2, md) % md));
}
const int maxn = 2000 * 100 + 5;
const long long inf = 9223372036854775807;
const long long mod = 1e9 + 7;
long long n, q, a[maxn], pt[maxn], res, seg[4 * maxn], lz[2][4 * maxn],
    mn[4 * maxn], cnt = 0;
long long nxt(long long x) {
  res = 0;
  while (pt[res] < x) res++;
  return pt[res];
}
long long doj(long long x) { return nxt(x) - x; }
void shift(int x, int lx, int rx) {
  if (lz[0][x]) {
    seg[x] = lz[0][x];
    mn[x] = doj(seg[x]);
    if (rx - lx > 1) {
      lz[0][x << 1] = lz[0][x << 1 | 1] = lz[0][x];
      lz[1][x << 1] = lz[1][x << 1 | 1] = 0;
    }
    lz[0][x] = lz[1][x] = 0;
  }
  if (lz[1][x]) {
    if (!seg[x]) {
      mn[x] -= lz[1][x];
    } else {
      seg[x] += lz[1][x];
      mn[x] = doj(seg[x]);
    }
    if (rx - lx > 1) {
      if (lz[0][x << 1])
        lz[0][x << 1] += lz[1][x];
      else
        lz[1][x << 1] += lz[1][x];
      if (lz[0][x << 1 | 1])
        lz[0][x << 1 | 1] += lz[1][x];
      else
        lz[1][x << 1 | 1] += lz[1][x];
    }
    lz[1][x] = 0;
  }
}
void build(int x = 1, int lx = 1, int rx = n + 1) {
  if (rx - lx == 1) {
    mn[x] = doj(a[lx]);
    seg[x] = a[lx];
    return;
  }
  int mid = lx + rx >> 1;
  build(x << 1, lx, mid);
  build(x << 1 | 1, mid, rx);
  if (seg[x << 1] == seg[x << 1 | 1])
    seg[x] = seg[x << 1];
  else
    seg[x] = 0;
  mn[x] = min(mn[x << 1], mn[x << 1 | 1]);
}
void st(int l, int r, long long v, int x = 1, int lx = 1, int rx = n + 1) {
  shift(x, lx, rx);
  if (lx >= r || rx <= l) return;
  if (lx >= l && rx <= r) {
    lz[0][x] = v;
    shift(x, lx, rx);
    return;
  }
  int mid = lx + rx >> 1;
  st(l, r, v, x << 1, lx, mid);
  st(l, r, v, x << 1 | 1, mid, rx);
  if (seg[x << 1] == seg[x << 1 | 1])
    seg[x] = seg[x << 1];
  else
    seg[x] = 0;
  mn[x] = min(mn[x << 1], mn[x << 1 | 1]);
}
void upd(int l, int r, long long v, int x = 1, int lx = 1, int rx = n + 1) {
  shift(x, lx, rx);
  if (lx >= r || rx <= l) return;
  if (mn[x] >= v || seg[x] != 0) {
    if (lx >= l && rx <= r) {
      lz[1][x] += v;
      shift(x, lx, rx);
      return;
    }
  }
  int mid = lx + rx >> 1;
  upd(l, r, v, x << 1, lx, mid);
  upd(l, r, v, x << 1 | 1, mid, rx);
  if (seg[x << 1] == seg[x << 1 | 1])
    seg[x] = seg[x << 1];
  else
    seg[x] = 0;
  mn[x] = min(mn[x << 1], mn[x << 1 | 1]);
}
long long get(int i, int x = 1, int lx = 1, int rx = n + 1) {
  shift(x, lx, rx);
  if (rx - lx == 1) {
    return seg[x];
  }
  int mid = lx + rx >> 1;
  if (i < mid)
    return get(i, x << 1, lx, mid);
  else
    return get(i, x << 1 | 1, mid, rx);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ;
  pt[0] = 1;
  for (int i = 1; i < 12; i++) pt[i] = pt[i - 1] * (long long)42;
  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  build();
  long long type, l, r, v;
  while (q--) {
    cin >> type >> l;
    if (type == 1) {
      cout << get(l) << endl;
      continue;
    }
    cin >> r >> v;
    r++;
    if (type == 2) {
      st(l, r, v);
    }
    if (type == 3) {
      upd(l, r, v);
      while (mn[1] == 0) {
        upd(l, r, v);
      }
    }
  }
}
