//#pragma GCC optimize("Ofast,unroll-loops")
//#pragma GCC target("avx2,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define file "fakernum"
#define ff(i,a,b) for(auto i=(a); i<=(b); ++i)
#define ffr(i,b,a) for(auto i=(b); i>=(a); --i)
#define nl "\n"
#define ss " "
#define pb emplace_back
#define fi first
#define se second
#define sz(s) (int)(s).size()
#define all(s) (s).begin(), (s).end()
#define ms(a,x) memset(a, x, sizeof(a))
#define cn continue
#define re exit(0)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
const int mod=1e9+7;
const int maxn=1e5+15;
const ll inf=4e18;
const ll LIMV = 10000000000000000LL;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll ran(ll l, ll r){ return uniform_int_distribution<ll>(l,r)(rng); }
inline void rf(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
if(fopen(file".inp","r")){
freopen(file".inp","r",stdin); freopen(file".out","w",stdout);
}
}
template<typename T> inline void addm(T &x, const T &y){ x+=y; if(x>=mod) x-=mod; if(x<0) x+=mod; }
template<typename T> inline bool maxi(T &a, T b){ if(a>=b) return 0; a=b; return 1; }
template<typename T> inline bool mini(T &a, T b){ if(a<=b) return 0; a=b; return 1; }
int n,q;
ll a[maxn];
vi g[maxn];
int par[maxn], h[maxn], heavy[maxn], head[maxn], st[maxn], ed[maxn], siz[maxn], timer_=0;
vll spev;
unordered_set<ll> spes;
inline string todecstr(ll x){
if(x==0) return "0";
string s; while(x){ s+=char('0'+(x%10)); x/=10; } reverse(all(s)); return s;
}
inline long long palsub(const string &s){
int m=sz(s);
long long ans=0;
ff(c,0,m-1){
int l=c, r=c;
while(l>=0 && r<m && s[l]==s[r]){ ++ans; --l; ++r; }
}
ff(c,0,m-2){
int l=c, r=c+1;
while(l>=0 && r<m && s[l]==s[r]){ ++ans; --l; ++r; }
}
return ans;
}
inline bool valid(ll x){
if(x<=0) return 0;
string s=todecstr(x);
int c3=0,c6=0;
for(char c:s){
if(c=='3') ++c3;
else if(c=='6') ++c6;
else return 0;
}
if(c3!=c6) return 0;
long long mau=1LL*sz(s)*(sz(s)+1)/2;
long long tu=palsub(s);
return tu*2>mau;
}
void gen(ll x){
if(x>LIMV) return;
if(x!=0 && valid(x)) spev.pb(x);
if(x==0){ gen(3); gen(6); }
else{
if(x<=LIMV/10){ gen(x*10+3); gen(x*10+6); }
}
}
int dfs1(int u, int p){
par[u]=p; siz[u]=1; int mx=0; heavy[u]=0;
for(int v:g[u]) if(v!=p){
h[v]=h[u]+1;
int s=dfs1(v,u);
siz[u]+=s;
if(s>mx){ mx=s; heavy[u]=v; }
}
return siz[u];
}
void dfs2(int u, int hd){
head[u]=hd; st[u]=++timer_;
if(heavy[u]) dfs2(heavy[u], hd);
for(int v:g[u]) if(v!=par[u] && v!=heavy[u]) dfs2(v, v);
ed[u]=timer_;
}
struct BLK {
int N,B,NB;
vll val, tag;
vector<unordered_map<ll,int>> freq;
inline int bid(int i) const { return (i-1)/B; }
inline int bl(int b) const { return b*B+1; }
inline int br(int b) const { return min(N, (b+1)*B); }
void init(int n, int B_=512){
N=n; B=max(256,B_); NB=(N+B-1)/B;
val.assign(N+1,0); tag.assign(NB,0);
freq.assign(NB, {});
}
void build(const vll &base){
ff(i,1,N) val[i]=base[i];
ff(b,0,NB-1){
freq[b].clear();
ff(i,bl(b),br(b)) ++freq[b][val[i]];
}
}
void range_add(int l, int r, ll x){
if(l>r) return;
int blid=bid(l), brid=bid(r);
if(blid==brid){
auto &F=freq[blid];
ff(i,l,r){
ll oldv=val[i];
auto it=F.find(oldv);
if(it!=F.end()){ if(--(it->se)==0) F.erase(it); }
val[i]=oldv+x;
++F[val[i]];
}
return;
}
{
auto &F=freq[blid];
ff(i,l,br(blid)){
ll oldv=val[i];
auto it=F.find(oldv);
if(it!=F.end()){ if(--(it->se)==0) F.erase(it); }
val[i]=oldv+x;
++F[val[i]];
}
}
ff(b,blid+1,brid-1) tag[b]+=x;
{
auto &F=freq[brid];
ff(i,bl(brid),r){
ll oldv=val[i];
auto it=F.find(oldv);
if(it!=F.end()){ if(--(it->se)==0) F.erase(it); }
val[i]=oldv+x;
++F[val[i]];
}
}
}
long long range_cnt(int l, int r) const{
if(l>r) return 0;
long long ans=0;
int blid=bid(l), brid=bid(r);
if(blid==brid){
ll tg=tag[blid];
ff(i,l,r){
ll realv=val[i]+tg;
if(spes.find(realv)!=spes.end()) ++ans;
}
return ans;
}
{
ll tg=tag[blid];
ff(i,l,br(blid)){
ll realv=val[i]+tg;
if(spes.find(realv)!=spes.end()) ++ans;
}
}
ff(b,blid+1,brid-1){
ll tg=tag[b];
const auto &F=freq[b];
for(const auto &kv:F){
ll realv=kv.fi+tg;
if(spes.find(realv)!=spes.end()) ans+=kv.se;
}
}
{
ll tg=tag[brid];
ff(i,bl(brid),r){
ll realv=val[i]+tg;
if(spes.find(realv)!=spes.end()) ++ans;
}
}
return ans;
}
} T;
inline void upd_path(int u, int v, ll x){
while(head[u]!=head[v]){
if(h[head[u]]<h[head[v]]) swap(u,v);
T.range_add(st[head[u]], st[u], x);
u=par[head[u]];
}
if(h[u]>h[v]) swap(u,v);
T.range_add(st[u], st[v], x);
}
inline long long get_path(int u, int v){
long long ans=0;
while(head[u]!=head[v]){
if(h[head[u]]<h[head[v]]) swap(u,v);
ans+=T.range_cnt(st[head[u]], st[u]);
u=par[head[u]];
}
if(h[u]>h[v]) swap(u,v);
ans+=T.range_cnt(st[u], st[v]);
return ans;
}
inline long long get_sub(int u){
return T.range_cnt(st[u], ed[u]);
}
signed main(){
rf();
cin>>n>>q;
ff(i,1,n) cin>>a[i];
ff(i,1,n-1){
int u,v; cin>>u>>v;
g[u].pb(v); g[v].pb(u);
}
dfs1(1,0); dfs2(1,1);
vll base(timer_+1,0);
ff(i,1,n) base[st[i]]=a[i];
gen(0);
sort(all(spev)); spev.erase(unique(all(spev)), spev.end());
spes.reserve(spev.size()*2+7);
for(ll v:spev) spes.insert(v);
T.init(timer_,512);
T.build(base);
while(q--){
int op; cin>>op;
if(op==1){
int u,v; ll x; cin>>u>>v>>x;
upd_path(u,v,x);
}else if(op==2){
int u,v; cin>>u>>v;
cout<<get_path(u,v)<<nl;
}else{
int u; cin>>u;
cout<<get_sub(u)<<nl;
}
}
re;
}
Ly8jcHJhZ21hIEdDQyBvcHRpbWl6ZSgiT2Zhc3QsdW5yb2xsLWxvb3BzIikKLy8jcHJhZ21hIEdDQyB0YXJnZXQoImF2eDIsdHVuZT1uYXRpdmUiKQojaW5jbHVkZSA8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiNkZWZpbmUgZmlsZSAiZmFrZXJudW0iCiNkZWZpbmUgZmYoaSxhLGIpIGZvcihhdXRvIGk9KGEpOyBpPD0oYik7ICsraSkKI2RlZmluZSBmZnIoaSxiLGEpIGZvcihhdXRvIGk9KGIpOyBpPj0oYSk7IC0taSkKI2RlZmluZSBubCAiXG4iCiNkZWZpbmUgc3MgIiAiCiNkZWZpbmUgcGIgZW1wbGFjZV9iYWNrCiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBzeihzKSAoaW50KShzKS5zaXplKCkKI2RlZmluZSBhbGwocykgKHMpLmJlZ2luKCksIChzKS5lbmQoKQojZGVmaW5lIG1zKGEseCkgbWVtc2V0KGEsIHgsIHNpemVvZihhKSkKI2RlZmluZSBjbiBjb250aW51ZQojZGVmaW5lIHJlIGV4aXQoMCkKCnR5cGVkZWYgbG9uZyBsb25nIGxsOwp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB1bGw7CnR5cGVkZWYgbG9uZyBkb3VibGUgbGQ7CnR5cGVkZWYgdmVjdG9yPGludD4gdmk7CnR5cGVkZWYgdmVjdG9yPGxsPiB2bGw7CnR5cGVkZWYgcGFpcjxpbnQsaW50PiBwaWk7CnR5cGVkZWYgcGFpcjxsbCxsbD4gcGxsOwp0eXBlZGVmIHZlY3RvcjxwaWk+IHZwaWk7CnR5cGVkZWYgdmVjdG9yPHBsbD4gdnBsbDsKCmNvbnN0IGludCBtb2Q9MWU5Kzc7CmNvbnN0IGludCBtYXhuPTFlNSsxNTsKY29uc3QgbGwgaW5mPTRlMTg7CmNvbnN0IGxsIExJTVYgPSAxMDAwMDAwMDAwMDAwMDAwMExMOwoKbXQxOTkzN182NCBybmcoY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsKbGwgcmFuKGxsIGwsIGxsIHIpeyByZXR1cm4gdW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGxsPihsLHIpKHJuZyk7IH0KCmlubGluZSB2b2lkIHJmKCl7CiAgICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIGNpbi50aWUobnVsbHB0cik7IGNvdXQudGllKG51bGxwdHIpOwogICAgaWYoZm9wZW4oZmlsZSIuaW5wIiwiciIpKXsKICAgICAgICBmcmVvcGVuKGZpbGUiLmlucCIsInIiLHN0ZGluKTsgZnJlb3BlbihmaWxlIi5vdXQiLCJ3IixzdGRvdXQpOwogICAgfQp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBpbmxpbmUgdm9pZCBhZGRtKFQgJngsIGNvbnN0IFQgJnkpeyB4Kz15OyBpZih4Pj1tb2QpIHgtPW1vZDsgaWYoeDwwKSB4Kz1tb2Q7IH0KdGVtcGxhdGU8dHlwZW5hbWUgVD4gaW5saW5lIGJvb2wgbWF4aShUICZhLCBUIGIpeyBpZihhPj1iKSByZXR1cm4gMDsgYT1iOyByZXR1cm4gMTsgfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBpbmxpbmUgYm9vbCBtaW5pKFQgJmEsIFQgYil7IGlmKGE8PWIpIHJldHVybiAwOyBhPWI7IHJldHVybiAxOyB9CgppbnQgbixxOwpsbCBhW21heG5dOwp2aSBnW21heG5dOwppbnQgcGFyW21heG5dLCBoW21heG5dLCBoZWF2eVttYXhuXSwgaGVhZFttYXhuXSwgc3RbbWF4bl0sIGVkW21heG5dLCBzaXpbbWF4bl0sIHRpbWVyXz0wOwoKdmxsIHNwZXY7CnVub3JkZXJlZF9zZXQ8bGw+IHNwZXM7CgppbmxpbmUgc3RyaW5nIHRvZGVjc3RyKGxsIHgpewogICAgaWYoeD09MCkgcmV0dXJuICIwIjsKICAgIHN0cmluZyBzOyB3aGlsZSh4KXsgcys9Y2hhcignMCcrKHglMTApKTsgeC89MTA7IH0gcmV2ZXJzZShhbGwocykpOyByZXR1cm4gczsKfQppbmxpbmUgbG9uZyBsb25nIHBhbHN1Yihjb25zdCBzdHJpbmcgJnMpewogICAgaW50IG09c3oocyk7CiAgICBsb25nIGxvbmcgYW5zPTA7CiAgICBmZihjLDAsbS0xKXsKICAgICAgICBpbnQgbD1jLCByPWM7CiAgICAgICAgd2hpbGUobD49MCAmJiByPG0gJiYgc1tsXT09c1tyXSl7ICsrYW5zOyAtLWw7ICsrcjsgfQogICAgfQogICAgZmYoYywwLG0tMil7CiAgICAgICAgaW50IGw9Yywgcj1jKzE7CiAgICAgICAgd2hpbGUobD49MCAmJiByPG0gJiYgc1tsXT09c1tyXSl7ICsrYW5zOyAtLWw7ICsrcjsgfQogICAgfQogICAgcmV0dXJuIGFuczsKfQppbmxpbmUgYm9vbCB2YWxpZChsbCB4KXsKICAgIGlmKHg8PTApIHJldHVybiAwOwogICAgc3RyaW5nIHM9dG9kZWNzdHIoeCk7CiAgICBpbnQgYzM9MCxjNj0wOwogICAgZm9yKGNoYXIgYzpzKXsKICAgICAgICBpZihjPT0nMycpICsrYzM7CiAgICAgICAgZWxzZSBpZihjPT0nNicpICsrYzY7CiAgICAgICAgZWxzZSByZXR1cm4gMDsKICAgIH0KICAgIGlmKGMzIT1jNikgcmV0dXJuIDA7CiAgICBsb25nIGxvbmcgbWF1PTFMTCpzeihzKSooc3oocykrMSkvMjsKICAgIGxvbmcgbG9uZyB0dT1wYWxzdWIocyk7CiAgICByZXR1cm4gdHUqMj5tYXU7Cn0Kdm9pZCBnZW4obGwgeCl7CiAgICBpZih4PkxJTVYpIHJldHVybjsKICAgIGlmKHghPTAgJiYgdmFsaWQoeCkpIHNwZXYucGIoeCk7CiAgICBpZih4PT0wKXsgZ2VuKDMpOyBnZW4oNik7IH0KICAgIGVsc2V7CiAgICAgICAgaWYoeDw9TElNVi8xMCl7IGdlbih4KjEwKzMpOyBnZW4oeCoxMCs2KTsgfQogICAgfQp9CgppbnQgZGZzMShpbnQgdSwgaW50IHApewogICAgcGFyW3VdPXA7IHNpelt1XT0xOyBpbnQgbXg9MDsgaGVhdnlbdV09MDsKICAgIGZvcihpbnQgdjpnW3VdKSBpZih2IT1wKXsKICAgICAgICBoW3ZdPWhbdV0rMTsKICAgICAgICBpbnQgcz1kZnMxKHYsdSk7CiAgICAgICAgc2l6W3VdKz1zOwogICAgICAgIGlmKHM+bXgpeyBteD1zOyBoZWF2eVt1XT12OyB9CiAgICB9CiAgICByZXR1cm4gc2l6W3VdOwp9CnZvaWQgZGZzMihpbnQgdSwgaW50IGhkKXsKICAgIGhlYWRbdV09aGQ7IHN0W3VdPSsrdGltZXJfOwogICAgaWYoaGVhdnlbdV0pIGRmczIoaGVhdnlbdV0sIGhkKTsKICAgIGZvcihpbnQgdjpnW3VdKSBpZih2IT1wYXJbdV0gJiYgdiE9aGVhdnlbdV0pIGRmczIodiwgdik7CiAgICBlZFt1XT10aW1lcl87Cn0KCnN0cnVjdCBCTEsgewogICAgaW50IE4sQixOQjsKICAgIHZsbCB2YWwsIHRhZzsKICAgIHZlY3Rvcjx1bm9yZGVyZWRfbWFwPGxsLGludD4+IGZyZXE7CiAgICBpbmxpbmUgaW50IGJpZChpbnQgaSkgY29uc3QgeyByZXR1cm4gKGktMSkvQjsgfQogICAgaW5saW5lIGludCBibChpbnQgYikgY29uc3QgeyByZXR1cm4gYipCKzE7IH0KICAgIGlubGluZSBpbnQgYnIoaW50IGIpIGNvbnN0IHsgcmV0dXJuIG1pbihOLCAoYisxKSpCKTsgfQogICAgdm9pZCBpbml0KGludCBuLCBpbnQgQl89NTEyKXsKICAgICAgICBOPW47IEI9bWF4KDI1NixCXyk7IE5CPShOK0ItMSkvQjsKICAgICAgICB2YWwuYXNzaWduKE4rMSwwKTsgdGFnLmFzc2lnbihOQiwwKTsKICAgICAgICBmcmVxLmFzc2lnbihOQiwge30pOwogICAgfQogICAgdm9pZCBidWlsZChjb25zdCB2bGwgJmJhc2UpewogICAgICAgIGZmKGksMSxOKSB2YWxbaV09YmFzZVtpXTsKICAgICAgICBmZihiLDAsTkItMSl7CiAgICAgICAgICAgIGZyZXFbYl0uY2xlYXIoKTsKICAgICAgICAgICAgZmYoaSxibChiKSxicihiKSkgKytmcmVxW2JdW3ZhbFtpXV07CiAgICAgICAgfQogICAgfQogICAgdm9pZCByYW5nZV9hZGQoaW50IGwsIGludCByLCBsbCB4KXsKICAgICAgICBpZihsPnIpIHJldHVybjsKICAgICAgICBpbnQgYmxpZD1iaWQobCksIGJyaWQ9YmlkKHIpOwogICAgICAgIGlmKGJsaWQ9PWJyaWQpewogICAgICAgICAgICBhdXRvICZGPWZyZXFbYmxpZF07CiAgICAgICAgICAgIGZmKGksbCxyKXsKICAgICAgICAgICAgICAgIGxsIG9sZHY9dmFsW2ldOwogICAgICAgICAgICAgICAgYXV0byBpdD1GLmZpbmQob2xkdik7CiAgICAgICAgICAgICAgICBpZihpdCE9Ri5lbmQoKSl7IGlmKC0tKGl0LT5zZSk9PTApIEYuZXJhc2UoaXQpOyB9CiAgICAgICAgICAgICAgICB2YWxbaV09b2xkdit4OwogICAgICAgICAgICAgICAgKytGW3ZhbFtpXV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB7CiAgICAgICAgICAgIGF1dG8gJkY9ZnJlcVtibGlkXTsKICAgICAgICAgICAgZmYoaSxsLGJyKGJsaWQpKXsKICAgICAgICAgICAgICAgIGxsIG9sZHY9dmFsW2ldOwogICAgICAgICAgICAgICAgYXV0byBpdD1GLmZpbmQob2xkdik7CiAgICAgICAgICAgICAgICBpZihpdCE9Ri5lbmQoKSl7IGlmKC0tKGl0LT5zZSk9PTApIEYuZXJhc2UoaXQpOyB9CiAgICAgICAgICAgICAgICB2YWxbaV09b2xkdit4OwogICAgICAgICAgICAgICAgKytGW3ZhbFtpXV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmYoYixibGlkKzEsYnJpZC0xKSB0YWdbYl0rPXg7CiAgICAgICAgewogICAgICAgICAgICBhdXRvICZGPWZyZXFbYnJpZF07CiAgICAgICAgICAgIGZmKGksYmwoYnJpZCkscil7CiAgICAgICAgICAgICAgICBsbCBvbGR2PXZhbFtpXTsKICAgICAgICAgICAgICAgIGF1dG8gaXQ9Ri5maW5kKG9sZHYpOwogICAgICAgICAgICAgICAgaWYoaXQhPUYuZW5kKCkpeyBpZigtLShpdC0+c2UpPT0wKSBGLmVyYXNlKGl0KTsgfQogICAgICAgICAgICAgICAgdmFsW2ldPW9sZHYreDsKICAgICAgICAgICAgICAgICsrRlt2YWxbaV1dOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgbG9uZyBsb25nIHJhbmdlX2NudChpbnQgbCwgaW50IHIpIGNvbnN0ewogICAgICAgIGlmKGw+cikgcmV0dXJuIDA7CiAgICAgICAgbG9uZyBsb25nIGFucz0wOwogICAgICAgIGludCBibGlkPWJpZChsKSwgYnJpZD1iaWQocik7CiAgICAgICAgaWYoYmxpZD09YnJpZCl7CiAgICAgICAgICAgIGxsIHRnPXRhZ1tibGlkXTsKICAgICAgICAgICAgZmYoaSxsLHIpewogICAgICAgICAgICAgICAgbGwgcmVhbHY9dmFsW2ldK3RnOwogICAgICAgICAgICAgICAgaWYoc3Blcy5maW5kKHJlYWx2KSE9c3Blcy5lbmQoKSkgKythbnM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGFuczsKICAgICAgICB9CiAgICAgICAgewogICAgICAgICAgICBsbCB0Zz10YWdbYmxpZF07CiAgICAgICAgICAgIGZmKGksbCxicihibGlkKSl7CiAgICAgICAgICAgICAgICBsbCByZWFsdj12YWxbaV0rdGc7CiAgICAgICAgICAgICAgICBpZihzcGVzLmZpbmQocmVhbHYpIT1zcGVzLmVuZCgpKSArK2FuczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmZihiLGJsaWQrMSxicmlkLTEpewogICAgICAgICAgICBsbCB0Zz10YWdbYl07CiAgICAgICAgICAgIGNvbnN0IGF1dG8gJkY9ZnJlcVtiXTsKICAgICAgICAgICAgZm9yKGNvbnN0IGF1dG8gJmt2OkYpewogICAgICAgICAgICAgICAgbGwgcmVhbHY9a3YuZmkrdGc7CiAgICAgICAgICAgICAgICBpZihzcGVzLmZpbmQocmVhbHYpIT1zcGVzLmVuZCgpKSBhbnMrPWt2LnNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHsKICAgICAgICAgICAgbGwgdGc9dGFnW2JyaWRdOwogICAgICAgICAgICBmZihpLGJsKGJyaWQpLHIpewogICAgICAgICAgICAgICAgbGwgcmVhbHY9dmFsW2ldK3RnOwogICAgICAgICAgICAgICAgaWYoc3Blcy5maW5kKHJlYWx2KSE9c3Blcy5lbmQoKSkgKythbnM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFuczsKICAgIH0KfSBUOwoKaW5saW5lIHZvaWQgdXBkX3BhdGgoaW50IHUsIGludCB2LCBsbCB4KXsKICAgIHdoaWxlKGhlYWRbdV0hPWhlYWRbdl0pewogICAgICAgIGlmKGhbaGVhZFt1XV08aFtoZWFkW3ZdXSkgc3dhcCh1LHYpOwogICAgICAgIFQucmFuZ2VfYWRkKHN0W2hlYWRbdV1dLCBzdFt1XSwgeCk7CiAgICAgICAgdT1wYXJbaGVhZFt1XV07CiAgICB9CiAgICBpZihoW3VdPmhbdl0pIHN3YXAodSx2KTsKICAgIFQucmFuZ2VfYWRkKHN0W3VdLCBzdFt2XSwgeCk7Cn0KaW5saW5lIGxvbmcgbG9uZyBnZXRfcGF0aChpbnQgdSwgaW50IHYpewogICAgbG9uZyBsb25nIGFucz0wOwogICAgd2hpbGUoaGVhZFt1XSE9aGVhZFt2XSl7CiAgICAgICAgaWYoaFtoZWFkW3VdXTxoW2hlYWRbdl1dKSBzd2FwKHUsdik7CiAgICAgICAgYW5zKz1ULnJhbmdlX2NudChzdFtoZWFkW3VdXSwgc3RbdV0pOwogICAgICAgIHU9cGFyW2hlYWRbdV1dOwogICAgfQogICAgaWYoaFt1XT5oW3ZdKSBzd2FwKHUsdik7CiAgICBhbnMrPVQucmFuZ2VfY250KHN0W3VdLCBzdFt2XSk7CiAgICByZXR1cm4gYW5zOwp9CmlubGluZSBsb25nIGxvbmcgZ2V0X3N1YihpbnQgdSl7CiAgICByZXR1cm4gVC5yYW5nZV9jbnQoc3RbdV0sIGVkW3VdKTsKfQoKc2lnbmVkIG1haW4oKXsKICAgIHJmKCk7CiAgICBjaW4+Pm4+PnE7CiAgICBmZihpLDEsbikgY2luPj5hW2ldOwogICAgZmYoaSwxLG4tMSl7CiAgICAgICAgaW50IHUsdjsgY2luPj51Pj52OwogICAgICAgIGdbdV0ucGIodik7IGdbdl0ucGIodSk7CiAgICB9CiAgICBkZnMxKDEsMCk7IGRmczIoMSwxKTsKICAgIHZsbCBiYXNlKHRpbWVyXysxLDApOwogICAgZmYoaSwxLG4pIGJhc2Vbc3RbaV1dPWFbaV07CiAgICBnZW4oMCk7CiAgICBzb3J0KGFsbChzcGV2KSk7IHNwZXYuZXJhc2UodW5pcXVlKGFsbChzcGV2KSksIHNwZXYuZW5kKCkpOwogICAgc3Blcy5yZXNlcnZlKHNwZXYuc2l6ZSgpKjIrNyk7CiAgICBmb3IobGwgdjpzcGV2KSBzcGVzLmluc2VydCh2KTsKICAgIFQuaW5pdCh0aW1lcl8sNTEyKTsKICAgIFQuYnVpbGQoYmFzZSk7CiAgICB3aGlsZShxLS0pewogICAgICAgIGludCBvcDsgY2luPj5vcDsKICAgICAgICBpZihvcD09MSl7CiAgICAgICAgICAgIGludCB1LHY7IGxsIHg7IGNpbj4+dT4+dj4+eDsKICAgICAgICAgICAgdXBkX3BhdGgodSx2LHgpOwogICAgICAgIH1lbHNlIGlmKG9wPT0yKXsKICAgICAgICAgICAgaW50IHUsdjsgY2luPj51Pj52OwogICAgICAgICAgICBjb3V0PDxnZXRfcGF0aCh1LHYpPDxubDsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgaW50IHU7IGNpbj4+dTsKICAgICAgICAgICAgY291dDw8Z2V0X3N1Yih1KTw8bmw7CiAgICAgICAgfQogICAgfQogICAgcmU7Cn0K