#include"planttree.h"
#include<vector>
#include<string>
#include<iostream>
#define cir(i,a,b) for(int i=a;i<b;++i)
using namespace std;
using ulint=unsigned __int128;
namespace encoderf{
vector<vector<ulint>> f,vis;
auto rank(int u,int c)->ulint{
if(u<0||c<0) return (ulint)(0);
auto&fx=f[u][c];
if(!u) return fx=(c==1);
if(vis[u][c]) return fx;
vis[u][c]=true;
return fx=rank(u-1,c+1)+rank(u-1,c-1);
}
auto getstrrk(string::iterator it,string::iterator ed,int prec=0){
if(it==ed) return (ulint)(0);
if(*it=='(') return getstrrk(next(it),ed,prec+1);
//clog<<string(it,ed)<<':'<<(int)(rank(ed-it-2,prec+1))<<' '<<prec<<' '<<ed-it-1<<' '<<(int)(rank(3,2))<<'\n';
return getstrrk(next(it),ed,prec-1)+rank(ed-it-2,prec+1);
}
auto init(){
f.resize(177,vector<ulint>(177));
vis.resize(177,vector<ulint>(177));
}
}
class tree{
private:
vector<vector<int>> gr;
auto dfs(int u,string&s,int f=0)->void{
if(f) s+='(';
for(auto&i:gr[u]) if(i!=f) dfs(i,s,u);
if(f) s+=')';
}
public:
auto link(int u,int v){
gr[u].push_back(v);
gr[v].push_back(u);
}
auto getstr(){
string s;
return dfs(1,s),s;
}
tree(int _n):gr(_n+1){}
};
unsigned __int128 encoder(int n, const int*p){
tree tr(n);encoderf::init();
cir(i,2,n+1) tr.link(i,p[i]);
auto str=tr.getstr();
return encoderf::getstrrk(str.begin(),str.end());
}
namespace decoderf{
vector<vector<ulint>> f,vis;
auto rank(int u,int c)->ulint{
if(u<0||c<0) return (ulint)(0);
auto&fx=f[u][c];
if(!u) return fx=(c==1);
if(vis[u][c]) return fx;
vis[u][c]=true;
return fx=rank(u-1,c+1)+rank(u-1,c-1);
}
auto getrkstr(int u,int c,ulint rk,string&s){
if(u==-1) return;
const auto rkl=rank(u-1,c+1);
if(rk<rkl) return s+='(',getrkstr(u-1,c+1,rk,s);
return s+=')',getrkstr(u-1,c-1,rk-rkl,s);
}
auto rebuild(string::iterator&it,int&c,int*p,int f=0)->void{
auto u=++c;
p[u]=f;
while(*(++it)=='('){
rebuild(it,c,p,u);
}
}
auto init(){
f.resize(177,vector<ulint>(177));
vis.resize(177,vector<ulint>(177));
}
}
void decoder(int n, unsigned __int128 rk, int*p){
decoderf::init();
string sans="(";
decoderf::getrkstr(n*2-3,0,rk,sans);
sans+=')';
auto c=0;auto it=sans.begin();
decoderf::rebuild(it,c,p);
}
#undef cir