//#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 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;
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 add(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 ll palsub(const string &s)
{
int m=sz(s);
ll 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;
ll mau=1LL*sz(s)*(sz(s)+1)/2;
ll tu=palsub(s);
return tu*2>mau;
}
void gen(ll x)
{
if(x>1e16) return;
if(x!=0 && valid(x)) spev.pb(x);
if(x==0){ gen(3); gen(6); }
else
{
if(x<=1e15){ 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]];
}
}
}
ll range_cnt(int l, int r) const
{
if(l>r) return 0;
ll 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 ll get_path(int u, int v)
{
ll 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 ll 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;
}
Ly8jcHJhZ21hIEdDQyBvcHRpbWl6ZSgiT2Zhc3QsdW5yb2xsLWxvb3BzIikKLy8jcHJhZ21hIEdDQyB0YXJnZXQoImF2eDIsdHVuZT1uYXRpdmUiKQojaW5jbHVkZSA8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiNkZWZpbmUgZmlsZSAiZmFrZXJudW0iCiNkZWZpbmUgZmYoaSwgYSwgYikgZm9yKGF1dG8gaT0oYSk7IGk8PShiKTsgKytpKQojZGVmaW5lIGZmcihpLCBiLCBhKSBmb3IoYXV0byBpPShiKTsgaT49KGEpOyAtLWkpCiNkZWZpbmUgbmwgIlxuIgojZGVmaW5lIHNzICIgIgojZGVmaW5lIHBiIGVtcGxhY2VfYmFjawojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCiNkZWZpbmUgc3oocykgKGludClzLnNpemUoKQojZGVmaW5lIGFsbChzKSAocykuYmVnaW4oKSwgKHMpLmVuZCgpCiNkZWZpbmUgbXMoYSx4KSBtZW1zZXQoYSwgeCwgc2l6ZW9mIChhKSkKI2RlZmluZSBjbiBjb250aW51ZQojZGVmaW5lIHJlIGV4aXQoMCkKCnR5cGVkZWYgbG9uZyBsb25nIGxsOwp0eXBlZGVmIGxvbmcgZG91YmxlIGxkOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwp0eXBlZGVmIHZlY3RvcjxsbD4gdmxsOwp0eXBlZGVmIHBhaXI8aW50LCBpbnQ+IHBpaTsKdHlwZWRlZiBwYWlyPGxsLCBsbD4gcGxsOwp0eXBlZGVmIHZlY3RvcjxwaWk+IHZwaWk7CnR5cGVkZWYgdmVjdG9yPHBsbD4gdnBsbDsKCmNvbnN0IGludCBtb2Q9MWU5Kzc7CmNvbnN0IGludCBtYXhuPTFlNSsxNTsKY29uc3QgbGwgaW5mPTRlMTg7CgptdDE5OTM3XzY0IHJuZyhjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCkpOwpsbCByYW4obGwgbCwgbGwgcikKewogICAgcmV0dXJuIHVuaWZvcm1faW50X2Rpc3RyaWJ1dGlvbjxsbD4gKGwsIHIpKHJuZyk7Cn0KCmlubGluZSB2b2lkIHJmKCl7CiAgICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIGNpbi50aWUobnVsbHB0cik7IGNvdXQudGllKG51bGxwdHIpOwogICAgaWYoZm9wZW4oZmlsZSIuaW5wIiwiciIpKXsKICAgICAgICBmcmVvcGVuKGZpbGUiLmlucCIsInIiLHN0ZGluKTsgZnJlb3BlbihmaWxlIi5vdXQiLCJ3IixzdGRvdXQpOwogICAgfQp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBpbmxpbmUgdm9pZCBhZGQoVCAmeCwgY29uc3QgVCAmeSkKewogICAgeCs9eTsKICAgIGlmKHg+PW1vZCkgeC09bW9kOwogICAgaWYoeDwwKSB4Kz1tb2Q7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IGlubGluZSBib29sIG1heGkoVCAmYSwgVCBiKQp7CiAgICBpZihhPj1iKSByZXR1cm4gMDsKICAgIGE9YjsgcmV0dXJuIDE7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IGlubGluZSBib29sIG1pbmkoVCAmYSwgVCBiKQp7CiAgICBpZihhPD1iKSByZXR1cm4gMDsKICAgIGE9YjsgcmV0dXJuIDE7Cn0KCmludCBuLHE7CmxsIGFbbWF4bl07CnZpIGdbbWF4bl07CmludCBwYXJbbWF4bl0sIGhbbWF4bl0sIGhlYXZ5W21heG5dLCBoZWFkW21heG5dLCBzdFttYXhuXSwgZWRbbWF4bl0sIHNpelttYXhuXSwgdGltZXJfPTA7Cgp2bGwgc3BldjsKdW5vcmRlcmVkX3NldDxsbD4gc3BlczsKCmlubGluZSBzdHJpbmcgdG9kZWNzdHIobGwgeCkKewogICAgaWYoeD09MCkgcmV0dXJuICIwIjsKICAgIHN0cmluZyBzOyB3aGlsZSh4KXsgcys9Y2hhcignMCcrKHglMTApKTsgeC89MTA7IH0gcmV2ZXJzZShhbGwocykpOyByZXR1cm4gczsKfQoKaW5saW5lIGxsIHBhbHN1Yihjb25zdCBzdHJpbmcgJnMpCnsKICAgIGludCBtPXN6KHMpOwogICAgbGwgYW5zPTA7CiAgICBmZihjLDAsbS0xKXsKICAgICAgICBpbnQgbD1jLCByPWM7CiAgICAgICAgd2hpbGUobD49MCAmJiByPG0gJiYgc1tsXT09c1tyXSl7ICsrYW5zOyAtLWw7ICsrcjsgfQogICAgfQogICAgZmYoYywwLG0tMil7CiAgICAgICAgaW50IGw9Yywgcj1jKzE7CiAgICAgICAgd2hpbGUobD49MCAmJiByPG0gJiYgc1tsXT09c1tyXSl7ICsrYW5zOyAtLWw7ICsrcjsgfQogICAgfQogICAgcmV0dXJuIGFuczsKfQoKaW5saW5lIGJvb2wgdmFsaWQobGwgeCkKewogICAgaWYoeDw9MCkgcmV0dXJuIDA7CiAgICBzdHJpbmcgcz10b2RlY3N0cih4KTsKICAgIGludCBjMz0wLGM2PTA7CiAgICBmb3IoY2hhciBjOnMpCiAgICB7CiAgICAgICAgaWYoYz09JzMnKSArK2MzOwogICAgICAgIGVsc2UgaWYoYz09JzYnKSArK2M2OwogICAgICAgIGVsc2UgcmV0dXJuIDA7CiAgICB9CiAgICBpZihjMyE9YzYpIHJldHVybiAwOwogICAgbGwgbWF1PTFMTCpzeihzKSooc3oocykrMSkvMjsKICAgIGxsIHR1PXBhbHN1YihzKTsKICAgIHJldHVybiB0dSoyPm1hdTsKfQoKdm9pZCBnZW4obGwgeCkKewogICAgaWYoeD4xZTE2KSByZXR1cm47CiAgICBpZih4IT0wICYmIHZhbGlkKHgpKSBzcGV2LnBiKHgpOwogICAgaWYoeD09MCl7IGdlbigzKTsgZ2VuKDYpOyB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYoeDw9MWUxNSl7IGdlbih4KjEwKzMpOyBnZW4oeCoxMCs2KTsgfQogICAgfQp9CgppbnQgZGZzMShpbnQgdSwgaW50IHApCnsKICAgIHBhclt1XT1wOyBzaXpbdV09MTsgaW50IG14PTA7IGhlYXZ5W3VdPTA7CiAgICBmb3IoaW50IHY6Z1t1XSkgaWYodiE9cCkKICAgIHsKICAgICAgICBoW3ZdPWhbdV0rMTsKICAgICAgICBpbnQgcz1kZnMxKHYsdSk7CiAgICAgICAgc2l6W3VdKz1zOwogICAgICAgIGlmKHM+bXgpeyBteD1zOyBoZWF2eVt1XT12OyB9CiAgICB9CiAgICByZXR1cm4gc2l6W3VdOwp9CnZvaWQgZGZzMihpbnQgdSwgaW50IGhkKQp7CiAgICBoZWFkW3VdPWhkOyBzdFt1XT0rK3RpbWVyXzsKICAgIGlmKGhlYXZ5W3VdKSBkZnMyKGhlYXZ5W3VdLCBoZCk7CiAgICBmb3IoaW50IHY6Z1t1XSkgaWYodiE9cGFyW3VdICYmIHYhPWhlYXZ5W3VdKSBkZnMyKHYsIHYpOwogICAgZWRbdV09dGltZXJfOwp9CgpzdHJ1Y3QgQkxLIAp7CiAgICBpbnQgTixCLE5COwogICAgdmxsIHZhbCwgdGFnOwogICAgdmVjdG9yPHVub3JkZXJlZF9tYXA8bGwsaW50Pj4gZnJlcTsKICAgIGlubGluZSBpbnQgYmlkKGludCBpKSBjb25zdCB7IHJldHVybiAoaS0xKS9COyB9CiAgICBpbmxpbmUgaW50IGJsKGludCBiKSBjb25zdCB7IHJldHVybiBiKkIrMTsgfQogICAgaW5saW5lIGludCBicihpbnQgYikgY29uc3QgeyByZXR1cm4gbWluKE4sIChiKzEpKkIpOyB9CiAgICB2b2lkIGluaXQoaW50IG4sIGludCBCXz01MTIpCiAgICB7CiAgICAgICAgTj1uOyBCPW1heCgyNTYsQl8pOyBOQj0oTitCLTEpL0I7CiAgICAgICAgdmFsLmFzc2lnbihOKzEsMCk7IHRhZy5hc3NpZ24oTkIsMCk7CiAgICAgICAgZnJlcS5hc3NpZ24oTkIsIHt9KTsKICAgIH0KICAgIHZvaWQgYnVpbGQoY29uc3QgdmxsICZiYXNlKQogICAgewogICAgICAgIGZmKGksMSxOKSB2YWxbaV09YmFzZVtpXTsKICAgICAgICBmZihiLDAsTkItMSkKICAgICAgICB7CiAgICAgICAgICAgIGZyZXFbYl0uY2xlYXIoKTsKICAgICAgICAgICAgZmYoaSxibChiKSxicihiKSkgKytmcmVxW2JdW3ZhbFtpXV07CiAgICAgICAgfQogICAgfQogICAgdm9pZCByYW5nZV9hZGQoaW50IGwsIGludCByLCBsbCB4KQogICAgewogICAgICAgIGlmKGw+cikgcmV0dXJuOwogICAgICAgIGludCBibGlkPWJpZChsKSwgYnJpZD1iaWQocik7CiAgICAgICAgaWYoYmxpZD09YnJpZCkKICAgICAgICB7CiAgICAgICAgICAgIGF1dG8gJkY9ZnJlcVtibGlkXTsKICAgICAgICAgICAgZmYoaSxsLHIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxsIG9sZHY9dmFsW2ldOwogICAgICAgICAgICAgICAgYXV0byBpdD1GLmZpbmQob2xkdik7CiAgICAgICAgICAgICAgICBpZihpdCE9Ri5lbmQoKSl7IGlmKC0tKGl0LT5zZSk9PTApIEYuZXJhc2UoaXQpOyB9CiAgICAgICAgICAgICAgICB2YWxbaV09b2xkdit4OwogICAgICAgICAgICAgICAgKytGW3ZhbFtpXV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB7CiAgICAgICAgICAgIGF1dG8gJkY9ZnJlcVtibGlkXTsKICAgICAgICAgICAgZmYoaSxsLGJyKGJsaWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBsbCBvbGR2PXZhbFtpXTsKICAgICAgICAgICAgICAgIGF1dG8gaXQ9Ri5maW5kKG9sZHYpOwogICAgICAgICAgICAgICAgaWYoaXQhPUYuZW5kKCkpeyBpZigtLShpdC0+c2UpPT0wKSBGLmVyYXNlKGl0KTsgfQogICAgICAgICAgICAgICAgdmFsW2ldPW9sZHYreDsKICAgICAgICAgICAgICAgICsrRlt2YWxbaV1dOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZmKGIsYmxpZCsxLGJyaWQtMSkgdGFnW2JdKz14OwogICAgICAgIHsKICAgICAgICAgICAgYXV0byAmRj1mcmVxW2JyaWRdOwogICAgICAgICAgICBmZihpLGJsKGJyaWQpLHIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxsIG9sZHY9dmFsW2ldOwogICAgICAgICAgICAgICAgYXV0byBpdD1GLmZpbmQob2xkdik7CiAgICAgICAgICAgICAgICBpZihpdCE9Ri5lbmQoKSl7IGlmKC0tKGl0LT5zZSk9PTApIEYuZXJhc2UoaXQpOyB9CiAgICAgICAgICAgICAgICB2YWxbaV09b2xkdit4OwogICAgICAgICAgICAgICAgKytGW3ZhbFtpXV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBsbCByYW5nZV9jbnQoaW50IGwsIGludCByKSBjb25zdAogICAgewogICAgICAgIGlmKGw+cikgcmV0dXJuIDA7CiAgICAgICAgbGwgYW5zPTA7CiAgICAgICAgaW50IGJsaWQ9YmlkKGwpLCBicmlkPWJpZChyKTsKICAgICAgICBpZihibGlkPT1icmlkKQogICAgICAgIHsKICAgICAgICAgICAgbGwgdGc9dGFnW2JsaWRdOwogICAgICAgICAgICBmZihpLGwscikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGwgcmVhbHY9dmFsW2ldK3RnOwogICAgICAgICAgICAgICAgaWYoc3Blcy5maW5kKHJlYWx2KSE9c3Blcy5lbmQoKSkgKythbnM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGFuczsKICAgICAgICB9CiAgICAgICAgewogICAgICAgICAgICBsbCB0Zz10YWdbYmxpZF07CiAgICAgICAgICAgIGZmKGksbCxicihibGlkKSl7CiAgICAgICAgICAgICAgICBsbCByZWFsdj12YWxbaV0rdGc7CiAgICAgICAgICAgICAgICBpZihzcGVzLmZpbmQocmVhbHYpIT1zcGVzLmVuZCgpKSArK2FuczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmZihiLGJsaWQrMSxicmlkLTEpCiAgICAgICAgewogICAgICAgICAgICBsbCB0Zz10YWdbYl07CiAgICAgICAgICAgIGNvbnN0IGF1dG8gJkY9ZnJlcVtiXTsKICAgICAgICAgICAgZm9yKGNvbnN0IGF1dG8gJmt2OkYpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxsIHJlYWx2PWt2LmZpK3RnOwogICAgICAgICAgICAgICAgaWYoc3Blcy5maW5kKHJlYWx2KSE9c3Blcy5lbmQoKSkgYW5zKz1rdi5zZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB7CiAgICAgICAgICAgIGxsIHRnPXRhZ1ticmlkXTsKICAgICAgICAgICAgZmYoaSxibChicmlkKSxyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBsbCByZWFsdj12YWxbaV0rdGc7CiAgICAgICAgICAgICAgICBpZihzcGVzLmZpbmQocmVhbHYpIT1zcGVzLmVuZCgpKSArK2FuczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYW5zOwogICAgfQp9IFQ7CgppbmxpbmUgdm9pZCB1cGRfcGF0aChpbnQgdSwgaW50IHYsIGxsIHgpCnsKICAgIHdoaWxlKGhlYWRbdV0hPWhlYWRbdl0pewogICAgICAgIGlmKGhbaGVhZFt1XV08aFtoZWFkW3ZdXSkgc3dhcCh1LHYpOwogICAgICAgIFQucmFuZ2VfYWRkKHN0W2hlYWRbdV1dLCBzdFt1XSwgeCk7CiAgICAgICAgdT1wYXJbaGVhZFt1XV07CiAgICB9CiAgICBpZihoW3VdPmhbdl0pIHN3YXAodSx2KTsKICAgIFQucmFuZ2VfYWRkKHN0W3VdLCBzdFt2XSwgeCk7Cn0KCmlubGluZSBsbCBnZXRfcGF0aChpbnQgdSwgaW50IHYpCnsKICAgIGxsIGFucz0wOwogICAgd2hpbGUoaGVhZFt1XSE9aGVhZFt2XSkKICAgIHsKICAgICAgICBpZihoW2hlYWRbdV1dPGhbaGVhZFt2XV0pIHN3YXAodSx2KTsKICAgICAgICBhbnMrPVQucmFuZ2VfY250KHN0W2hlYWRbdV1dLCBzdFt1XSk7CiAgICAgICAgdT1wYXJbaGVhZFt1XV07CiAgICB9CiAgICBpZihoW3VdPmhbdl0pIHN3YXAodSx2KTsKICAgIGFucys9VC5yYW5nZV9jbnQoc3RbdV0sIHN0W3ZdKTsKICAgIHJldHVybiBhbnM7Cn0KCmlubGluZSBsbCBnZXRfc3ViKGludCB1KQp7CiAgICByZXR1cm4gVC5yYW5nZV9jbnQoc3RbdV0sIGVkW3VdKTsKfQoKc2lnbmVkIG1haW4oKXsKICAgIHJmKCk7CiAgICBjaW4+Pm4+PnE7CiAgICBmZihpLDEsbikgY2luPj5hW2ldOwogICAgZmYoaSwxLG4tMSkKICAgIHsKICAgICAgICBpbnQgdSx2OyBjaW4+PnU+PnY7CiAgICAgICAgZ1t1XS5wYih2KTsgZ1t2XS5wYih1KTsKICAgIH0KICAgIGRmczEoMSwwKTsgZGZzMigxLDEpOwogICAgdmxsIGJhc2UodGltZXJfKzEsMCk7CiAgICBmZihpLDEsbikgYmFzZVtzdFtpXV09YVtpXTsKICAgIGdlbigwKTsKICAgIHNvcnQoYWxsKHNwZXYpKTsgc3Bldi5lcmFzZSh1bmlxdWUoYWxsKHNwZXYpKSwgc3Bldi5lbmQoKSk7CiAgICBzcGVzLnJlc2VydmUoc3Bldi5zaXplKCkqMis3KTsKICAgIGZvcihsbCB2OnNwZXYpIHNwZXMuaW5zZXJ0KHYpOwogICAgVC5pbml0KHRpbWVyXyw1MTIpOwogICAgVC5idWlsZChiYXNlKTsKICAgIHdoaWxlKHEtLSkKICAgIHsKICAgICAgICBpbnQgb3A7IGNpbj4+b3A7CiAgICAgICAgaWYob3A9PTEpCiAgICAgICAgewogICAgICAgICAgICBpbnQgdSx2OyBsbCB4OyBjaW4+PnU+PnY+Png7CiAgICAgICAgICAgIHVwZF9wYXRoKHUsdix4KTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihvcD09MikKICAgICAgICB7CiAgICAgICAgICAgIGludCB1LHY7IGNpbj4+dT4+djsKICAgICAgICAgICAgY291dDw8Z2V0X3BhdGgodSx2KTw8bmw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGludCB1OyBjaW4+PnU7CiAgICAgICAgICAgIGNvdXQ8PGdldF9zdWIodSk8PG5sOwogICAgICAgIH0KICAgIH0KICAgIHJlOwp9Cg==