#include <bits/stdc++.h>   using namespace std;   const int N = 1e5 + 5;   int arr[N];   long long seg[N << 2], mn[N << 2], lazy[N << 2];   bool flag[N << 2];   int n, q;   vector<long long> v;   void push_down(int id) {     if (flag[id]) {       lazy[id] = lazy[((id << 1) + 1)] = lazy[((id << 1) + 2)] = 0;       seg[((id << 1) + 1)] = seg[((id << 1) + 2)] = seg[id];       mn[((id << 1) + 1)] = mn[((id << 1) + 2)] = mn[id];       flag[((id << 1) + 1)] = flag[((id << 1) + 2)] = flag[id];       flag[id] = 0;     } else {       lazy[((id << 1) + 1)] += lazy[id];       lazy[((id << 1) + 2)] += lazy[id];       mn[((id << 1) + 1)] -= lazy[id];       mn[((id << 1) + 2)] -= lazy[id];       if (seg[((id << 1) + 1)] != -1) {         seg[((id << 1) + 1)] += lazy[id];       }       if (seg[((id << 1) + 2)] != -1) {         seg[((id << 1) + 2)] += lazy[id];       }       lazy[id] = 0;     }   }   void push_up(int id) {     mn[id] = min(mn[((id << 1) + 1)], mn[((id << 1) + 2)]);     if (seg[((id << 1) + 1)] == seg[((id << 1) + 2)]) {       seg[id] = seg[((id << 1) + 1)];     } else {       seg[id] = -1;     }   }   void build(int id = 0, int s = 0, int e = n) {     if (s + 1 == e) {       seg[id] = arr[s];       mn[id] = *upper_bound(v.begin(), v.end(), arr[s]) - arr[s];       return;     }     int mid = (s + e) >> 1;     build(((id << 1) + 1), s, mid);     build(((id << 1) + 2), mid, e);     push_up(id);   }   void print(int id = 0, int s = 0, int e = n) {     cout <<  [  << s + 1 <<  ,  << e <<  ]   << id <<   == >   << mn[id] <<              << seg[id] << endl;     if (s + 1 == e) {       return;     }     push_down(id);     int mid = (s + e) >> 1;     print(((id << 1) + 1), s, mid);     print(((id << 1) + 2), mid, e);     push_up(id);   }   long long query(int l, int r, int id = 0, int s = 0, int e = n) {     if (l >= e || r <= s) return 0;     if (s + 1 == e) return seg[id];     push_down(id);     int mid = (s + e) >> 1;     long long ret = query(l, r, ((id << 1) + 1), s, mid) +                     query(l, r, ((id << 1) + 2), mid, e);     push_up(id);     return ret;   }   void Set(int l, int r, int x, int id = 0, int s = 0, int e = n) {     if (l >= e || r <= s) return;     if (l <= s && r >= e) {       seg[id] = x;       flag[id] = true;       mn[id] = (*lower_bound(v.begin(), v.end(), x)) - x;       lazy[id] = 0;       return;     }     push_down(id);     int mid = (s + e) >> 1;     Set(l, r, x, ((id << 1) + 1), s, mid);     Set(l, r, x, ((id << 1) + 2), mid, e);     push_up(id);   }   void add(int l, int r, int x, int id = 0, int s = 0, int e = n) {     if (l >= e || r <= s) return;     if (l <= s && r >= e) {       if (seg[id] != -1) {         seg[id] += x;         mn[id] = (*lower_bound(v.begin(), v.end(), seg[id])) - seg[id];         flag[id] = true;         lazy[id] = 0;         return;       } else if (mn[id] >= x) {         mn[id] -= x;         lazy[id] += x;         return;       }     }     push_down(id);     int mid = (s + e) >> 1;     add(l, r, x, ((id << 1) + 1), s, mid);     add(l, r, x, ((id << 1) + 2), mid, e);     push_up(id);   }   int main() {     v.push_back(1);     while (v.back() < 1e17) {       v.push_back(v.back() * 42);     }     scanf( %d%d , &n, &q);     for (int i = 0; i < n; i++) scanf( %d , &arr[i]);     int type, a, b, x;     build();     while (q--) {       scanf( %d , &type);       if (type == 1) {         scanf( %d , &a);         printf( %lld n , query(a - 1, a));       } else if (type == 2) {         scanf( %d%d%d , &a, &b, &x);         Set(a - 1, b, x);       } else {         scanf( %d%d%d , &a, &b, &x);         do {           add(a - 1, b, x);         } while (mn[0] == 0);       }     }     return 0;   }