#include <bits/stdc++.h>   using namespace std;   template <typename tp>   inline void read(tp& x) {     x = 0;     char tmp;     bool key = 0;     for (tmp = getchar(); !isdigit(tmp); tmp = getchar()) key = (tmp ==  - );     for (; isdigit(tmp); tmp = getchar()) x = (x << 3) + (x << 1) + (tmp ^  0 );     if (key) x = -x;   }   template <typename tp>   inline void ckmn(tp& x, tp y) {     x = x < y ? x : y;   }   template <typename tp>   inline void ckmx(tp& x, tp y) {     x = x < y ? y : x;   }   const long long LLINF = (long long)1e18;   const int N = 100010, MP = 20;   int n, q, sta[N];   long long rec[MP], val[N];   struct node {     long long mn;     long long rv;     long long tag;     int rec;   } t[N << 2];   void puttag(int x, long long v) {     t[x].tag += v;     t[x].mn -= v;     t[x].rv += v;   }   void putrec(int x) {     t[x].rec = 1;     t[x].rv = t[x].mn = LLINF;     t[x].tag = 0;   }   void push_down(int x) {     if (t[x].tag) {       puttag(x << 1, t[x].tag);       puttag(x << 1 | 1, t[x].tag);       t[x].tag = 0;     }     if (t[x].rec) {       putrec(x << 1);       putrec(x << 1 | 1);       t[x].rec = 0;     }   }   void push_up(int x) {     t[x].mn = min(t[x << 1].mn, t[x << 1 | 1].mn);     t[x].rv = t[x << 1 | 1].rv;     if (t[x].rv >= LLINF) t[x].rv = t[x << 1].rv;   }   long long query(int p, int x = 1, int lp = 1, int rp = n) {     if (lp == rp) return t[x].rv;     push_down(x);     int mid = (lp + rp) >> 1;     if (p <= mid) return query(p, x << 1, lp, mid);     long long tmp = query(p, x << 1 | 1, mid + 1, rp);     if (tmp >= LLINF)       return t[x << 1].rv;     else       return tmp;   }   long long askmn(int l, int r, int x = 1, int lp = 1, int rp = n) {     if (l > rp || lp > r) return LLINF;     if (lp >= l && rp <= r) return t[x].mn;     int mid = (lp + rp) >> 1;     push_down(x);     return min(askmn(l, r, x << 1, lp, mid),                askmn(l, r, x << 1 | 1, mid + 1, rp));   }   void modify(int l, int r, long long v, int x = 1, int lp = 1, int rp = n) {     if (l > rp || lp > r) return;     if (lp >= l && rp <= r) {       puttag(x, v);       return;     }     int mid = (lp + rp) >> 1;     push_down(x);     modify(l, r, v, x << 1, lp, mid), modify(l, r, v, x << 1 | 1, mid + 1, rp);     push_up(x);   }   void doit(int x = 1, int lp = 1, int rp = n) {     if (t[x].mn >= 0) return;     if (lp == rp) {       while (t[x].mn < 0) {         ++sta[lp];         t[x].mn = rec[sta[lp]] - t[x].rv;       }       return;     }     int mid = (lp + rp) >> 1;     push_down(x);     doit(x << 1, lp, mid);     doit(x << 1 | 1, mid + 1, rp);     push_up(x);   }   void fill(int l, int r, int x = 1, int lp = 1, int rp = n) {     if (l > rp || lp > r) return;     if (lp >= l && rp <= r) {       putrec(x);       return;     }     int mid = (lp + rp) >> 1;     push_down(x);     fill(l, r, x << 1, lp, mid);     fill(l, r, x << 1 | 1, mid + 1, rp);     push_up(x);   }   void setval(int p, long long v, int x = 1, int lp = 1, int rp = n) {     if (lp == rp) {       t[x].rv = v;       t[x].tag = 0, t[x].rec = 0;       t[x].mn = rec[0] - v;       sta[lp] = 0;       return;     }     int mid = (lp + rp) >> 1;     push_down(x);     if (p <= mid)       setval(p, v, x << 1, lp, mid);     else       setval(p, v, x << 1 | 1, mid + 1, rp);     push_up(x);   }   void build(int x = 1, int lp = 1, int rp = n) {     t[x].tag = t[x].rec = 0;     if (lp == rp) {       t[x].rv = val[lp];       t[x].mn = rec[sta[lp]] - val[lp];       return;     }     int mid = (lp + rp) >> 1;     build(x << 1, lp, mid);     build(x << 1 | 1, mid + 1, rp);     push_up(x);   }   int main() {     int tp, x, y, z;     read(n), read(q);     for (int i = (1); i <= (n); ++i) read(val[i]);     rec[0] = 1;     for (int i = 1; rec[i - 1] <= LLINF / 42; ++i) rec[i] = rec[i - 1] * 42;     build();     for (int i = (1); i <= (q); ++i) {       read(tp);       if (tp == 1) {         read(x);         printf( %lld n , query(x));       } else if (tp == 2) {         read(x), read(y), read(z);         if (y < n) setval(y + 1, query(y + 1));         setval(x, z);         if (x < y) fill(x + 1, y);       } else {         read(x), read(y), read(z);         setval(x, query(x));         if (y < n) setval(y + 1, query(y + 1));         while (true) {           modify(x, y, z);           doit();           if (askmn(x, y) > 0) break;         }       }     }     return 0;   }