#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void ckmax(T& x, T y) {
  x = (y > x ? y : x);
}
template <typename T>
inline void ckmin(T& x, T y) {
  x = (y < x ? y : x);
}
namespace Fread {
const int SIZE = 1 << 21;
char buf[SIZE], *S, *T;
inline char getchar() {
  if (S == T) {
    T = (S = buf) + fread(buf, 1, SIZE, stdin);
    if (S == T) return '\n';
  }
  return *S++;
}
}  // namespace Fread
namespace Fwrite {
const int SIZE = 1 << 21;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush() {
  fwrite(buf, 1, S - buf, stdout);
  S = buf;
}
inline void putchar(char c) {
  *S++ = c;
  if (S == T) flush();
}
struct NTR {
  ~NTR() { flush(); }
} ztr;
}  // namespace Fwrite
namespace Fastio {
struct Reader {
  template <typename T>
  Reader& operator>>(T& x) {
    char c = Fread ::getchar();
    T f = 1;
    while (c < '0' || c > '9') {
      if (c == '-') f = -1;
      c = Fread ::getchar();
    }
    x = 0;
    while (c >= '0' && c <= '9') {
      x = x * 10 + (c - '0');
      c = Fread ::getchar();
    }
    x *= f;
    return *this;
  }
  Reader& operator>>(char& c) {
    c = Fread ::getchar();
    while (c == '\n' || c == ' ') c = Fread ::getchar();
    return *this;
  }
  Reader& operator>>(char* str) {
    int len = 0;
    char c = Fread ::getchar();
    while (c == '\n' || c == ' ') c = Fread ::getchar();
    while (c != '\n' && c != ' ') {
      str[len++] = c;
      c = Fread ::getchar();
    }
    str[len] = '\0';
    return *this;
  }
  Reader() {}
} cin;
const char endl = '\n';
struct Writer {
  template <typename T>
  Writer& operator<<(T x) {
    if (x == 0) {
      Fwrite ::putchar('0');
      return *this;
    }
    if (x < 0) {
      Fwrite ::putchar('-');
      x = -x;
    }
    static int sta[45];
    int top = 0;
    while (x) {
      sta[++top] = x % 10;
      x /= 10;
    }
    while (top) {
      Fwrite ::putchar(sta[top] + '0');
      --top;
    }
    return *this;
  }
  Writer& operator<<(char c) {
    Fwrite ::putchar(c);
    return *this;
  }
  Writer& operator<<(char* str) {
    int cur = 0;
    while (str[cur]) Fwrite ::putchar(str[cur++]);
    return *this;
  }
  Writer& operator<<(const char* str) {
    int cur = 0;
    while (str[cur]) Fwrite ::putchar(str[cur++]);
    return *this;
  }
  Writer() {}
} cout;
}  // namespace Fastio
const int MAXN = 1e5;
const int BASE_NUM = 42;
const long long LL_INF = 1e18;
int n, q, a[MAXN + 5];
set<int> interesting;
class SegmentTree {
 private:
  int n;
  long long arr[MAXN + 5];
  int pow_idx[MAXN + 5];
  long long pow_val[MAXN + 5];
  long long mn[MAXN * 4 + 5];
  int mnpos[MAXN * 4 + 5];
  long long tag_add[MAXN * 4 + 5];
  void addv(int p, long long v) {
    mn[p] += v;
    tag_add[p] += v;
  }
  void update_pow(int i) {
    while (pow_val[i] < arr[i]) {
      pow_idx[i]++;
      pow_val[i] *= BASE_NUM;
    }
  }
  void push_up(int p) {
    if (mn[p << 1] <= mn[p << 1 | 1]) {
      mn[p] = mn[p << 1];
      mnpos[p] = mnpos[p << 1];
    } else {
      mn[p] = mn[p << 1 | 1];
      mnpos[p] = mnpos[p << 1 | 1];
    }
  }
  void push_down(int p) {
    if (tag_add[p]) {
      addv(p << 1, tag_add[p]);
      addv(p << 1 | 1, tag_add[p]);
      tag_add[p] = 0;
    }
  }
  void build(int p, int l, int r) {
    tag_add[p] = 0;
    if (l == r) {
      pow_idx[l] = 0;
      pow_val[l] = 1;
      update_pow(l);
      mn[p] = pow_val[l] - arr[l];
      assert(mn[p] != 0);
      mnpos[p] = l;
      return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    push_up(p);
  }
  void range_add_diff(int p, int l, int r, int ql, int qr, long long v) {
    if (ql <= l && qr >= r) {
      addv(p, v);
      return;
    }
    push_down(p);
    int mid = (l + r) >> 1;
    if (ql <= mid) {
      range_add_diff(p << 1, l, mid, ql, qr, v);
    }
    if (qr > mid) {
      range_add_diff(p << 1 | 1, mid + 1, r, ql, qr, v);
    }
    push_up(p);
  }
  void point_set_real(int p, int l, int r, int pos, long long v) {
    if (l == r) {
      arr[l] = v;
      pow_idx[l] = 0;
      pow_val[l] = 1;
      update_pow(l);
      mn[p] = pow_val[l] - arr[l];
      return;
    }
    push_down(p);
    int mid = (l + r) >> 1;
    if (pos <= mid) {
      point_set_real(p << 1, l, mid, pos, v);
    } else {
      point_set_real(p << 1 | 1, mid + 1, r, pos, v);
    }
    push_up(p);
  }
  void kill_neg_diff(int p, int l, int r) {
    if (mn[p] >= 0) {
      return;
    }
    if (l == r) {
      arr[l] = pow_val[l] - mn[p];
      update_pow(l);
      mn[p] = pow_val[l] - arr[l];
      return;
    }
    push_down(p);
    int mid = (l + r) >> 1;
    kill_neg_diff(p << 1, l, mid);
    kill_neg_diff(p << 1 | 1, mid + 1, r);
    push_up(p);
  }
  long long point_query_real(int p, int l, int r, int pos) {
    if (l == r) {
      arr[l] = pow_val[l] - mn[p];
      return arr[l];
    }
    push_down(p);
    int mid = (l + r) >> 1;
    if (pos <= mid) {
      return point_query_real(p << 1, l, mid, pos);
    } else {
      return point_query_real(p << 1 | 1, mid + 1, r, pos);
    }
  }

 public:
  template <typename T>
  void build(T* _arr, int _n) {
    n = _n;
    for (int i = 1; i <= n; ++i) arr[i] = _arr[i];
    build(1, 1, n);
  }
  void range_add_diff(int l, int r, long long v) {
    range_add_diff(1, 1, n, l, r, v);
  }
  void point_set_real(int p, long long v) { point_set_real(1, 1, n, p, v); }
  void kill_neg_diff() { kill_neg_diff(1, 1, n); }
  long long global_query_min_diff() { return mn[1]; }
  long long point_query_real(int pos) { return point_query_real(1, 1, n, pos); }
  SegmentTree() {}
};
SegmentTree T;
long long re_insert(int i, bool need_ret = 0) {
  if (interesting.count(i)) {
    return (need_ret ? T.point_query_real(i) : -1);
  }
  assert(i < n);
  set<int>::iterator it = interesting.upper_bound(i);
  assert(it != interesting.end());
  long long v = T.point_query_real(*it);
  T.point_set_real(i, v);
  interesting.insert(i);
  return (need_ret ? v : -2);
}
int main() {
  Fastio ::cin >> n >> q;
  for (int i = 1; i <= n; ++i) {
    Fastio ::cin >> a[i];
    interesting.insert(i);
  }
  T.build(a, n);
  for (int tq = 1; tq <= q; ++tq) {
    int op;
    Fastio ::cin >> op;
    if (op == 1) {
      int pos;
      Fastio ::cin >> pos;
      Fastio ::cout << re_insert(pos, true) << Fastio ::endl;
    } else if (op == 2) {
      int l, r;
      long long to_set;
      Fastio ::cin >> l >> r >> to_set;
      re_insert(r);
      if (l > 1) re_insert(l - 1);
      T.point_set_real(r, to_set);
      while (1) {
        set<int>::iterator it = interesting.lower_bound(l);
        assert(it != interesting.end());
        if ((*it) == r) {
          break;
        }
        T.point_set_real(*it, -LL_INF);
        interesting.erase(it);
      }
    } else {
      int l, r;
      long long to_add;
      Fastio ::cin >> l >> r >> to_add;
      re_insert(r);
      if (l > 1) re_insert(l - 1);
      do {
        T.range_add_diff(l, r, -to_add);
        T.kill_neg_diff();
        assert(T.global_query_min_diff() >= 0);
      } while (T.global_query_min_diff() == 0);
    }
  }
  return 0;
}
