/* Creation Date - 30-01-2023 */
/* Creation Time - 21:47:56.65 */
#define ill
/*
Written By : mafailure
In the name of God
O Allah, May you grant peace and honor on Muhammad and his family.
Allahumm-a-Sall-iAla Muhammad-in Wa Al-i Muhammad
*/
#ifdef LOCAL
#define AATIF_DEBUG
#endif
/*Add -DLOCAL in
compiler command
to trigger it*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#include <functional> // for less
using namespace std;
using namespace __gnu_pbds;
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl "\n"
/*------------------------int to long long -----------------*/
#ifdef ill
#define int long long
#endif
/*---------------------------DEBUG HELPER--------------------------------------*/
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep; for (const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template<typename T, size_t size> ostream& operator<<(ostream &os, const array<T, size> &arr) { os << '{'; string sep; for (const auto &x : arr) os << sep << x, sep = ", "; return os << '}'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename T,typename K> ostream& operator<<(ostream & os,const map<T,K> & mapp){ os<<"{"; string sep=""; for(const auto& x:mapp)os<<sep<<x,sep=", "; return os<<'}'; }
template <typename T> ostream & operator<<(ostream & os,const set<T> & sett){os<<'{'; string sep=""; for(const auto & x:sett)os<<sep<<x,sep=", "; return os<<'}';}
void dbg_out() { cerr << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
#ifdef AATIF_DEBUG
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif
//#define int long long
// int dx[]={-1,1,0,0}; int dy[]={0,0,1,-1};
// int dx[]={2,2,-2,-2,1,1,-1,-1}; int dy[]={1,-1,1,-1,2,-2,2,-2};
#ifndef mod_2
long long mod = 1e9 + 7;
#else
long long mod =998244353;
#endif
const double eps=1e-9;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef pair<int, int> ii;
typedef vector< pair< int, int > > vii;
typedef map<int, int> mii;
typedef pair<int, ii> pip;
typedef pair<ii, int> ppi;
#define arrinp(arr,init,final,size,type) type* arr=new type[size];for(int i=init;i<final;i++)cin>>arr[i];
#define cr2d(arr,n,m,t) t**arr=new t*[n];for(int i=0;i<n;i++)arr[i]=new t[m];
#define w(t) int t;cin>>t; while(t--)
#define takeInp(n) int n;cin>>n;
#define fr(i,init,final) for(int i=init;i<final;i++)
#define frr(i,init,final) for(int i=init;i>=final;i--)
#define Fr(i,final) for(int i=0;i<final;i++)
#define Frr(i,first) for(int i=first;i>=0;i--)
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define rall(c) (c).rbegin(),(c).rend()
#define debug(x) cerr<<">value ("<<#x<<") : "<<x<<endl;
#define setb __builtin_popcount
#define lsone(n) (n&(-n))
#define rlsone(n) (n&(n-1))
#define clr(a,b) memset(a,b,sizeof(a))
#ifdef ill
const int inf =1e18;
#else
const int inf=1e9;
#endif
/*-----------------------------RANDOM NUMBER GENERATOR ---------------------*/
#ifdef RNG
unsigned seed=chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 rng(seed);
#endif
/*------------------------------UNORDERED MAP HASH --------------------------------------------*/
//To make unordered_map unhackable
// use it as unordered_map<int,int,custom_hash> mapp;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
/* http://x...content-available-to-author-only...i.it/splitmix64.c */
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
/*---------------------------ORDERED SET--------------------------------------*/
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
/*----------------------------------------------------------------------------*/
vi init(string s)
{
istringstream sin(s);
int n;
vi arr;
while(sin>>n)arr.push_back(n);
return arr;
}
int power(int x, int y)
{
if(y==0)return 1;
int u=power(x,y/2);
u=(u*u)%mod;
if(y%2)u=(x*u)%mod;
return u;
}
int gcd(int a,int b)
{
if(a<b)return gcd(b,a);
return (b==0?a:(a%b?gcd(b,a%b):b));
}
int gcd_e(int a,int b,int &x,int &y)
{
if(b==0){x=1; y=0; return a;}
int x1,y1;
int p=gcd_e(b,a%b,x1,y1);
x=y1;
y=x1-(a/b)*y1;
return p;
}
/*-----------------to solve int to long long problem-----------------*/
int Min (int a,int b){return min(a,b);}
int Max(int a,int b){ return max(a,b);}
inline int add(int a,int b,int mod=mod){return (a+b)%mod;}
inline int sub(int a,int b,int mod=mod){return (a-b+mod)%mod;}
inline int mul(int a,int b,int mod=mod){return (a*b%mod);}
inline int divide(int a,int b,int mod=mod){return a*power(b,mod-2)%mod;}
inline int high(int a,int b){return (a>>b)&1;}
//786 121 786 121 786 121 786 121 786 121 786 121 786 121 786 121 786 121
/*========================CODE*****CODE****CODE======================*/
using namespace std;
template <class T = int, class L = int, class A = int>
class segTree
{
public:
#define left (p << 1)
#define right (left | 1)
#define mid ((l + r) >> 1)
#define toleft left, l, mid
#define toright right, mid + 1, r
int n;
vector<T> t;
vector<L> lazy;
vector<A> a;
// T tmp;
segTree(int n) : n(n), t(4 * n), lazy(4 * n,-1) {}
T mer(T a, T b){
T c;
fr(i,0,4)c[i]=a[i]+b[i];
return c;
}
void build(int p, int l, int r)
{
if (l == r)
{
t[p] = T({0,a[l],0,1});
return void();
}
build(toleft);
build(toright);
t[p] = mer(t[left], t[right]);
}
void push(int p, int l, int r)
{
if(lazy[p]==-1)return;
if(lazy[p]){
t[p][1]=t[p][0]+t[p][1];
t[p][0]=0;
t[p][3]+=t[p][2];
t[p][2]=0;
}
else
{
t[p][0]=t[p][0]+t[p][1];
t[p][1]=0;
t[p][2]+=t[p][3];
t[p][3]=0;
}
if(l!=r)lazy[left]=lazy[right]=lazy[p];
lazy[p]=-1;
return;
}
T query(int p, int l, int r, int i, int j)
{
push(p, l, r);
if (i <= l && r <= j)
return t[p];
if (j <= mid)
return query(toleft, i, j);
if (i > mid)
return query(toright, i, j);
return mer(query(toleft, i, j), query(toright, i, j));
}
template <typename V, typename... Args>
void lazy_oper(int p, int l, int r, V val, Args... args)
{
lazy[p]=val;
}
template <typename... V>
void update(int p, int l, int r, int i, int j, V... val)
{
push(p, l, r);
if (r < i || l > j)
return void();
if (i <= l && r <= j)
{
lazy_oper(p, l, r, val...);
push(p, l, r);
return;
}
update(toleft, i, j, val...);
update(toright, i, j, val...);
t[p] = mer(t[left], t[right]);
}
#undef toright
#undef toleft
#undef mid
#undef right
#undef left
};
template <class T = int, class L = int, class A = int>
class HLD
{
public:
segTree<T, L, A> seg;
#define Seg seg
#undef w
vvi g;
vi depth, par, heavy, node, pos, head, w,endpos,mxpos;
int n, cur_pos;
HLD(int n) : n(n), g(n),endpos(n),mxpos(n), cur_pos(0), depth(n), par(n), w(n), heavy(n, -1), node(n), pos(n), head(n), seg(n) {}
void dfs(int u, int p)
{
w[u] = 1;
heavy[u] = -1;
int size = 0;
par[u] = p;
//tin[u]=entry++;
//tout[u]=entry++;
//up[u][0]=p;
//fr(i,1,20)up[u][i]=up[up[u][i-1]][i-1];
// if(g[u].size()==1)leaf[u]=1;
// else leaf[u]=0;
for (auto v : g[u])
{
if (v == p)
continue;
depth[v] = depth[u] + 1;
dfs(v, u);
// leaf[u]+=leaf[v];
w[u] += w[v];
if (w[v] > size)
size = w[v], heavy[u] = v;
}
}
void decompose(int u, int h)
{
head[u] = h;
pos[u] = cur_pos++;
node[pos[u]] = u;
endpos[h]=pos[u];
mxpos[u]=pos[u];
if (~heavy[u])
decompose(heavy[u], h);
for (auto v : g[u])
{
if (v == par[u] || v == heavy[u])
continue;
decompose(v, v);
}
for(auto v:g[u])
{
if(v==par[u])continue;
mxpos[u]=max(mxpos[u],mxpos[v]);
}
}
T mer(T a, T b)
{
T c;
fr(i,0,4)c[i]=a[i]+b[i];
return c;
}
template <typename V>
void update(int u, int v, V val)
{
for (; head[u] != head[v]; v = par[head[v]])
{
if (depth[head[u]] > depth[head[v]])
swap(u, v);
seg.update(1, 0, n - 1, pos[head[v]], pos[v], val);
}
if (depth[u] > depth[v])
swap(u, v);
seg.update(1, 0, n - 1, pos[u], pos[v], val);
}
T query(int u, int v, T ans)
{
for (; head[u] != head[v]; v = par[head[v]])
{
if (depth[head[u]] > depth[head[v]])
swap(u, v);
// dbg(head[v],v);
ans = mer(ans, seg.query(1, 0, n - 1, pos[head[v]], pos[v]));
}
// dbg(u,v);
if (depth[u] > depth[v])
swap(u, v);
return ans = mer(ans, seg.query(1, 0, n - 1, pos[u], pos[v]));
}
void solve();
};
template<class T,class L,class A>
void HLD<T,L,A>:: solve()
{
int q;
cin>>q;
fr(i,0,n-1)
{
int u,v;
cin>>u>>v;
u--; v--;
g[u].pb(v);
g[v].pb(u);
}
vi a(n);
fr(i,0,n)cin>>a[i];
dfs(0,0);
decompose(0,0);
seg.a.resize(n);
fr(i,0,n)seg.a[pos[i]]=a[i];
seg.build(1,0,n-1);
//segTree sub(n);
const int d=20;
/*auto isancestor=[&](int u,int v)->bool
{
return tin[u]<=tin[v]&&tout[u]>=tout[v];
};
auto glca=[&](int u,int v)
{
if(isancestor(u,v))return u;
if(isancestor(v,u))return v;
frr(i,d-1,0)
{
if(!isancestor(up[u][i],v))u=up[u][i];
}
return up[u][0];
};*/
fr(i,0,q)
{
int type;
cin>>type;
if(type==1)
{
int u,v;
cin>>u>>v;
u--; v--;
//int lca=glca(u,v);
T gcnt=query(u,v,T({0,0,0,0}));
if(gcnt[2]==gcnt[3])continue;
if(gcnt[3]>gcnt[2])
{
update(u,v,1);
}
else update(u,v,0);
}
else if(type==2)
{
int x;
cin>>x;
x--;
int u=x;
seg.update(1,0,n-1,pos[u],mxpos[u],0);
}
else
{
int x,y;
cin>>x>>y;
x--; y--;
T gcnt=query(x,y,T({0,0,0,0}));
cout<<max(gcnt[0],gcnt[1])<<endl;
}
}
}
signed main()
{
IOS
int n;
cin>>n;
HLD<array<int,4>,int,int> hld(n);
hld.solve();
}
LyogQ3JlYXRpb24gRGF0ZSAtIDMwLTAxLTIwMjMgKi8gIAovKiBDcmVhdGlvbiBUaW1lIC0gMjE6NDc6NTYuNjUgKi8gIAojZGVmaW5lIGlsbCAKLyoKV3JpdHRlbiBCeSA6IG1hZmFpbHVyZQpJbiB0aGUgbmFtZSBvZiBHb2QgCk8gQWxsYWgsIE1heSB5b3UgZ3JhbnQgcGVhY2UgYW5kIGhvbm9yIG9uIE11aGFtbWFkIGFuZCBoaXMgZmFtaWx5LgpBbGxhaHVtbS1hLVNhbGwtaUFsYSBNdWhhbW1hZC1pbiBXYSBBbC1pIE11aGFtbWFkCiovCgojaWZkZWYgTE9DQUwgCiNkZWZpbmUgQUFUSUZfREVCVUcKI2VuZGlmIAovKkFkZCAtRExPQ0FMIGluIApjb21waWxlciBjb21tYW5kIAp0byB0cmlnZ2VyIGl0Ki8KICAKI2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI2luY2x1ZGUgPGV4dC9wYl9kcy9hc3NvY19jb250YWluZXIuaHBwPiAvLyBDb21tb24gZmlsZSAKI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+IAojaW5jbHVkZSA8ZnVuY3Rpb25hbD4gLy8gZm9yIGxlc3MKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7CiNkZWZpbmUgSU9TIGlvczo6c3luY193aXRoX3N0ZGlvKDApO2Npbi50aWUoMCk7Y291dC50aWUoMCk7CiAKI2RlZmluZSBlbmRsICJcbiIKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1pbnQgdG8gbG9uZyBsb25nIC0tLS0tLS0tLS0tLS0tLS0tKi8KI2lmZGVmIGlsbAojZGVmaW5lIGludCBsb25nIGxvbmcgCiNlbmRpZgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLURFQlVHIEhFTFBFUi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdGVtcGxhdGU8dHlwZW5hbWUgVD4gb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtICZvcywgY29uc3QgdmVjdG9yPFQ+ICZ2KSB7IG9zIDw8ICd7Jzsgc3RyaW5nIHNlcDsgZm9yIChjb25zdCBhdXRvICZ4IDogdikgb3MgPDwgc2VwIDw8IHgsIHNlcCA9ICIsICI7IHJldHVybiBvcyA8PCAnfSc7IH0KdGVtcGxhdGU8dHlwZW5hbWUgVCwgc2l6ZV90IHNpemU+IG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSAmb3MsIGNvbnN0IGFycmF5PFQsIHNpemU+ICZhcnIpIHsgb3MgPDwgJ3snOyBzdHJpbmcgc2VwOyBmb3IgKGNvbnN0IGF1dG8gJnggOiBhcnIpIG9zIDw8IHNlcCA8PCB4LCBzZXAgPSAiLCAiOyByZXR1cm4gb3MgPDwgJ30nOyB9CnRlbXBsYXRlPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+IG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSAmb3MsIGNvbnN0IHBhaXI8QSwgQj4gJnApIHsgcmV0dXJuIG9zIDw8ICcoJyA8PCBwLmZpcnN0IDw8ICIsICIgPDwgcC5zZWNvbmQgPDwgJyknOyB9CnRlbXBsYXRlPHR5cGVuYW1lIFQsdHlwZW5hbWUgSz4gb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtICYgb3MsY29uc3QgbWFwPFQsSz4gJiBtYXBwKXsgb3M8PCJ7Ijsgc3RyaW5nIHNlcD0iIjsgZm9yKGNvbnN0IGF1dG8mIHg6bWFwcClvczw8c2VwPDx4LHNlcD0iLCAiOyByZXR1cm4gb3M8PCd9JzsgfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gb3N0cmVhbSAmIG9wZXJhdG9yPDwob3N0cmVhbSAmIG9zLGNvbnN0IHNldDxUPiAmIHNldHQpe29zPDwneyc7IHN0cmluZyBzZXA9IiI7IGZvcihjb25zdCBhdXRvICYgeDpzZXR0KW9zPDxzZXA8PHgsc2VwPSIsICI7IHJldHVybiBvczw8J30nO30KIAp2b2lkIGRiZ19vdXQoKSB7IGNlcnIgPDwgZW5kbDsgfQp0ZW1wbGF0ZTx0eXBlbmFtZSBIZWFkLCB0eXBlbmFtZS4uLiBUYWlsPiB2b2lkIGRiZ19vdXQoSGVhZCBILCBUYWlsLi4uIFQpIHsgY2VyciA8PCAnICcgPDwgSDsgZGJnX291dChULi4uKTsgfQogCiNpZmRlZiBBQVRJRl9ERUJVRwojZGVmaW5lIGRiZyguLi4pIGNlcnIgPDwgIigiIDw8ICNfX1ZBX0FSR1NfXyA8PCAiKToiLCBkYmdfb3V0KF9fVkFfQVJHU19fKQojZWxzZQojZGVmaW5lIGRiZyguLi4pCiNlbmRpZgogCi8vI2RlZmluZSBpbnQgbG9uZyBsb25nIAovLyBpbnQgZHhbXT17LTEsMSwwLDB9OyBpbnQgZHlbXT17MCwwLDEsLTF9OwovLyBpbnQgZHhbXT17MiwyLC0yLC0yLDEsMSwtMSwtMX07IGludCBkeVtdPXsxLC0xLDEsLTEsMiwtMiwyLC0yfTsKI2lmbmRlZiBtb2RfMiAKbG9uZyBsb25nIG1vZCA9IDFlOSArIDc7CiNlbHNlIApsb25nIGxvbmcgbW9kID05OTgyNDQzNTM7IAojZW5kaWYgCmNvbnN0IGRvdWJsZSBlcHM9MWUtOTsKdHlwZWRlZiB2ZWN0b3I8aW50PiB2aTsKdHlwZWRlZiB2ZWN0b3I8dmk+IHZ2aTsKdHlwZWRlZiB2ZWN0b3I8c3RyaW5nPiB2czsKdHlwZWRlZiB2ZWN0b3I8Ym9vbD4gdmI7CnR5cGVkZWYgcGFpcjxpbnQsIGludD4gaWk7CnR5cGVkZWYgdmVjdG9yPCBwYWlyPCBpbnQsIGludCA+ID4gdmlpOwp0eXBlZGVmIG1hcDxpbnQsIGludD4gbWlpOwp0eXBlZGVmIHBhaXI8aW50LCBpaT4gcGlwOwp0eXBlZGVmIHBhaXI8aWksIGludD4gcHBpOwojZGVmaW5lIGFycmlucChhcnIsaW5pdCxmaW5hbCxzaXplLHR5cGUpIHR5cGUqIGFycj1uZXcgdHlwZVtzaXplXTtmb3IoaW50IGk9aW5pdDtpPGZpbmFsO2krKyljaW4+PmFycltpXTsKI2RlZmluZSBjcjJkKGFycixuLG0sdCkgdCoqYXJyPW5ldyB0KltuXTtmb3IoaW50IGk9MDtpPG47aSsrKWFycltpXT1uZXcgdFttXTsKI2RlZmluZSB3KHQpIGludCB0O2Npbj4+dDsgd2hpbGUodC0tKQojZGVmaW5lIHRha2VJbnAobikgaW50IG47Y2luPj5uOwojZGVmaW5lIGZyKGksaW5pdCxmaW5hbCkgZm9yKGludCBpPWluaXQ7aTxmaW5hbDtpKyspCiNkZWZpbmUgZnJyKGksaW5pdCxmaW5hbCkgZm9yKGludCBpPWluaXQ7aT49ZmluYWw7aS0tKQojZGVmaW5lIEZyKGksZmluYWwpIGZvcihpbnQgaT0wO2k8ZmluYWw7aSsrKQojZGVmaW5lIEZycihpLGZpcnN0KSBmb3IoaW50IGk9Zmlyc3Q7aT49MDtpLS0pCiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBtcCBtYWtlX3BhaXIKI2RlZmluZSBwYiBwdXNoX2JhY2sKI2RlZmluZSBhbGwoYykgKGMpLmJlZ2luKCksKGMpLmVuZCgpCiNkZWZpbmUgcmFsbChjKSAoYykucmJlZ2luKCksKGMpLnJlbmQoKQojZGVmaW5lIGRlYnVnKHgpIGNlcnI8PCI+dmFsdWUgKCI8PCN4PDwiKSA6ICI8PHg8PGVuZGw7CiNkZWZpbmUgc2V0YiBfX2J1aWx0aW5fcG9wY291bnQKI2RlZmluZSBsc29uZShuKSAobiYoLW4pKQojZGVmaW5lIHJsc29uZShuKSAobiYobi0xKSkKI2RlZmluZSBjbHIoYSxiKSBtZW1zZXQoYSxiLHNpemVvZihhKSkKI2lmZGVmIGlsbCAKY29uc3QgaW50IGluZiA9MWUxODsgCiNlbHNlIApjb25zdCBpbnQgaW5mPTFlOTsKI2VuZGlmCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1SQU5ET00gTlVNQkVSIEdFTkVSQVRPUiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwojaWZkZWYgUk5HIAp1bnNpZ25lZCBzZWVkPWNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKTsKbXQxOTkzNyBybmcoc2VlZCk7CiNlbmRpZiAKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1VTk9SREVSRUQgTUFQIEhBU0ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwovL1RvIG1ha2UgdW5vcmRlcmVkX21hcCB1bmhhY2thYmxlIAovLyB1c2UgaXQgYXMgdW5vcmRlcmVkX21hcDxpbnQsaW50LGN1c3RvbV9oYXNoPiBtYXBwOwpzdHJ1Y3QgY3VzdG9tX2hhc2ggewogICAgc3RhdGljIHVpbnQ2NF90IHNwbGl0bWl4NjQodWludDY0X3QgeCkgewogICAgICAgIC8qIGh0dHA6Ly94Li4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5pLml0L3NwbGl0bWl4NjQuYyAqLwogICAgICAgIHggKz0gMHg5ZTM3NzliOTdmNGE3YzE1OwogICAgICAgIHggPSAoeCBeICh4ID4+IDMwKSkgKiAweGJmNTg0NzZkMWNlNGU1Yjk7CiAgICAgICAgeCA9ICh4IF4gKHggPj4gMjcpKSAqIDB4OTRkMDQ5YmIxMzMxMTFlYjsKICAgICAgICByZXR1cm4geCBeICh4ID4+IDMxKTsKICAgIH0KIAogICAgc2l6ZV90IG9wZXJhdG9yKCkodWludDY0X3QgeCkgY29uc3QgewogICAgICAgIHN0YXRpYyBjb25zdCB1aW50NjRfdCBGSVhFRF9SQU5ET00gPSBjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCk7CiAgICAgICAgcmV0dXJuIHNwbGl0bWl4NjQoeCArIEZJWEVEX1JBTkRPTSk7CiAgICB9Cn07Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tT1JERVJFRCBTRVQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnR5cGVkZWYgdHJlZTxpbnQsIG51bGxfdHlwZSwgbGVzczxpbnQ+LCByYl90cmVlX3RhZywgdHJlZV9vcmRlcl9zdGF0aXN0aWNzX25vZGVfdXBkYXRlPiAgb3JkZXJlZF9zZXQ7IAovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2aSBpbml0KHN0cmluZyBzKQp7Cglpc3RyaW5nc3RyZWFtIHNpbihzKTsKCWludCBuOwoJdmkgYXJyOwoJd2hpbGUoc2luPj5uKWFyci5wdXNoX2JhY2sobik7CglyZXR1cm4gYXJyOwp9CmludCBwb3dlcihpbnQgeCwgaW50IHkpCnsgCglpZih5PT0wKXJldHVybiAxOwoJaW50IHU9cG93ZXIoeCx5LzIpOwoJdT0odSp1KSVtb2Q7CglpZih5JTIpdT0oeCp1KSVtb2Q7CglyZXR1cm4gdTsKICAgIAp9CmludCBnY2QoaW50IGEsaW50IGIpCnsKCWlmKGE8YilyZXR1cm4gZ2NkKGIsYSk7CglyZXR1cm4gKGI9PTA/YTooYSViP2djZChiLGElYik6YikpOwp9CmludCBnY2RfZShpbnQgYSxpbnQgYixpbnQgJngsaW50ICZ5KQp7CgkKCWlmKGI9PTApe3g9MTsgeT0wOyByZXR1cm4gYTt9CglpbnQgeDEseTE7CglpbnQgcD1nY2RfZShiLGElYix4MSx5MSk7Cgl4PXkxOwoJeT14MS0oYS9iKSp5MTsKCXJldHVybiBwOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS10byBzb2x2ZSBpbnQgdG8gbG9uZyBsb25nIHByb2JsZW0tLS0tLS0tLS0tLS0tLS0tLSovCmludCBNaW4gKGludCBhLGludCBiKXtyZXR1cm4gbWluKGEsYik7fQppbnQgTWF4KGludCBhLGludCBiKXsgcmV0dXJuIG1heChhLGIpO30KaW5saW5lIGludCBhZGQoaW50IGEsaW50IGIsaW50IG1vZD1tb2Qpe3JldHVybiAoYStiKSVtb2Q7fSAKaW5saW5lIGludCBzdWIoaW50IGEsaW50IGIsaW50IG1vZD1tb2Qpe3JldHVybiAoYS1iK21vZCklbW9kO30KaW5saW5lIGludCBtdWwoaW50IGEsaW50IGIsaW50IG1vZD1tb2Qpe3JldHVybiAoYSpiJW1vZCk7fQppbmxpbmUgaW50IGRpdmlkZShpbnQgYSxpbnQgYixpbnQgbW9kPW1vZCl7cmV0dXJuIGEqcG93ZXIoYixtb2QtMiklbW9kO30KaW5saW5lIGludCBoaWdoKGludCBhLGludCBiKXtyZXR1cm4gKGE+PmIpJjE7fQovLzc4NiAxMjEgNzg2IDEyMSA3ODYgMTIxIDc4NiAxMjEgNzg2IDEyMSA3ODYgMTIxIDc4NiAxMjEgNzg2IDEyMSA3ODYgMTIxCi8qPT09PT09PT09PT09PT09PT09PT09PT09Q09ERSoqKioqQ09ERSoqKipDT0RFPT09PT09PT09PT09PT09PT09PT09PSovCgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlIDxjbGFzcyBUID0gaW50LCBjbGFzcyBMID0gaW50LCBjbGFzcyBBID0gaW50PgpjbGFzcyBzZWdUcmVlCnsKcHVibGljOgojZGVmaW5lIGxlZnQgKHAgPDwgMSkKI2RlZmluZSByaWdodCAobGVmdCB8IDEpCiNkZWZpbmUgbWlkICgobCArIHIpID4+IDEpCiNkZWZpbmUgdG9sZWZ0IGxlZnQsIGwsIG1pZAojZGVmaW5lIHRvcmlnaHQgcmlnaHQsIG1pZCArIDEsIHIKCWludCBuOwoJdmVjdG9yPFQ+IHQ7Cgl2ZWN0b3I8TD4gbGF6eTsKCXZlY3RvcjxBPiBhOwoJLy8gVCB0bXA7CglzZWdUcmVlKGludCBuKSA6IG4obiksIHQoNCAqIG4pLCBsYXp5KDQgKiBuLC0xKSB7fQoJVCBtZXIoVCBhLCBUIGIpewoJICAgIFQgYzsgCgkgICAgZnIoaSwwLDQpY1tpXT1hW2ldK2JbaV07IAoJICAgIHJldHVybiBjOyAKCQkgfQoJdm9pZCBidWlsZChpbnQgcCwgaW50IGwsIGludCByKQoJewoJCWlmIChsID09IHIpCgkJewoJCQl0W3BdID0gVCh7MCxhW2xdLDAsMX0pOwoJCQlyZXR1cm4gdm9pZCgpOwoJCX0KCQlidWlsZCh0b2xlZnQpOwoJCWJ1aWxkKHRvcmlnaHQpOwoJCXRbcF0gPSBtZXIodFtsZWZ0XSwgdFtyaWdodF0pOwoJfQoJdm9pZCBwdXNoKGludCBwLCBpbnQgbCwgaW50IHIpCgl7CgkJaWYobGF6eVtwXT09LTEpcmV0dXJuOyAKCQlpZihsYXp5W3BdKXsKCQl0W3BdWzFdPXRbcF1bMF0rdFtwXVsxXTsKCQl0W3BdWzBdPTA7ICAKCQl0W3BdWzNdKz10W3BdWzJdOyAKCQl0W3BdWzJdPTA7CgkJCX0KCQllbHNlIAoJCXsKCQkJdFtwXVswXT10W3BdWzBdK3RbcF1bMV07IAoJCQl0W3BdWzFdPTA7CgkJCXRbcF1bMl0rPXRbcF1bM107CgkJCXRbcF1bM109MDsgIAoJCX0KCQlpZihsIT1yKWxhenlbbGVmdF09bGF6eVtyaWdodF09bGF6eVtwXTsgCgkJbGF6eVtwXT0tMTsgCgkJcmV0dXJuOwoJfQoJVCBxdWVyeShpbnQgcCwgaW50IGwsIGludCByLCBpbnQgaSwgaW50IGopCgl7CgkJcHVzaChwLCBsLCByKTsKCQlpZiAoaSA8PSBsICYmIHIgPD0gaikKCQkJcmV0dXJuIHRbcF07CgkJaWYgKGogPD0gbWlkKQoJCQlyZXR1cm4gcXVlcnkodG9sZWZ0LCBpLCBqKTsKCQlpZiAoaSA+IG1pZCkKCQkJcmV0dXJuIHF1ZXJ5KHRvcmlnaHQsIGksIGopOwoJCXJldHVybiBtZXIocXVlcnkodG9sZWZ0LCBpLCBqKSwgcXVlcnkodG9yaWdodCwgaSwgaikpOwoJfQoJdGVtcGxhdGUgPHR5cGVuYW1lIFYsIHR5cGVuYW1lLi4uIEFyZ3M+Cgl2b2lkIGxhenlfb3BlcihpbnQgcCwgaW50IGwsIGludCByLCBWIHZhbCwgQXJncy4uLiBhcmdzKQoJewoJCWxhenlbcF09dmFsOyAgCgl9Cgl0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVj4KCXZvaWQgdXBkYXRlKGludCBwLCBpbnQgbCwgaW50IHIsIGludCBpLCBpbnQgaiwgVi4uLiB2YWwpCgl7CgkJcHVzaChwLCBsLCByKTsKCQlpZiAociA8IGkgfHwgbCA+IGopCgkJCXJldHVybiB2b2lkKCk7CgkJaWYgKGkgPD0gbCAmJiByIDw9IGopCgkJewoJCQlsYXp5X29wZXIocCwgbCwgciwgdmFsLi4uKTsKCQkJcHVzaChwLCBsLCByKTsKCQkJcmV0dXJuOwoJCX0KCQl1cGRhdGUodG9sZWZ0LCBpLCBqLCB2YWwuLi4pOwoJCXVwZGF0ZSh0b3JpZ2h0LCBpLCBqLCB2YWwuLi4pOwoJCXRbcF0gPSBtZXIodFtsZWZ0XSwgdFtyaWdodF0pOwoJfQoJCiN1bmRlZiB0b3JpZ2h0CiN1bmRlZiB0b2xlZnQKI3VuZGVmIG1pZAojdW5kZWYgcmlnaHQKI3VuZGVmIGxlZnQKfTsKCnRlbXBsYXRlIDxjbGFzcyBUID0gaW50LCBjbGFzcyBMID0gaW50LCBjbGFzcyBBID0gaW50PgpjbGFzcyBITEQKewpwdWJsaWM6CglzZWdUcmVlPFQsIEwsIEE+IHNlZzsKI2RlZmluZSBTZWcgc2VnCiN1bmRlZiB3Cgl2dmkgZzsKCXZpIGRlcHRoLCBwYXIsIGhlYXZ5LCBub2RlLCBwb3MsIGhlYWQsIHcsZW5kcG9zLG14cG9zOwoJCgoJaW50IG4sIGN1cl9wb3M7IAoJSExEKGludCBuKSA6IG4obiksIGcobiksZW5kcG9zKG4pLG14cG9zKG4pLCBjdXJfcG9zKDApLCBkZXB0aChuKSwgcGFyKG4pLCB3KG4pLCBoZWF2eShuLCAtMSksIG5vZGUobiksIHBvcyhuKSwgaGVhZChuKSwgc2VnKG4pIHt9Cgl2b2lkIGRmcyhpbnQgdSwgaW50IHApCgl7CgkJd1t1XSA9IDE7CgkJaGVhdnlbdV0gPSAtMTsKCQlpbnQgc2l6ZSA9IDA7CgkJcGFyW3VdID0gcDsKCQkvL3Rpblt1XT1lbnRyeSsrOyAKCQkvL3RvdXRbdV09ZW50cnkrKzsgCgkJLy91cFt1XVswXT1wOyAKCQkvL2ZyKGksMSwyMCl1cFt1XVtpXT11cFt1cFt1XVtpLTFdXVtpLTFdOyAKCQkvLyBpZihnW3VdLnNpemUoKT09MSlsZWFmW3VdPTE7CgkJLy8gZWxzZSBsZWFmW3VdPTA7CgkJZm9yIChhdXRvIHYgOiBnW3VdKQoJCXsKCQkJaWYgKHYgPT0gcCkKCQkJCWNvbnRpbnVlOwoJCQlkZXB0aFt2XSA9IGRlcHRoW3VdICsgMTsKCQkJZGZzKHYsIHUpOwoJCQkvLyBsZWFmW3VdKz1sZWFmW3ZdOwoJCQl3W3VdICs9IHdbdl07CgkJCWlmICh3W3ZdID4gc2l6ZSkKCQkJCXNpemUgPSB3W3ZdLCBoZWF2eVt1XSA9IHY7CgkJfQoJfQoKCXZvaWQgZGVjb21wb3NlKGludCB1LCBpbnQgaCkKCXsKCQloZWFkW3VdID0gaDsKCQlwb3NbdV0gPSBjdXJfcG9zKys7CgkJbm9kZVtwb3NbdV1dID0gdTsgIAoJCWVuZHBvc1toXT1wb3NbdV07IAoJCW14cG9zW3VdPXBvc1t1XTsgCgkJaWYgKH5oZWF2eVt1XSkKCQkJZGVjb21wb3NlKGhlYXZ5W3VdLCBoKTsKCQlmb3IgKGF1dG8gdiA6IGdbdV0pCgkJewoJCQlpZiAodiA9PSBwYXJbdV0gfHwgdiA9PSBoZWF2eVt1XSkKCQkJCWNvbnRpbnVlOwoJCQlkZWNvbXBvc2Uodiwgdik7CgkJfQoJCWZvcihhdXRvIHY6Z1t1XSkKCQl7CgkJCWlmKHY9PXBhclt1XSljb250aW51ZTsgCgkJCW14cG9zW3VdPW1heChteHBvc1t1XSxteHBvc1t2XSk7IAoJCX0KCX0KCVQgbWVyKFQgYSwgVCBiKQoJewoJCVQgYzsgCgkJZnIoaSwwLDQpY1tpXT1hW2ldK2JbaV07IAoJCXJldHVybiBjOwoJfQoKCXRlbXBsYXRlIDx0eXBlbmFtZSBWPgoJdm9pZCB1cGRhdGUoaW50IHUsIGludCB2LCBWIHZhbCkKCXsKCQlmb3IgKDsgaGVhZFt1XSAhPSBoZWFkW3ZdOyB2ID0gcGFyW2hlYWRbdl1dKQoJCXsKCQkJaWYgKGRlcHRoW2hlYWRbdV1dID4gZGVwdGhbaGVhZFt2XV0pCgkJCQlzd2FwKHUsIHYpOwoJCQlzZWcudXBkYXRlKDEsIDAsIG4gLSAxLCBwb3NbaGVhZFt2XV0sIHBvc1t2XSwgdmFsKTsKCQl9CgkJaWYgKGRlcHRoW3VdID4gZGVwdGhbdl0pCgkJCXN3YXAodSwgdik7CgkJc2VnLnVwZGF0ZSgxLCAwLCBuIC0gMSwgcG9zW3VdLCBwb3Nbdl0sIHZhbCk7Cgl9CglUIHF1ZXJ5KGludCB1LCBpbnQgdiwgVCBhbnMpCgl7CgkJZm9yICg7IGhlYWRbdV0gIT0gaGVhZFt2XTsgdiA9IHBhcltoZWFkW3ZdXSkKCQl7CgkJCWlmIChkZXB0aFtoZWFkW3VdXSA+IGRlcHRoW2hlYWRbdl1dKQoJCQkJc3dhcCh1LCB2KTsKCQkJLy8gZGJnKGhlYWRbdl0sdik7CgkJCWFucyA9IG1lcihhbnMsIHNlZy5xdWVyeSgxLCAwLCBuIC0gMSwgcG9zW2hlYWRbdl1dLCBwb3Nbdl0pKTsKCQl9CgkJLy8gZGJnKHUsdik7CgkJaWYgKGRlcHRoW3VdID4gZGVwdGhbdl0pCgkJCXN3YXAodSwgdik7CgoJCXJldHVybiBhbnMgPSBtZXIoYW5zLCBzZWcucXVlcnkoMSwgMCwgbiAtIDEsIHBvc1t1XSwgcG9zW3ZdKSk7Cgl9Cgl2b2lkIHNvbHZlKCk7Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBULGNsYXNzIEwsY2xhc3MgQT4gCnZvaWQgSExEPFQsTCxBPjo6IHNvbHZlKCkKewoJaW50IHE7IAoJY2luPj5xOyAKCWZyKGksMCxuLTEpCgl7CgkJaW50IHUsdjsgCgkJY2luPj51Pj52OyAKCQl1LS07IHYtLTsgCgkJZ1t1XS5wYih2KTsgCgkJZ1t2XS5wYih1KTsgCgl9Cgl2aSBhKG4pOyAKCWZyKGksMCxuKWNpbj4+YVtpXTsgCgkgCgkKCWRmcygwLDApOyAKCWRlY29tcG9zZSgwLDApOwoJc2VnLmEucmVzaXplKG4pOyAKCWZyKGksMCxuKXNlZy5hW3Bvc1tpXV09YVtpXTsgCglzZWcuYnVpbGQoMSwwLG4tMSk7IAoJLy9zZWdUcmVlIHN1YihuKTsgCgkKCWNvbnN0IGludCBkPTIwOyAKCS8qYXV0byBpc2FuY2VzdG9yPVsmXShpbnQgdSxpbnQgdiktPmJvb2wgCgl7CgkJcmV0dXJuIHRpblt1XTw9dGluW3ZdJiZ0b3V0W3VdPj10b3V0W3ZdOyAKCX07CglhdXRvIGdsY2E9WyZdKGludCB1LGludCB2KQoJewoJCWlmKGlzYW5jZXN0b3IodSx2KSlyZXR1cm4gdTsgCgkJaWYoaXNhbmNlc3Rvcih2LHUpKXJldHVybiB2OyAKCQlmcnIoaSxkLTEsMCkKCQl7CgkJCWlmKCFpc2FuY2VzdG9yKHVwW3VdW2ldLHYpKXU9dXBbdV1baV07IAkKCQl9CgkJcmV0dXJuIHVwW3VdWzBdOyAKCX07Ki8KCQoJZnIoaSwwLHEpCgl7CgkJaW50IHR5cGU7IAoJCWNpbj4+dHlwZTsgCgkJaWYodHlwZT09MSkKCQl7CgkJCWludCB1LHY7IAoJCQljaW4+PnU+PnY7IAoJCQl1LS07IHYtLTsgCgkJCS8vaW50IGxjYT1nbGNhKHUsdik7IAoJCQlUIGdjbnQ9cXVlcnkodSx2LFQoezAsMCwwLDB9KSk7IAoJCQlpZihnY250WzJdPT1nY250WzNdKWNvbnRpbnVlOyAKCQkJaWYoZ2NudFszXT5nY250WzJdKQoJCQl7CgkJCQl1cGRhdGUodSx2LDEpOyAKCQkJfQoJCQllbHNlIHVwZGF0ZSh1LHYsMCk7IAoJCQkKCQl9CgkJZWxzZSBpZih0eXBlPT0yKQoJCXsKCQkJaW50IHg7IAoJCQljaW4+Png7IAoJCQl4LS07IAoJCQlpbnQgdT14OyAKCQkJc2VnLnVwZGF0ZSgxLDAsbi0xLHBvc1t1XSxteHBvc1t1XSwwKTsgCgkJfQoJCWVsc2UKCQl7CgkJCWludCB4LHk7CgkJCWNpbj4+eD4+eTsKCQkJeC0tOyB5LS07IAoJCQlUIGdjbnQ9cXVlcnkoeCx5LFQoezAsMCwwLDB9KSk7IAoJCQljb3V0PDxtYXgoZ2NudFswXSxnY250WzFdKTw8ZW5kbDsgCgkJfQoJfQoJCgkKCQoJIAoJCgkKfQoKc2lnbmVkIG1haW4oKQp7CglJT1MKCQoJaW50IG47IAoJY2luPj5uOyAKCUhMRDxhcnJheTxpbnQsND4saW50LGludD4gaGxkKG4pOwoJaGxkLnNvbHZlKCk7IAoJCgkgCgkKCQkgCn0KCgoK