//
// Created by Bhagirathi on 2019-04-21.
//
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <queue>
#include <deque>
#include <bitset>
#include <iterator>
#include <list>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <numeric>
#include <utility>
#include <limits>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <algorithm>
#include <chrono>
#include <random>
#include <vector>
using namespace std;
/******* All Required define Pre-Processors and typedef Constants *******/
#define SCD(t) scanf("%d",&t)
#define SCLD(t) scanf("%ld",&t)
#define SCLLD(t) scanf("%lld",&t)
#define SCC(t) scanf("%c",&t)
#define SCS(t) scanf("%s",t)
#define SCF(t) scanf("%f",&t)
#define SCLF(t) scanf("%lf",&t)
#define MEM(a, b) memset(a, (b), sizeof(a))
#define FOR(i, j, k, in) for (int i=j ; i<k ; i+=in)
#define RFOR(i, j, k, in) for (int i=j ; i>=k ; i-=in)
#define REP(i, j) FOR(i, 0, j, 1)
#define RREP(i, j) RFOR(i, j, 0, 1)
#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define FOREACH(it, l) for (auto it = l.begin(); it != l.end(); it++)
#define IN(A, B, C) assert( B <= A && A <= C)
#define MP make_pair
#define PB push_back
#define INF (int)1e9
#define EPS 1e-9
#define PI 3.1415926535897932384626433832795
#define MOD 1000000007
#define read(type) readInt<type>()
const double pi=acos(-1.0);
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef map<int,int> MPII;
typedef set<int> SETI;
typedef multiset<int> MSETI;
typedef long int int32;
typedef unsigned long int uint32;
typedef long long int int64;
typedef unsigned long long int uint64;
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
/****** Template of some basic operations *****/
template<typename T, typename U> inline void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> inline void amax(T &x, U y) { if(x < y) x = y; }
/**********************************************/
using namespace std;
const int MAXN = (int)1e7;
const int LOGMAXN = 31;
int zero[MAXN],one[MAXN],leafValue[MAXN];
int nodeCount = 0;
int root[MAXN],currRoot=0;
map<int64,int> idToNodeNumber;
map<int64,int> idToEncryption;
map<int64,VI> adj;
int64 maxAns=0,minAns=0;
void printDFS(int i, int64 r);
int newNode(int lef, int rig) {
int p = ++nodeCount;
zero[p] = lef;
one[p] = rig;
return p;
}
int newLeaf(int val) {
int p = ++nodeCount;
zero[p]=one[p]=0;
leafValue[p] = val;
return p;
}
int countBits(int n)
{
int count = 0;
while (n)
{
count++;
n >>= 1;
}
return count;
}
void maxXOR(int trieIndex,int val,int valBitIndex,int appendZeroes){
if(appendZeroes>0){
if(one[trieIndex]!=0){ //want to go right
maxXOR(one[trieIndex],val,valBitIndex,appendZeroes-1);
maxAns += (int)pow(2,valBitIndex+appendZeroes-1);
}
else{
maxXOR(zero[trieIndex],val,valBitIndex,appendZeroes-1);
}
}
else{
if(valBitIndex==0)
return;
int bit = (1<<(valBitIndex-1))&val;
if(bit==0){//go right
if(one[trieIndex]!=0){ //want to go right
maxXOR(one[trieIndex],val,valBitIndex-1,appendZeroes);
maxAns += (int)pow(2,valBitIndex-1);
}
else{
maxXOR(zero[trieIndex],val,valBitIndex-1,appendZeroes);
}
}
else{//go left
if(zero[trieIndex]!=0) { //want to go left
maxXOR(zero[trieIndex],val,valBitIndex-1,appendZeroes);
maxAns += (int)pow(2,valBitIndex-1);
}
else{
maxXOR(one[trieIndex],val,valBitIndex-1,appendZeroes);
}
}
}
}
void minXOR(int trieIndex,int val,int valBitIndex,int appendZeroes){
if(appendZeroes>0){
if(zero[trieIndex]!=0){ //want to go left
minXOR(zero[trieIndex],val,valBitIndex,appendZeroes-1);
}
else{ //have to go right no choice left
minXOR(one[trieIndex],val,valBitIndex,appendZeroes-1);
minAns += (int)pow(2,valBitIndex+appendZeroes-1);
}
}
else{
if(valBitIndex==0)
return;
int bit = (1<<(valBitIndex-1))&val;
if(bit==0){//go left
if(zero[trieIndex]!=0){ //want to go left
minXOR(zero[trieIndex],val,valBitIndex-1,appendZeroes);
}
else{//have to go right no choice left
minXOR(one[trieIndex],val,valBitIndex-1,appendZeroes);
minAns += (int)pow(2,valBitIndex-1);
}
}
else{//go right
if(one[trieIndex]!=0) { //want to go right
minXOR(one[trieIndex],val,valBitIndex-1,appendZeroes);
}
else{//have to go left no choice left
minXOR(zero[trieIndex],val,valBitIndex-1,appendZeroes);
minAns += (int)pow(2,valBitIndex-1);
}
}
}
}
int insert(int prevPointer,int val,int valBitIndex,int appendZeroes){
if(appendZeroes>0){
return newNode(insert(zero[prevPointer],val,valBitIndex,appendZeroes-1),one[prevPointer]);
}
else{
if(valBitIndex==0)
return newLeaf(val);
int64 bit = (1<<(valBitIndex-1))&val;
if(bit==0){//go left
return newNode(insert(zero[prevPointer],val,valBitIndex-1,appendZeroes),
one[prevPointer]);
}
else{//go right
return newNode(zero[prevPointer],
insert(one[prevPointer],val,valBitIndex-1,appendZeroes));
}
}
}
void printTrie(int index){
cout<<"node number: "<<index<<"\n";
if(zero[index]==0 && one[index]==0) {
cout<<"leaf hit\n";
return;
}
cout<<"going left\n";
printTrie(zero[index]);
cout<<"going right\n";
printTrie(one[index]);
}
void dfs(int p,int u){
int v;
for (int i = 0; i < adj[u].size(); ++i) {
v = adj[u][i];
if(v!=p) {
int bitsCount = countBits(idToEncryption[v]);
//cout<<"current Node: "<<u<<" , parent node number = "<<idToNodeNumber[u]<<"\n";
int t = insert(idToNodeNumber[u],idToEncryption[v],bitsCount,LOGMAXN-bitsCount);
idToNodeNumber[v]=t;
dfs(u, v);
}
}
}
void printDFS(int p, int64 u) {
cout<<"NODE : "<<u<<"\n";
printTrie(idToNodeNumber[u]);
int v;
for (int i = 0; i < adj[u].size(); ++i) {
v = adj[u][i];
if(v!=p) {
printDFS(u, v);
}
}
}
int main()
{
MEM(zero,0);
MEM(one,0);
MEM(root,0);
#ifndef ONLINE_JUDGE
freopen("/Users/bhagirathi/Documents/CLionProjects/codeforces/debug/input.txt", "r", stdin);
freopen("/Users/bhagirathi/Documents/CLionProjects/codeforces/debug/output.txt", "w", stdout);
#endif
int n,q;
cin>>n>>q;
int64 r,key;
cin>>r>>key;
idToEncryption[r]=key;
int64 u,v,k;
for (int i = 0; i <n-1 ; ++i) {
cin>>u>>v>>k;
VI currNeighbours = adj[v];
currNeighbours.push_back(u);
adj[v] = currNeighbours;
idToEncryption[u]=k;
}
// for (auto it = adj.begin(); it != adj.end() ; it++) {
//
// cout<<" NODE: "<<it->first<<"\n";
// VI curr = it->second;
// for (int i = 0; i <curr.size() ; ++i) {
// cout<<curr[i]<<" ";
// }
// cout<<"\n";
//
// }
idToNodeNumber[0]=0;
int bitsCount = countBits(key);
int t = insert(0,key,bitsCount,LOGMAXN-bitsCount);
idToNodeNumber[r] = t;
dfs(0,r);
//printDFS(0,r);
int last_answer = 0;
for (int i = 0; i < q; i++)
{
cin >> t;
// find real value of t
t ^= last_answer;
if (t == 0)
{
cin >> v >> u >> k;
// find real values for u, v, and k
u ^= last_answer;
v ^= last_answer;
k ^= last_answer;
//insert
adj[v].push_back(u);
bitsCount = countBits(k);
idToEncryption[u]=k;
t = insert(idToNodeNumber[v],k,bitsCount,LOGMAXN-bitsCount);
idToNodeNumber[u] = t;
}
else
{
cin >> v >> k;
// find real values for v, and k
v ^= last_answer;
k ^= last_answer;
//cout<<"NODE NUMBER QUERY: "<<idToNodeNumber[v]<<"\n";
// compute the requested values
bitsCount = countBits(k);
minXOR(idToNodeNumber[v],k,bitsCount,LOGMAXN-bitsCount);
int min_answer = minAns;
minAns = 0;
maxXOR(idToNodeNumber[v],k,bitsCount,LOGMAXN-bitsCount);
int max_answer = maxAns;
maxAns =0;
cout<<min_answer<<" "<<max_answer<<"\n";
// update last_answer
last_answer = min_answer ^ max_answer;
}
}
return 0;
}
Ly8KLy8gQ3JlYXRlZCBieSBCaGFnaXJhdGhpIG9uIDIwMTktMDQtMjEuCi8vCgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxzc3RyZWFtPgojaW5jbHVkZSA8cXVldWU+CiNpbmNsdWRlIDxkZXF1ZT4KI2luY2x1ZGUgPGJpdHNldD4KI2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8bGlzdD4KI2luY2x1ZGUgPHN0YWNrPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPG51bWVyaWM+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8bGltaXRzPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8bWF0aC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGNocm9ubz4KI2luY2x1ZGUgPHJhbmRvbT4KI2luY2x1ZGUgPHZlY3Rvcj4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8qKioqKioqICBBbGwgUmVxdWlyZWQgZGVmaW5lIFByZS1Qcm9jZXNzb3JzIGFuZCB0eXBlZGVmIENvbnN0YW50cyAqKioqKioqLwojZGVmaW5lIFNDRCh0KSBzY2FuZigiJWQiLCZ0KQojZGVmaW5lIFNDTEQodCkgc2NhbmYoIiVsZCIsJnQpCiNkZWZpbmUgU0NMTEQodCkgc2NhbmYoIiVsbGQiLCZ0KQojZGVmaW5lIFNDQyh0KSBzY2FuZigiJWMiLCZ0KQojZGVmaW5lIFNDUyh0KSBzY2FuZigiJXMiLHQpCiNkZWZpbmUgU0NGKHQpIHNjYW5mKCIlZiIsJnQpCiNkZWZpbmUgU0NMRih0KSBzY2FuZigiJWxmIiwmdCkKI2RlZmluZSBNRU0oYSwgYikgbWVtc2V0KGEsIChiKSwgc2l6ZW9mKGEpKQojZGVmaW5lIEZPUihpLCBqLCBrLCBpbikgZm9yIChpbnQgaT1qIDsgaTxrIDsgaSs9aW4pCiNkZWZpbmUgUkZPUihpLCBqLCBrLCBpbikgZm9yIChpbnQgaT1qIDsgaT49ayA7IGktPWluKQojZGVmaW5lIFJFUChpLCBqKSBGT1IoaSwgMCwgaiwgMSkKI2RlZmluZSBSUkVQKGksIGopIFJGT1IoaSwgaiwgMCwgMSkKI2RlZmluZSBhbGwoY29udCkgY29udC5iZWdpbigpLCBjb250LmVuZCgpCiNkZWZpbmUgcmFsbChjb250KSBjb250LmVuZCgpLCBjb250LmJlZ2luKCkKI2RlZmluZSBGT1JFQUNIKGl0LCBsKSBmb3IgKGF1dG8gaXQgPSBsLmJlZ2luKCk7IGl0ICE9IGwuZW5kKCk7IGl0KyspCiNkZWZpbmUgSU4oQSwgQiwgQykgYXNzZXJ0KCBCIDw9IEEgJiYgQSA8PSBDKQojZGVmaW5lIE1QIG1ha2VfcGFpcgojZGVmaW5lIFBCIHB1c2hfYmFjawojZGVmaW5lIElORiAoaW50KTFlOQojZGVmaW5lIEVQUyAxZS05CiNkZWZpbmUgUEkgMy4xNDE1OTI2NTM1ODk3OTMyMzg0NjI2NDMzODMyNzk1CiNkZWZpbmUgTU9EIDEwMDAwMDAwMDcKI2RlZmluZSByZWFkKHR5cGUpIHJlYWRJbnQ8dHlwZT4oKQpjb25zdCBkb3VibGUgcGk9YWNvcygtMS4wKTsKdHlwZWRlZiBwYWlyPGludCwgaW50PiBQSUk7CnR5cGVkZWYgdmVjdG9yPGludD4gVkk7CnR5cGVkZWYgdmVjdG9yPHN0cmluZz4gVlM7CnR5cGVkZWYgdmVjdG9yPFBJST4gVklJOwp0eXBlZGVmIHZlY3RvcjxWST4gVlZJOwp0eXBlZGVmIG1hcDxpbnQsaW50PiBNUElJOwp0eXBlZGVmIHNldDxpbnQ+IFNFVEk7CnR5cGVkZWYgbXVsdGlzZXQ8aW50PiBNU0VUSTsKdHlwZWRlZiBsb25nIGludCBpbnQzMjsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGludCB1aW50MzI7CnR5cGVkZWYgbG9uZyBsb25nIGludCBpbnQ2NDsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgaW50ICB1aW50NjQ7CgptdDE5OTM3IHJuZzMyKGNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKSk7CgovKioqKioqIFRlbXBsYXRlIG9mIHNvbWUgYmFzaWMgb3BlcmF0aW9ucyAqKioqKi8KdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVT4gaW5saW5lIHZvaWQgYW1pbihUICZ4LCBVIHkpIHsgaWYoeSA8IHgpIHggPSB5OyB9CnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IGlubGluZSB2b2lkIGFtYXgoVCAmeCwgVSB5KSB7IGlmKHggPCB5KSB4ID0geTsgfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgpjb25zdCBpbnQgTUFYTiA9IChpbnQpMWU3Owpjb25zdCBpbnQgTE9HTUFYTiA9IDMxOwoKaW50IHplcm9bTUFYTl0sb25lW01BWE5dLGxlYWZWYWx1ZVtNQVhOXTsKaW50IG5vZGVDb3VudCA9IDA7CmludCByb290W01BWE5dLGN1cnJSb290PTA7Cm1hcDxpbnQ2NCxpbnQ+IGlkVG9Ob2RlTnVtYmVyOwptYXA8aW50NjQsaW50PiBpZFRvRW5jcnlwdGlvbjsKbWFwPGludDY0LFZJPiBhZGo7CgppbnQ2NCBtYXhBbnM9MCxtaW5BbnM9MDsKCnZvaWQgcHJpbnRERlMoaW50IGksIGludDY0IHIpOwoKaW50IG5ld05vZGUoaW50IGxlZiwgaW50IHJpZykgewogICAgaW50IHAgPSArK25vZGVDb3VudDsKICAgIHplcm9bcF0gPSBsZWY7CiAgICBvbmVbcF0gPSByaWc7CiAgICByZXR1cm4gcDsKfQoKaW50IG5ld0xlYWYoaW50IHZhbCkgewogICAgaW50IHAgPSArK25vZGVDb3VudDsKICAgIHplcm9bcF09b25lW3BdPTA7CiAgICBsZWFmVmFsdWVbcF0gPSB2YWw7CiAgICByZXR1cm4gcDsKfQoKaW50IGNvdW50Qml0cyhpbnQgbikKewogICAgaW50IGNvdW50ID0gMDsKICAgIHdoaWxlIChuKQogICAgewogICAgICAgIGNvdW50Kys7CiAgICAgICAgbiA+Pj0gMTsKICAgIH0KICAgIHJldHVybiBjb3VudDsKfQoKdm9pZCBtYXhYT1IoaW50IHRyaWVJbmRleCxpbnQgdmFsLGludCB2YWxCaXRJbmRleCxpbnQgYXBwZW5kWmVyb2VzKXsKCiAgICBpZihhcHBlbmRaZXJvZXM+MCl7CiAgICAgICAgaWYob25lW3RyaWVJbmRleF0hPTApeyAvL3dhbnQgdG8gZ28gcmlnaHQKICAgICAgICAgICAgbWF4WE9SKG9uZVt0cmllSW5kZXhdLHZhbCx2YWxCaXRJbmRleCxhcHBlbmRaZXJvZXMtMSk7CiAgICAgICAgICAgIG1heEFucyArPSAoaW50KXBvdygyLHZhbEJpdEluZGV4K2FwcGVuZFplcm9lcy0xKTsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICAgbWF4WE9SKHplcm9bdHJpZUluZGV4XSx2YWwsdmFsQml0SW5kZXgsYXBwZW5kWmVyb2VzLTEpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2V7CgogICAgICAgIGlmKHZhbEJpdEluZGV4PT0wKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGludCBiaXQgPSAoMTw8KHZhbEJpdEluZGV4LTEpKSZ2YWw7CgogICAgICAgIGlmKGJpdD09MCl7Ly9nbyByaWdodAoKICAgICAgICAgICAgaWYob25lW3RyaWVJbmRleF0hPTApeyAvL3dhbnQgdG8gZ28gcmlnaHQKICAgICAgICAgICAgICAgIG1heFhPUihvbmVbdHJpZUluZGV4XSx2YWwsdmFsQml0SW5kZXgtMSxhcHBlbmRaZXJvZXMpOwogICAgICAgICAgICAgICAgbWF4QW5zICs9IChpbnQpcG93KDIsdmFsQml0SW5kZXgtMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgIG1heFhPUih6ZXJvW3RyaWVJbmRleF0sdmFsLHZhbEJpdEluZGV4LTEsYXBwZW5kWmVyb2VzKTsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgZWxzZXsvL2dvIGxlZnQKICAgICAgICAgICAgaWYoemVyb1t0cmllSW5kZXhdIT0wKSB7IC8vd2FudCB0byBnbyBsZWZ0CiAgICAgICAgICAgICAgICBtYXhYT1IoemVyb1t0cmllSW5kZXhdLHZhbCx2YWxCaXRJbmRleC0xLGFwcGVuZFplcm9lcyk7CiAgICAgICAgICAgICAgICBtYXhBbnMgKz0gKGludClwb3coMix2YWxCaXRJbmRleC0xKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgbWF4WE9SKG9uZVt0cmllSW5kZXhdLHZhbCx2YWxCaXRJbmRleC0xLGFwcGVuZFplcm9lcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQoKfQoKdm9pZCBtaW5YT1IoaW50IHRyaWVJbmRleCxpbnQgdmFsLGludCB2YWxCaXRJbmRleCxpbnQgYXBwZW5kWmVyb2VzKXsKCiAgICBpZihhcHBlbmRaZXJvZXM+MCl7CiAgICAgICAgaWYoemVyb1t0cmllSW5kZXhdIT0wKXsgLy93YW50IHRvIGdvIGxlZnQKICAgICAgICAgICAgbWluWE9SKHplcm9bdHJpZUluZGV4XSx2YWwsdmFsQml0SW5kZXgsYXBwZW5kWmVyb2VzLTEpOwogICAgICAgIH0KICAgICAgICBlbHNleyAvL2hhdmUgdG8gZ28gcmlnaHQgbm8gY2hvaWNlIGxlZnQKICAgICAgICAgICAgbWluWE9SKG9uZVt0cmllSW5kZXhdLHZhbCx2YWxCaXRJbmRleCxhcHBlbmRaZXJvZXMtMSk7CiAgICAgICAgICAgIG1pbkFucyArPSAoaW50KXBvdygyLHZhbEJpdEluZGV4K2FwcGVuZFplcm9lcy0xKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlewoKICAgICAgICBpZih2YWxCaXRJbmRleD09MCkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBpbnQgYml0ID0gKDE8PCh2YWxCaXRJbmRleC0xKSkmdmFsOwoKICAgICAgICBpZihiaXQ9PTApey8vZ28gbGVmdAoKICAgICAgICAgICAgaWYoemVyb1t0cmllSW5kZXhdIT0wKXsgLy93YW50IHRvIGdvIGxlZnQKICAgICAgICAgICAgICAgIG1pblhPUih6ZXJvW3RyaWVJbmRleF0sdmFsLHZhbEJpdEluZGV4LTEsYXBwZW5kWmVyb2VzKTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZXsvL2hhdmUgdG8gZ28gcmlnaHQgbm8gY2hvaWNlIGxlZnQKICAgICAgICAgICAgICAgIG1pblhPUihvbmVbdHJpZUluZGV4XSx2YWwsdmFsQml0SW5kZXgtMSxhcHBlbmRaZXJvZXMpOwogICAgICAgICAgICAgICAgbWluQW5zICs9IChpbnQpcG93KDIsdmFsQml0SW5kZXgtMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIGVsc2V7Ly9nbyByaWdodAogICAgICAgICAgICBpZihvbmVbdHJpZUluZGV4XSE9MCkgeyAvL3dhbnQgdG8gZ28gcmlnaHQKICAgICAgICAgICAgICAgIG1pblhPUihvbmVbdHJpZUluZGV4XSx2YWwsdmFsQml0SW5kZXgtMSxhcHBlbmRaZXJvZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2V7Ly9oYXZlIHRvIGdvIGxlZnQgbm8gY2hvaWNlIGxlZnQKICAgICAgICAgICAgICAgIG1pblhPUih6ZXJvW3RyaWVJbmRleF0sdmFsLHZhbEJpdEluZGV4LTEsYXBwZW5kWmVyb2VzKTsKICAgICAgICAgICAgICAgIG1pbkFucyArPSAoaW50KXBvdygyLHZhbEJpdEluZGV4LTEpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCn0KCmludCBpbnNlcnQoaW50IHByZXZQb2ludGVyLGludCB2YWwsaW50IHZhbEJpdEluZGV4LGludCBhcHBlbmRaZXJvZXMpewoKICAgIGlmKGFwcGVuZFplcm9lcz4wKXsKICAgICAgICByZXR1cm4gbmV3Tm9kZShpbnNlcnQoemVyb1twcmV2UG9pbnRlcl0sdmFsLHZhbEJpdEluZGV4LGFwcGVuZFplcm9lcy0xKSxvbmVbcHJldlBvaW50ZXJdKTsKICAgIH0KICAgIGVsc2V7CgogICAgICAgIGlmKHZhbEJpdEluZGV4PT0wKQogICAgICAgICAgICByZXR1cm4gbmV3TGVhZih2YWwpOwoKICAgICAgICBpbnQ2NCBiaXQgPSAoMTw8KHZhbEJpdEluZGV4LTEpKSZ2YWw7CgogICAgICAgIGlmKGJpdD09MCl7Ly9nbyBsZWZ0CiAgICAgICAgICAgIHJldHVybiBuZXdOb2RlKGluc2VydCh6ZXJvW3ByZXZQb2ludGVyXSx2YWwsdmFsQml0SW5kZXgtMSxhcHBlbmRaZXJvZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVbcHJldlBvaW50ZXJdKTsKICAgICAgICB9CiAgICAgICAgZWxzZXsvL2dvIHJpZ2h0CiAgICAgICAgICAgIHJldHVybiBuZXdOb2RlKHplcm9bcHJldlBvaW50ZXJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnQob25lW3ByZXZQb2ludGVyXSx2YWwsdmFsQml0SW5kZXgtMSxhcHBlbmRaZXJvZXMpKTsKICAgICAgICB9CgogICAgfQoKfQoKCgp2b2lkIHByaW50VHJpZShpbnQgaW5kZXgpewoKICAgIGNvdXQ8PCJub2RlIG51bWJlcjogIjw8aW5kZXg8PCJcbiI7CgogICAgaWYoemVyb1tpbmRleF09PTAgJiYgb25lW2luZGV4XT09MCkgewogICAgICAgIGNvdXQ8PCJsZWFmIGhpdFxuIjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY291dDw8ImdvaW5nIGxlZnRcbiI7CiAgICBwcmludFRyaWUoemVyb1tpbmRleF0pOwogICAgY291dDw8ImdvaW5nIHJpZ2h0XG4iOwogICAgcHJpbnRUcmllKG9uZVtpbmRleF0pOwoKfQoKdm9pZCBkZnMoaW50IHAsaW50IHUpewoKICAgIGludCB2OwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGpbdV0uc2l6ZSgpOyArK2kpIHsKICAgICAgICB2ID0gYWRqW3VdW2ldOwogICAgICAgIGlmKHYhPXApIHsKICAgICAgICAgICAgaW50IGJpdHNDb3VudCA9IGNvdW50Qml0cyhpZFRvRW5jcnlwdGlvblt2XSk7CiAgICAgICAgICAgIC8vY291dDw8ImN1cnJlbnQgTm9kZTogIjw8dTw8IiAsIHBhcmVudCBub2RlIG51bWJlciA9ICI8PGlkVG9Ob2RlTnVtYmVyW3VdPDwiXG4iOwogICAgICAgICAgICBpbnQgdCA9IGluc2VydChpZFRvTm9kZU51bWJlclt1XSxpZFRvRW5jcnlwdGlvblt2XSxiaXRzQ291bnQsTE9HTUFYTi1iaXRzQ291bnQpOwogICAgICAgICAgICBpZFRvTm9kZU51bWJlclt2XT10OwogICAgICAgICAgICBkZnModSwgdik7CiAgICAgICAgfQogICAgfQoKfQoKCnZvaWQgcHJpbnRERlMoaW50IHAsIGludDY0IHUpIHsKCiAgICBjb3V0PDwiTk9ERSA6ICI8PHU8PCJcbiI7CiAgICBwcmludFRyaWUoaWRUb05vZGVOdW1iZXJbdV0pOwogICAgaW50IHY7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkalt1XS5zaXplKCk7ICsraSkgewogICAgICAgIHYgPSBhZGpbdV1baV07CiAgICAgICAgaWYodiE9cCkgewogICAgICAgICAgICBwcmludERGUyh1LCB2KTsKICAgICAgICB9CiAgICB9Cn0KCgppbnQgbWFpbigpCnsKCiAgICBNRU0oemVybywwKTsKICAgIE1FTShvbmUsMCk7CiAgICBNRU0ocm9vdCwwKTsKCiNpZm5kZWYgT05MSU5FX0pVREdFCiAgICBmcmVvcGVuKCIvVXNlcnMvYmhhZ2lyYXRoaS9Eb2N1bWVudHMvQ0xpb25Qcm9qZWN0cy9jb2RlZm9yY2VzL2RlYnVnL2lucHV0LnR4dCIsICJyIiwgc3RkaW4pOwogICAgZnJlb3BlbigiL1VzZXJzL2JoYWdpcmF0aGkvRG9jdW1lbnRzL0NMaW9uUHJvamVjdHMvY29kZWZvcmNlcy9kZWJ1Zy9vdXRwdXQudHh0IiwgInciLCBzdGRvdXQpOwojZW5kaWYKCiAgICBpbnQgbixxOwogICAgY2luPj5uPj5xOwoKICAgIGludDY0IHIsa2V5OwogICAgY2luPj5yPj5rZXk7CgogICAgaWRUb0VuY3J5cHRpb25bcl09a2V5OwoKICAgIGludDY0IHUsdixrOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPG4tMSA7ICsraSkgewoKICAgICAgICBjaW4+PnU+PnY+Pms7CgogICAgICAgIFZJIGN1cnJOZWlnaGJvdXJzID0gYWRqW3ZdOwogICAgICAgIGN1cnJOZWlnaGJvdXJzLnB1c2hfYmFjayh1KTsKICAgICAgICBhZGpbdl0gPSBjdXJyTmVpZ2hib3VyczsKCiAgICAgICAgaWRUb0VuY3J5cHRpb25bdV09azsKICAgIH0KCi8vICAgIGZvciAoYXV0byBpdCA9IGFkai5iZWdpbigpOyBpdCAhPSBhZGouZW5kKCkgOyBpdCsrKSB7Ci8vCi8vICAgICAgICBjb3V0PDwiIE5PREU6ICI8PGl0LT5maXJzdDw8IlxuIjsKLy8gICAgICAgIFZJIGN1cnIgPSBpdC0+c2Vjb25kOwovLyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPGN1cnIuc2l6ZSgpIDsgKytpKSB7Ci8vICAgICAgICAgICAgY291dDw8Y3VycltpXTw8IiAiOwovLyAgICAgICAgfQovLyAgICAgICAgY291dDw8IlxuIjsKLy8KLy8gICAgfQoKICAgIGlkVG9Ob2RlTnVtYmVyWzBdPTA7CgogICAgaW50IGJpdHNDb3VudCA9IGNvdW50Qml0cyhrZXkpOwogICAgaW50IHQgPSBpbnNlcnQoMCxrZXksYml0c0NvdW50LExPR01BWE4tYml0c0NvdW50KTsKICAgIGlkVG9Ob2RlTnVtYmVyW3JdID0gdDsKCiAgICBkZnMoMCxyKTsKCiAgICAvL3ByaW50REZTKDAscik7CgogICAgaW50IGxhc3RfYW5zd2VyID0gMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcTsgaSsrKQogICAgewogICAgICAgIGNpbiA+PiB0OwoKICAgICAgICAvLyBmaW5kIHJlYWwgdmFsdWUgb2YgdAogICAgICAgIHQgXj0gbGFzdF9hbnN3ZXI7CgogICAgICAgIGlmICh0ID09IDApCiAgICAgICAgewogICAgICAgICAgICBjaW4gPj4gdiA+PiB1ID4+IGs7CgogICAgICAgICAgICAvLyBmaW5kIHJlYWwgdmFsdWVzIGZvciB1LCB2LCBhbmQgawogICAgICAgICAgICB1IF49IGxhc3RfYW5zd2VyOwogICAgICAgICAgICB2IF49IGxhc3RfYW5zd2VyOwogICAgICAgICAgICBrIF49IGxhc3RfYW5zd2VyOwoKICAgICAgICAgICAgLy9pbnNlcnQKICAgICAgICAgICAgYWRqW3ZdLnB1c2hfYmFjayh1KTsKICAgICAgICAgICAgYml0c0NvdW50ID0gY291bnRCaXRzKGspOwogICAgICAgICAgICBpZFRvRW5jcnlwdGlvblt1XT1rOwogICAgICAgICAgICB0ID0gaW5zZXJ0KGlkVG9Ob2RlTnVtYmVyW3ZdLGssYml0c0NvdW50LExPR01BWE4tYml0c0NvdW50KTsKICAgICAgICAgICAgaWRUb05vZGVOdW1iZXJbdV0gPSB0OwoKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgY2luID4+IHYgPj4gazsKCiAgICAgICAgICAgIC8vIGZpbmQgcmVhbCB2YWx1ZXMgZm9yIHYsIGFuZCBrCiAgICAgICAgICAgIHYgXj0gbGFzdF9hbnN3ZXI7CiAgICAgICAgICAgIGsgXj0gbGFzdF9hbnN3ZXI7CgoKICAgICAgICAgICAgLy9jb3V0PDwiTk9ERSBOVU1CRVIgUVVFUlk6ICI8PGlkVG9Ob2RlTnVtYmVyW3ZdPDwiXG4iOwoKICAgICAgICAgICAgLy8gY29tcHV0ZSB0aGUgcmVxdWVzdGVkIHZhbHVlcwogICAgICAgICAgICBiaXRzQ291bnQgPSBjb3VudEJpdHMoayk7CiAgICAgICAgICAgIG1pblhPUihpZFRvTm9kZU51bWJlclt2XSxrLGJpdHNDb3VudCxMT0dNQVhOLWJpdHNDb3VudCk7CiAgICAgICAgICAgIGludCBtaW5fYW5zd2VyID0gbWluQW5zOwogICAgICAgICAgICBtaW5BbnMgPSAwOwogICAgICAgICAgICBtYXhYT1IoaWRUb05vZGVOdW1iZXJbdl0sayxiaXRzQ291bnQsTE9HTUFYTi1iaXRzQ291bnQpOwogICAgICAgICAgICBpbnQgbWF4X2Fuc3dlciA9IG1heEFuczsKICAgICAgICAgICAgbWF4QW5zID0wOwoKCiAgICAgICAgICAgIGNvdXQ8PG1pbl9hbnN3ZXI8PCIgIjw8bWF4X2Fuc3dlcjw8IlxuIjsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBsYXN0X2Fuc3dlcgogICAgICAgICAgICBsYXN0X2Fuc3dlciA9IG1pbl9hbnN3ZXIgXiBtYXhfYW5zd2VyOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMDsKfQoK