#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
const int oo = 0x3f3f3f3f;
const int maxn = 100000, maxlog = 12;
long long pw[maxlog];
int n, qn;
long long a[maxn + 5];
struct lab_type {
  bool ty;
  long long val;
  lab_type() : ty(0), val(0) {}
  lab_type(int _ty, const long long &_val) : ty(_ty), val(_val) {}
  bool empty() { return !ty && !val; }
  friend lab_type &operator+=(lab_type &first, const lab_type &second) {
    if (second.ty) return first = second;
    if (!first.ty || first.val) first.val += second.val;
    return first;
  }
  friend long long &operator+=(long long &first, const lab_type &second) {
    if (second.ty) return first = second.val;
    if (!first) return first;
    return first += second.val;
  }
};
struct node {
  node *c[2];
  long long Max;
  lab_type label;
  node() : Max(0) { memset(c, 0, sizeof c); }
  void update() {
    Max = 0;
    for (int i = (0), _end_ = (2); i < _end_; ++i)
      if (c[i]) chkmax(Max, c[i]->Max);
  }
  void flag_label(const lab_type &_label) {
    label += _label;
    Max += _label;
  }
  void push_down() {
    if (!label.empty()) {
      for (int i = (0), _end_ = (2); i < _end_; ++i)
        if (c[i]) c[i]->flag_label(label);
      label = lab_type();
    }
  }
};
const int max0 = 100000;
node *nd_pool;
int nd_res = 0;
node *newnode() {
  if (!nd_res) nd_pool = new node[max0], nd_res = max0;
  return nd_pool + (--nd_res);
}
node *rt[maxlog];
int seg_x, seg_y;
lab_type seg_z;
long long seg_ret;
int seg_id;
void add(node *&rt, int l, int r) {
  if (seg_x <= l && r <= seg_y) {
    rt->flag_label(seg_z);
    return;
  }
  int mid = (l + r) >> 1;
  rt->push_down();
  if (seg_x < mid) add(rt->c[0], l, mid);
  if (seg_y > mid) add(rt->c[1], mid, r);
  rt->update();
}
void doit(node *rt, int l, int r) {
  if (!rt) return;
  if (rt->Max <= pw[seg_id]) return;
  if (r - l <= 1) {
    rt->Max = 0;
    return;
  }
  if (rt->label.ty) {
    rt->flag_label(lab_type(1, 0));
    return;
  }
  rt->push_down();
  int mid = (l + r) >> 1;
  doit(rt->c[0], l, mid);
  doit(rt->c[1], mid, r);
  rt->update();
}
void query(node *rt, int l, int r) {
  if (!rt) return;
  if (seg_x <= l && r <= seg_y) {
    chkmax(seg_ret, rt->Max);
    return;
  }
  rt->push_down();
  int mid = (l + r) >> 1;
  if (seg_x < mid) query(rt->c[0], l, mid);
  if (seg_y > mid) query(rt->c[1], mid, r);
  rt->update();
}
void build(node *&rt, int l, int r) {
  if (!rt) rt = newnode();
  if (r - l <= 1) {
    if (a[l] <= pw[seg_id])
      rt->Max = a[l];
    else
      rt->Max = 0;
    return;
  }
  rt->push_down();
  int mid = (l + r) >> 1;
  build(rt->c[0], l, mid);
  build(rt->c[1], mid, r);
  rt->update();
}
int main() {
  pw[0] = 1;
  for (int i = (1), _end_ = (maxlog); i < _end_; ++i) pw[i] = pw[i - 1] * 42;
  scanf("%d%d", &n, &qn);
  for (int i = (0), _end_ = (n); i < _end_; ++i) scanf("%I64d", a + i);
  for (int i = (0), _end_ = (maxlog); i < _end_; ++i) {
    seg_id = i;
    build(rt[i], 0, n);
  }
  for (int i = (0), _end_ = (qn); i < _end_; ++i) {
    int ty, l, r, first;
    scanf("%d", &ty);
    if (ty == 1) {
      scanf("%d", &first), --first;
      seg_x = first, seg_y = first + 1, seg_ret = 0;
      query(rt[maxlog - 1], 0, n);
      printf("%I64d\n", seg_ret);
    } else {
      scanf("%d%d%d", &l, &r, &first), --l;
      seg_x = l, seg_y = r;
      if (ty == 2) {
        seg_z = lab_type(1, first);
        for (int i = maxlog - 1; i >= 0; --i) {
          if (first > pw[i]) seg_z.val = 0;
          add(rt[i], 0, n);
        }
      } else {
        static long long Max[maxlog];
        static long long cnt[maxlog];
        for (int i = (0), _end_ = (maxlog); i < _end_; ++i) {
          seg_ret = 0;
          query(rt[i], 0, n);
          Max[i] = seg_ret;
          cnt[i] = 0;
        }
        while (1) {
          bool ok = 1;
          for (int i = (0), _end_ = (maxlog); i < _end_; ++i) {
            cnt[i] += first;
            if (Max[i] && Max[i] + cnt[i] > pw[i]) {
              seg_z = lab_type(0, cnt[i]);
              add(rt[i], 0, n);
              cnt[i] = 0;
              seg_id = i;
              doit(rt[i], 0, n);
              seg_ret = 0;
              query(rt[i], 0, n);
              Max[i] = seg_ret;
            }
            if (Max[i] && Max[i] + cnt[i] == pw[i]) ok = 0;
          }
          if (ok) break;
        }
        for (int i = (0), _end_ = (maxlog); i < _end_; ++i)
          if (cnt[i]) {
            seg_z = lab_type(0, cnt[i]), add(rt[i], 0, n), cnt[i] = 0;
            assert(rt[i]->Max != pw[i]);
          }
      }
    }
  }
  return 0;
}
