#include <bits/stdc++.h>
using namespace std;
int n, q, a[100005];
long long pow42[] = {1ll,
                     42ll,
                     1764ll,
                     74088ll,
                     3111696ll,
                     130691232ll,
                     5489031744ll,
                     230539333248ll,
                     9682651996416ll,
                     406671383849472ll,
                     17080198121677824ll,
                     717368321110468608ll};
struct tree {
  long long v[100005 << 2], f[100005 << 2], ma[100005 << 2];
  int po[100005 << 2];
  void build(int l, int r, int id) {
    if (l == r) {
      v[id] = a[l];
      for (int i = 0; i <= 11; i++)
        if (pow42[i] > a[l]) {
          po[id] = i;
          ma[id] = a[l] - pow42[i];
          break;
        }
      return;
    }
    int g = ((l + r) >> 1);
    build(l, g, id << 1);
    build(g + 1, r, (id << 1) | 1);
    ma[id] = max(ma[id << 1], ma[(id << 1) | 1]);
  }
  void push(int id) {
    if (v[id]) {
      v[id << 1] = v[(id << 1) | 1] = v[id];
      f[id << 1] = f[(id << 1) | 1] = 0;
      for (int i = 0; i <= 11; i++)
        if (pow42[i] >= v[id << 1]) {
          ma[id << 1] = ma[(id << 1) | 1] = v[id << 1] - pow42[i];
          po[id << 1] = po[(id << 1) | 1] = i;
          break;
        }
      v[id] = 0;
    }
    if (f[id]) {
      if (v[id << 1])
        v[id << 1] += f[id];
      else
        f[id << 1] += f[id];
      if (v[(id << 1) | 1])
        v[(id << 1) | 1] += f[id];
      else
        f[(id << 1) | 1] += f[id];
      ma[id << 1] += f[id];
      ma[(id << 1) | 1] += f[id];
      f[id] = 0;
    }
  }
  void update(int l, int r, int id, int x, int y, long long val) {
    if (l > y || r < x) return;
    if (x <= l && r <= y) {
      v[id] = val;
      f[id] = 0;
      for (int i = 0; i <= 11; i++)
        if (pow42[i] >= val) {
          po[id] = i;
          ma[id] = val - pow42[i];
          break;
        }
      return;
    }
    push(id);
    int g = ((l + r) >> 1);
    update(l, g, id << 1, x, y, val);
    update(g + 1, r, (id << 1) | 1, x, y, val);
    ma[id] = max(ma[id << 1], ma[(id << 1) | 1]);
  }
  void add(int l, int r, int id, int x, int y, long long val) {
    if (l > y || r < x) return;
    if (x <= l && r <= y) {
      if (v[id])
        v[id] += val;
      else
        f[id] += val;
      ma[id] += val;
      return;
    }
    push(id);
    int g = ((l + r) >> 1);
    add(l, g, id << 1, x, y, val);
    add(g + 1, r, (id << 1) | 1, x, y, val);
    ma[id] = max(ma[id << 1], ma[(id << 1) | 1]);
  }
  void fix(int l, int r, int id) {
    if (ma[id] <= 0) return;
    if (l == r) {
      while (ma[id] > 0) {
        ma[id] -= pow42[po[id] + 1] - pow42[po[id]];
        po[id]++;
      }
      return;
    }
    push(id);
    int g = ((l + r) >> 1);
    fix(l, g, id << 1);
    fix(g + 1, r, (id << 1) | 1);
    ma[id] = max(ma[id << 1], ma[(id << 1) | 1]);
  }
  long long get(int l, int r, int id, int x) {
    if (l > x || r < x) return 0;
    if (l == r) return ma[id] + pow42[po[id]];
    push(id);
    int g = ((l + r) >> 1);
    return get(l, g, id << 1, x) + get(g + 1, r, (id << 1) | 1, x);
  }
} t;
void setup() {
  cin >> n >> q;
  for (int i = 1; i <= n; i++) cin >> a[i];
  t.build(1, n, 1);
}
void querry1() {
  int x;
  cin >> x;
  cout << t.get(1, n, 1, x) << '\n';
}
void querry2() {
  int x, y;
  long long v;
  cin >> x >> y >> v;
  t.update(1, n, 1, x, y, v);
}
void querry3() {
  int x, y;
  long long v;
  cin >> x >> y >> v;
  do {
    t.add(1, n, 1, x, y, v);
    t.fix(1, n, 1);
  } while (t.ma[1] == 0);
}
void xuly() {
  int type;
  for (int i = 1; i <= q; i++) {
    cin >> type;
    if (type == 1) querry1();
    if (type == 2) querry2();
    if (type == 3) querry3();
  }
}
int main() {
  iostream::sync_with_stdio(0);
  cin.tie(NULL);
  cout.tie(NULL);
  setup();
  xuly();
  return 0;
}
