#include <bits/stdc++.h>
using namespace std;
const int mod = 1000 * 1000 * 1000 + 7;
const int INF = 1e9 + 100;
const long long LINF = 1e18 + 100;
const long long p42[] = {1,
                         42,
                         1764,
                         74088,
                         3111696,
                         130691232,
                         5489031744,
                         230539333248,
                         9682651996416,
                         406671383849472,
                         17080198121677824,
                         717368321110468608};
const int c42 = sizeof(p42) / sizeof(p42[0]);
struct node {
  long long mindif, minpos;
  long long curpow;
  long long lz;
};
int n, q;
int a[100100];
node seg[4 * 100100];
set<int> s;
inline void update(int v, int lc, int rc) {
  seg[v].mindif = min(seg[lc].mindif, seg[rc].mindif);
  if (seg[lc].mindif == seg[v].mindif)
    seg[v].minpos = seg[lc].minpos;
  else
    seg[v].minpos = seg[rc].minpos;
}
inline void pushdown(int v) {
  if (!seg[v].lz) return;
  long long &x = seg[v].lz;
  node &lc = seg[2 * v];
  node &rc = seg[2 * v + 1];
  lc.lz += x;
  rc.lz += x;
  lc.mindif -= x;
  rc.mindif -= x;
  x = 0;
}
void build(int v = 1, int l = 0, int r = n - 1) {
  if (l == r) {
    if (s.find(l) == s.end()) {
      seg[v].mindif = LINF;
      seg[v].minpos = l;
      return;
    }
    seg[v].curpow = *upper_bound(p42, p42 + c42, a[l]);
    seg[v].mindif = seg[v].curpow - a[l];
    seg[v].minpos = l;
    return;
  }
  int mid = (r + l) / 2;
  build(2 * v, l, mid);
  build(2 * v + 1, mid + 1, r);
  update(v, 2 * v, 2 * v + 1);
}
void setind(int i, long long x, int v = 1, int l = 0, int r = n - 1) {
  if (l == r) {
    if (x == -1) {
      long long val = seg[v].curpow - seg[v].mindif;
      seg[v].curpow = *lower_bound(p42, p42 + c42, val);
      seg[v].mindif = seg[v].curpow - val;
      return;
    } else if (x == -2) {
      seg[v].mindif = LINF;
      return;
    } else {
      seg[v].curpow = *lower_bound(p42, p42 + c42, x);
      seg[v].mindif = seg[v].curpow - x;
      return;
    }
    return;
  }
  int mid = (r + l) / 2;
  pushdown(v);
  if (i <= mid)
    setind(i, x, 2 * v, l, mid);
  else
    setind(i, x, 2 * v + 1, mid + 1, r);
  update(v, 2 * v, 2 * v + 1);
}
long long getind(int i, int v = 1, int l = 0, int r = n - 1) {
  if (l == r) return seg[v].curpow - seg[v].mindif;
  int mid = (r + l) / 2;
  pushdown(v);
  if (i <= mid) return getind(i, 2 * v, l, mid);
  return getind(i, 2 * v + 1, mid + 1, r);
}
void add(int L, int R, int x, int v = 1, int l = 0, int r = n - 1) {
  if (l > R || r < L) return;
  if (l >= L && r <= R) {
    seg[v].lz += x;
    seg[v].mindif -= x;
    return;
  }
  int mid = (r + l) / 2;
  pushdown(v);
  add(L, R, x, 2 * v, l, mid);
  add(L, R, x, 2 * v + 1, mid + 1, r);
  update(v, 2 * v, 2 * v + 1);
}
int32_t main(void) {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> q;
  for (int i = (0); i < (n); i++) cin >> a[i];
  for (int i = 0; i < n;) {
    int j;
    for (j = i; j < n && a[i] == a[j]; j++)
      ;
    s.insert(i);
    i = j;
  }
  build();
  while (q--) {
    int op;
    cin >> op;
    if (op == 1) {
      int pos;
      cin >> pos;
      pos--;
      auto it = --s.upper_bound(pos);
      pos = *it;
      cout << getind(pos) << '\n';
    } else if (op == 2) {
      int l, r, x;
      cin >> l >> r >> x;
      l--;
      r--;
      if (r < n - 1) {
        auto it = --s.upper_bound(r + 1);
        setind(r + 1, getind(*it));
        s.insert(r + 1);
      }
      s.insert(l);
      setind(l, x);
      auto it = s.upper_bound(l);
      while (it != s.end() && *it <= r) {
        setind(*it, -2);
        it = s.erase(it);
      }
    } else {
      int l, r, x;
      cin >> l >> r >> x;
      l--;
      r--;
      if (r < n - 1) {
        auto it = --s.upper_bound(r + 1);
        setind(r + 1, getind(*it));
        s.insert(r + 1);
      }
      auto it = --s.upper_bound(l);
      setind(l, getind(*it));
      s.insert(l);
      do {
        add(l, r, x);
        while (seg[1].mindif < 0) {
          setind(seg[1].minpos, -1);
        }
      } while (seg[1].mindif == 0);
    }
  }
  return 0;
}
