#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll NINF = (ll)-4e18;
const int MOD = 1'000'000'007;
struct VC { ll v; int c; VC(ll V=NINF,int C=0):v(V),c(C){} };
inline VC mx(const VC&a,const VC&b){ if(a.v>b.v) return a; if(b.v>a.v) return b; return VC(a.v,(a.c+b.c)%MOD); }
inline VC add(const VC&a,const VC&b){ if(!a.c||!b.c) return VC(NINF,0); return VC(a.v+b.v,(int)(1LL*a.c*b.c%MOD)); }
struct M {
VC a[2][2];
M(){ a[0][0]=a[0][1]=a[1][0]=a[1][1]=VC(NINF,0); }
static M I(){ M x; x.a[0][0]=VC(0,1); x.a[1][1]=VC(0,1); return x; }
};
M mulm(const M&A,const M&B){
M C;
for(int i=0;i<2;i++) for(int j=0;j<2;j++){
VC t(NINF,0);
for(int k=0;k<2;k++) t=mx(t,add(A.a[i][k],B.a[k][j]));
C.a[i][j]=t;
}
return C;
}
M mor(const M&A,const M&B){
M C;
for(int i=0;i<2;i++) for(int j=0;j<2;j++) C.a[i][j]=mx(A.a[i][j],B.a[i][j]);
return C;
}
M mpow(M b, long long e){
M r=M::I();
while(e){ if(e&1) r=mulm(r,b); b=mulm(b,b); e>>=1; }
return r;
}
struct V2 { VC x[2]; V2(){ x[0]=x[1]=VC(NINF,0); } static V2 sN(int er){ V2 v; v.x[0]=VC(0,1); v.x[1]=VC(-er,1); return v; } static V2 sR(int er,int ex){ V2 v; v.x[0]=VC(0,1); v.x[1]=VC(-er-ex,1); return v; } };
V2 mulvm(const V2&v,const M&A){
V2 y;
for(int j=0;j<2;j++){ VC t(NINF,0); for(int k=0;k<2;k++) t=mx(t,add(v.x[k],A.a[k][j])); y.x[j]=t; }
return y;
}
VC fin(const V2&v,int el){ return mx(add(v.x[0],VC(0,1)), add(v.x[1],VC(1-el,1))); }
int n; long long d;
vector<vector<int>> g;
vector<int> par; vector<vector<int>> ch; vector<int> ord;
vector<int> A,B,S,UA,UB; vector<char> UH,ess;
void build(int s=0){
par.assign(n,-1); ch.assign(n,{}); ord.clear();
vector<int> st={s}; par[s]=-2;
while(!st.empty()){ int u=st.back(); st.pop_back(); ord.push_back(u); for(int v:g[u]) if(par[v]==-1){ par[v]=u; st.push_back(v);} }
par[s]=-1; for(int v=0;v<n;v++) if(par[v]!=-1) ch[par[v]].push_back(v);
}
void down(){
A.assign(n,0); B.assign(n,0); S.assign(n,0);
for(int i=n-1;i>=0;i--){
int u=ord[i], sum=0, best=INT_MIN/4;
for(int v:ch[u]){ sum+=A[v]; best=max(best, B[v]-A[v]); }
S[u]=sum; B[u]=sum; A[u]=(best<=INT_MIN/8?sum:max(sum,sum+1+best));
}
}
void up(){
UA.assign(n,0); UB.assign(n,0); UH.assign(n,0); UH[0]=0;
vector<vector<int>> pre(n),suf(n);
for(int u:ord){
int k=ch[u].size();
pre[u].assign(k+1,INT_MIN/4);
for(int i=0;i<k;i++){ int v=ch[u][i]; pre[u][i+1]=max(pre[u][i], B[v]-A[v]); }
suf[u].assign(k+1,INT_MIN/4);
for(int i=k-1;i>=0;i--){ int v=ch[u][i]; suf[u][i]=max(suf[u][i+1], B[v]-A[v]); }
}
for(int u:ord){
int k=ch[u].size();
for(int i=0;i<k;i++){
int v=ch[u][i];
int Sex=UA[u]+(S[u]-A[v]);
int best=max(pre[u][i],suf[u][i+1]);
if(UH[u]) best=max(best,UB[u]-UA[u]);
UB[v]=Sex; UA[v]=(best<=INT_MIN/8?Sex:max(Sex,Sex+1+best)); UH[v]=1;
}
}
}
void compE(){
ess.assign(n,0);
int M=A[0];
for(int u=0;u<n;u++){ int rem=UA[u]+S[u]; ess[u]=(M>rem); }
}
vector<char> inD,inA; vector<int> cid, Dc, Ac; vector<char> tight;
void GE(){
inD.assign(n,0); for(int u=0;u<n;u++) inD[u]=!ess[u];
inA.assign(n,0); for(int u=0;u<n;u++) if(inD[u]) for(int v:g[u]) inA[v]=1;
cid.assign(n,-1); Dc.clear(); Ac.clear();
vector<int> vis(n,0); int id=0;
for(int u=0;u<n;u++){
if(vis[u] || !(inD[u]||inA[u])) continue;
queue<int> q; q.push(u); vis[u]=1; int dcnt=0, acnt=0; vector<int> nodes;
while(!q.empty()){
int x=q.front(); q.pop(); nodes.push_back(x);
if(inD[x]) dcnt++; else if(inA[x]) acnt++;
for(int y:g[x]){
if(!((inD[x]&&inA[y])||(inA[x]&&inD[y]))) continue;
if(!vis[y]){ vis[y]=1; q.push(y); }
}
}
for(int x:nodes) if(inD[x]) cid[x]=id;
Dc.push_back(dcnt); Ac.push_back(acnt); id++;
}
tight.assign(id,0);
for(int i=0;i<id;i++) tight[i]=(Dc[i]-Ac[i]==1);
}
struct P { long long ee_same=0,ee_diff=0,enL=0,enR=0,nn_same=0,nn_tight=0,nn_other=0; };
P cntPairs(){
long long E=0, NE=0; for(int u=0;u<n;u++) (ess[u]?E:NE)++;
long long T=0,S2=0; for(size_t i=0;i<Dc.size();i++) if(tight[i]){ T+=Dc[i]; S2+=1LL*Dc[i]*Dc[i]; }
P p;
p.ee_same = E;
p.ee_diff = E*E - E;
p.enL = E*NE;
p.enR = NE*E;
p.nn_same = NE;
p.nn_tight = S2 - T;
p.nn_other = NE*NE - p.nn_same - p.nn_tight;
return p;
}
M mat(int eL,int eR,int ex,int forbd){
M T;
T.a[0][0]=VC(0,1);
T.a[0][1]=VC(-eR,1);
T.a[1][0]=VC(1-eL,1);
if(forbd) T.a[1][1]=VC(NINF,0);
else T.a[1][1]=VC(1-eL-eR-ex,1);
return T;
}
M agg1(const vector<pair<M,ll>>& lst){
M R;
for(auto &t:lst){
M X=t.first; ll cnt=t.second%MOD;
if(!cnt) continue;
for(int i=0;i<2;i++) for(int j=0;j<2;j++){ if(X.a[i][j].c) X.a[i][j].c=(int)cnt; }
R=mor(R,X);
}
return R;
}
struct EC { int r[2]; int exr; int l[2]; };
EC ends(int s){
int E=0,NE=0; for(int u=0;u<n;u++) (ess[u]?E:NE)++;
EC e{}; e.r[1]=E%MOD; e.r[0]=NE%MOD; e.l[1]=E%MOD; e.l[0]=NE%MOD;
if(ess[s]) e.exr=0;
else{
int id=cid[s];
if(id>=0 && tight[id]) e.exr = Dc[id]%MOD;
else e.exr=0;
}
return e;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>d;
g.assign(n,{});
for(int i=0;i<n-1;i++){ int u,v; cin>>u>>v; --u;--v; g[u].push_back(v); g[v].push_back(u); }
build(0); down(); up(); compE(); GE();
P p = cntPairs();
vector<pair<M,ll>> lst;
lst.push_back({mat(1,1,0,1), p.ee_same});
lst.push_back({mat(1,1,0,0), p.ee_diff});
lst.push_back({mat(1,0,0,0), p.enL});
lst.push_back({mat(0,1,0,0), p.enR});
lst.push_back({mat(0,0,0,1), p.nn_same});
lst.push_back({mat(0,0,1,0), p.nn_tight});
lst.push_back({mat(0,0,0,0), p.nn_other});
M step = agg1(lst);
M mid = (d>=2? mpow(step,d-1): M::I());
EC e = ends(0);
ll ans = 0;
for(int er=0;er<=1;er++){
V2 vN = V2::sN(er);
V2 vR0 = V2::sR(er,0);
V2 vR1 = V2::sR(er,1);
V2 tN = mulvm(vN,mid), tR0 = mulvm(vR0,mid), tR1 = mulvm(vR1,mid);
for(int el=0;el<=1;el++){
VC VN = fin(tN,el), VR0 = fin(tR0,el), VR1 = fin(tR1,el);
if(ess[0]){ if(VR0.c) VR0.v-=1; if(VR1.c) VR1.v-=1; }
int cntR = e.r[er], cntRe = (er==0? e.exr:0), cntL = e.l[el];
if(VN.v>VR0.v){ ll add = 1LL*((cntR - cntRe + MOD)%MOD)*cntL%MOD; add = add*VN.c%MOD; ans=(ans+add)%MOD; }
if(cntRe && VN.v>VR1.v){ ll add = 1LL*cntRe*cntL%MOD; add = add*VN.c%MOD; ans=(ans+add)%MOD; }
}
}
cout<<ans%MOD<<"\n";
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnVzaW5nIGxsID0gbG9uZyBsb25nOwpjb25zdCBsbCBOSU5GID0gKGxsKS00ZTE4Owpjb25zdCBpbnQgTU9EID0gMScwMDAnMDAwJzAwNzsKCnN0cnVjdCBWQyB7IGxsIHY7IGludCBjOyBWQyhsbCBWPU5JTkYsaW50IEM9MCk6dihWKSxjKEMpe30gfTsKaW5saW5lIFZDIG14KGNvbnN0IFZDJmEsY29uc3QgVkMmYil7IGlmKGEudj5iLnYpIHJldHVybiBhOyBpZihiLnY+YS52KSByZXR1cm4gYjsgcmV0dXJuIFZDKGEudiwoYS5jK2IuYyklTU9EKTsgfQppbmxpbmUgVkMgYWRkKGNvbnN0IFZDJmEsY29uc3QgVkMmYil7IGlmKCFhLmN8fCFiLmMpIHJldHVybiBWQyhOSU5GLDApOyByZXR1cm4gVkMoYS52K2IudiwoaW50KSgxTEwqYS5jKmIuYyVNT0QpKTsgfQoKc3RydWN0IE0gewogIFZDIGFbMl1bMl07CiAgTSgpeyBhWzBdWzBdPWFbMF1bMV09YVsxXVswXT1hWzFdWzFdPVZDKE5JTkYsMCk7IH0KICBzdGF0aWMgTSBJKCl7IE0geDsgeC5hWzBdWzBdPVZDKDAsMSk7IHguYVsxXVsxXT1WQygwLDEpOyByZXR1cm4geDsgfQp9OwpNIG11bG0oY29uc3QgTSZBLGNvbnN0IE0mQil7CiAgTSBDOwogIGZvcihpbnQgaT0wO2k8MjtpKyspIGZvcihpbnQgaj0wO2o8MjtqKyspewogICAgVkMgdChOSU5GLDApOwogICAgZm9yKGludCBrPTA7azwyO2srKykgdD1teCh0LGFkZChBLmFbaV1ba10sQi5hW2tdW2pdKSk7CiAgICBDLmFbaV1bal09dDsKICB9CiAgcmV0dXJuIEM7Cn0KTSBtb3IoY29uc3QgTSZBLGNvbnN0IE0mQil7CiAgTSBDOwogIGZvcihpbnQgaT0wO2k8MjtpKyspIGZvcihpbnQgaj0wO2o8MjtqKyspIEMuYVtpXVtqXT1teChBLmFbaV1bal0sQi5hW2ldW2pdKTsKICByZXR1cm4gQzsKfQpNIG1wb3coTSBiLCBsb25nIGxvbmcgZSl7CiAgTSByPU06OkkoKTsKICB3aGlsZShlKXsgaWYoZSYxKSByPW11bG0ocixiKTsgYj1tdWxtKGIsYik7IGU+Pj0xOyB9CiAgcmV0dXJuIHI7Cn0Kc3RydWN0IFYyIHsgVkMgeFsyXTsgVjIoKXsgeFswXT14WzFdPVZDKE5JTkYsMCk7IH0gc3RhdGljIFYyIHNOKGludCBlcil7IFYyIHY7IHYueFswXT1WQygwLDEpOyB2LnhbMV09VkMoLWVyLDEpOyByZXR1cm4gdjsgfSBzdGF0aWMgVjIgc1IoaW50IGVyLGludCBleCl7IFYyIHY7IHYueFswXT1WQygwLDEpOyB2LnhbMV09VkMoLWVyLWV4LDEpOyByZXR1cm4gdjsgfSB9OwpWMiBtdWx2bShjb25zdCBWMiZ2LGNvbnN0IE0mQSl7CiAgVjIgeTsKICBmb3IoaW50IGo9MDtqPDI7aisrKXsgVkMgdChOSU5GLDApOyBmb3IoaW50IGs9MDtrPDI7aysrKSB0PW14KHQsYWRkKHYueFtrXSxBLmFba11bal0pKTsgeS54W2pdPXQ7IH0KICByZXR1cm4geTsKfQpWQyBmaW4oY29uc3QgVjImdixpbnQgZWwpeyByZXR1cm4gbXgoYWRkKHYueFswXSxWQygwLDEpKSwgYWRkKHYueFsxXSxWQygxLWVsLDEpKSk7IH0KCmludCBuOyBsb25nIGxvbmcgZDsKdmVjdG9yPHZlY3RvcjxpbnQ+PiBnOwp2ZWN0b3I8aW50PiBwYXI7IHZlY3Rvcjx2ZWN0b3I8aW50Pj4gY2g7IHZlY3RvcjxpbnQ+IG9yZDsKdmVjdG9yPGludD4gQSxCLFMsVUEsVUI7IHZlY3RvcjxjaGFyPiBVSCxlc3M7Cgp2b2lkIGJ1aWxkKGludCBzPTApewogIHBhci5hc3NpZ24obiwtMSk7IGNoLmFzc2lnbihuLHt9KTsgb3JkLmNsZWFyKCk7CiAgdmVjdG9yPGludD4gc3Q9e3N9OyBwYXJbc109LTI7CiAgd2hpbGUoIXN0LmVtcHR5KCkpeyBpbnQgdT1zdC5iYWNrKCk7IHN0LnBvcF9iYWNrKCk7IG9yZC5wdXNoX2JhY2sodSk7IGZvcihpbnQgdjpnW3VdKSBpZihwYXJbdl09PS0xKXsgcGFyW3ZdPXU7IHN0LnB1c2hfYmFjayh2KTt9IH0KICBwYXJbc109LTE7IGZvcihpbnQgdj0wO3Y8bjt2KyspIGlmKHBhclt2XSE9LTEpIGNoW3Bhclt2XV0ucHVzaF9iYWNrKHYpOwp9CnZvaWQgZG93bigpewogIEEuYXNzaWduKG4sMCk7IEIuYXNzaWduKG4sMCk7IFMuYXNzaWduKG4sMCk7CiAgZm9yKGludCBpPW4tMTtpPj0wO2ktLSl7CiAgICBpbnQgdT1vcmRbaV0sIHN1bT0wLCBiZXN0PUlOVF9NSU4vNDsKICAgIGZvcihpbnQgdjpjaFt1XSl7IHN1bSs9QVt2XTsgYmVzdD1tYXgoYmVzdCwgQlt2XS1BW3ZdKTsgfQogICAgU1t1XT1zdW07IEJbdV09c3VtOyBBW3VdPShiZXN0PD1JTlRfTUlOLzg/c3VtOm1heChzdW0sc3VtKzErYmVzdCkpOwogIH0KfQp2b2lkIHVwKCl7CiAgVUEuYXNzaWduKG4sMCk7IFVCLmFzc2lnbihuLDApOyBVSC5hc3NpZ24obiwwKTsgVUhbMF09MDsKICB2ZWN0b3I8dmVjdG9yPGludD4+IHByZShuKSxzdWYobik7CiAgZm9yKGludCB1Om9yZCl7CiAgICBpbnQgaz1jaFt1XS5zaXplKCk7CiAgICBwcmVbdV0uYXNzaWduKGsrMSxJTlRfTUlOLzQpOwogICAgZm9yKGludCBpPTA7aTxrO2krKyl7IGludCB2PWNoW3VdW2ldOyBwcmVbdV1baSsxXT1tYXgocHJlW3VdW2ldLCBCW3ZdLUFbdl0pOyB9CiAgICBzdWZbdV0uYXNzaWduKGsrMSxJTlRfTUlOLzQpOwogICAgZm9yKGludCBpPWstMTtpPj0wO2ktLSl7IGludCB2PWNoW3VdW2ldOyBzdWZbdV1baV09bWF4KHN1Zlt1XVtpKzFdLCBCW3ZdLUFbdl0pOyB9CiAgfQogIGZvcihpbnQgdTpvcmQpewogICAgaW50IGs9Y2hbdV0uc2l6ZSgpOwogICAgZm9yKGludCBpPTA7aTxrO2krKyl7CiAgICAgIGludCB2PWNoW3VdW2ldOwogICAgICBpbnQgU2V4PVVBW3VdKyhTW3VdLUFbdl0pOwogICAgICBpbnQgYmVzdD1tYXgocHJlW3VdW2ldLHN1Zlt1XVtpKzFdKTsKICAgICAgaWYoVUhbdV0pIGJlc3Q9bWF4KGJlc3QsVUJbdV0tVUFbdV0pOwogICAgICBVQlt2XT1TZXg7IFVBW3ZdPShiZXN0PD1JTlRfTUlOLzg/U2V4Om1heChTZXgsU2V4KzErYmVzdCkpOyBVSFt2XT0xOwogICAgfQogIH0KfQp2b2lkIGNvbXBFKCl7CiAgZXNzLmFzc2lnbihuLDApOwogIGludCBNPUFbMF07CiAgZm9yKGludCB1PTA7dTxuO3UrKyl7IGludCByZW09VUFbdV0rU1t1XTsgZXNzW3VdPShNPnJlbSk7IH0KfQoKdmVjdG9yPGNoYXI+IGluRCxpbkE7IHZlY3RvcjxpbnQ+IGNpZCwgRGMsIEFjOyB2ZWN0b3I8Y2hhcj4gdGlnaHQ7CnZvaWQgR0UoKXsKICBpbkQuYXNzaWduKG4sMCk7IGZvcihpbnQgdT0wO3U8bjt1KyspIGluRFt1XT0hZXNzW3VdOwogIGluQS5hc3NpZ24obiwwKTsgZm9yKGludCB1PTA7dTxuO3UrKykgaWYoaW5EW3VdKSBmb3IoaW50IHY6Z1t1XSkgaW5BW3ZdPTE7CiAgY2lkLmFzc2lnbihuLC0xKTsgRGMuY2xlYXIoKTsgQWMuY2xlYXIoKTsKICB2ZWN0b3I8aW50PiB2aXMobiwwKTsgaW50IGlkPTA7CiAgZm9yKGludCB1PTA7dTxuO3UrKyl7CiAgICBpZih2aXNbdV0gfHwgIShpbkRbdV18fGluQVt1XSkpIGNvbnRpbnVlOwogICAgcXVldWU8aW50PiBxOyBxLnB1c2godSk7IHZpc1t1XT0xOyBpbnQgZGNudD0wLCBhY250PTA7IHZlY3RvcjxpbnQ+IG5vZGVzOwogICAgd2hpbGUoIXEuZW1wdHkoKSl7CiAgICAgIGludCB4PXEuZnJvbnQoKTsgcS5wb3AoKTsgbm9kZXMucHVzaF9iYWNrKHgpOwogICAgICBpZihpbkRbeF0pIGRjbnQrKzsgZWxzZSBpZihpbkFbeF0pIGFjbnQrKzsKICAgICAgZm9yKGludCB5OmdbeF0pewogICAgICAgIGlmKCEoKGluRFt4XSYmaW5BW3ldKXx8KGluQVt4XSYmaW5EW3ldKSkpIGNvbnRpbnVlOwogICAgICAgIGlmKCF2aXNbeV0peyB2aXNbeV09MTsgcS5wdXNoKHkpOyB9CiAgICAgIH0KICAgIH0KICAgIGZvcihpbnQgeDpub2RlcykgaWYoaW5EW3hdKSBjaWRbeF09aWQ7CiAgICBEYy5wdXNoX2JhY2soZGNudCk7IEFjLnB1c2hfYmFjayhhY250KTsgaWQrKzsKICB9CiAgdGlnaHQuYXNzaWduKGlkLDApOwogIGZvcihpbnQgaT0wO2k8aWQ7aSsrKSB0aWdodFtpXT0oRGNbaV0tQWNbaV09PTEpOwp9CgpzdHJ1Y3QgUCB7IGxvbmcgbG9uZyBlZV9zYW1lPTAsZWVfZGlmZj0wLGVuTD0wLGVuUj0wLG5uX3NhbWU9MCxubl90aWdodD0wLG5uX290aGVyPTA7IH07ClAgY250UGFpcnMoKXsKICBsb25nIGxvbmcgRT0wLCBORT0wOyBmb3IoaW50IHU9MDt1PG47dSsrKSAoZXNzW3VdP0U6TkUpKys7CiAgbG9uZyBsb25nIFQ9MCxTMj0wOyBmb3Ioc2l6ZV90IGk9MDtpPERjLnNpemUoKTtpKyspIGlmKHRpZ2h0W2ldKXsgVCs9RGNbaV07IFMyKz0xTEwqRGNbaV0qRGNbaV07IH0KICBQIHA7CiAgcC5lZV9zYW1lID0gRTsKICBwLmVlX2RpZmYgPSBFKkUgLSBFOwogIHAuZW5MID0gRSpORTsKICBwLmVuUiA9IE5FKkU7CiAgcC5ubl9zYW1lID0gTkU7CiAgcC5ubl90aWdodCA9IFMyIC0gVDsKICBwLm5uX290aGVyID0gTkUqTkUgLSBwLm5uX3NhbWUgLSBwLm5uX3RpZ2h0OwogIHJldHVybiBwOwp9CgpNIG1hdChpbnQgZUwsaW50IGVSLGludCBleCxpbnQgZm9yYmQpewogIE0gVDsKICBULmFbMF1bMF09VkMoMCwxKTsKICBULmFbMF1bMV09VkMoLWVSLDEpOwogIFQuYVsxXVswXT1WQygxLWVMLDEpOwogIGlmKGZvcmJkKSBULmFbMV1bMV09VkMoTklORiwwKTsKICBlbHNlIFQuYVsxXVsxXT1WQygxLWVMLWVSLWV4LDEpOwogIHJldHVybiBUOwp9Ck0gYWdnMShjb25zdCB2ZWN0b3I8cGFpcjxNLGxsPj4mIGxzdCl7CiAgTSBSOwogIGZvcihhdXRvICZ0OmxzdCl7CiAgICBNIFg9dC5maXJzdDsgbGwgY250PXQuc2Vjb25kJU1PRDsKICAgIGlmKCFjbnQpIGNvbnRpbnVlOwogICAgZm9yKGludCBpPTA7aTwyO2krKykgZm9yKGludCBqPTA7ajwyO2orKyl7IGlmKFguYVtpXVtqXS5jKSBYLmFbaV1bal0uYz0oaW50KWNudDsgfQogICAgUj1tb3IoUixYKTsKICB9CiAgcmV0dXJuIFI7Cn0KCnN0cnVjdCBFQyB7IGludCByWzJdOyBpbnQgZXhyOyBpbnQgbFsyXTsgfTsKRUMgZW5kcyhpbnQgcyl7CiAgaW50IEU9MCxORT0wOyBmb3IoaW50IHU9MDt1PG47dSsrKSAoZXNzW3VdP0U6TkUpKys7CiAgRUMgZXt9OyBlLnJbMV09RSVNT0Q7IGUuclswXT1ORSVNT0Q7IGUubFsxXT1FJU1PRDsgZS5sWzBdPU5FJU1PRDsKICBpZihlc3Nbc10pIGUuZXhyPTA7CiAgZWxzZXsKICAgIGludCBpZD1jaWRbc107CiAgICBpZihpZD49MCAmJiB0aWdodFtpZF0pIGUuZXhyID0gRGNbaWRdJU1PRDsKICAgIGVsc2UgZS5leHI9MDsKICB9CiAgcmV0dXJuIGU7Cn0KCmludCBtYWluKCl7CiAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwogIGNpbi50aWUobnVsbHB0cik7CiAgY2luPj5uPj5kOwogIGcuYXNzaWduKG4se30pOwogIGZvcihpbnQgaT0wO2k8bi0xO2krKyl7IGludCB1LHY7IGNpbj4+dT4+djsgLS11Oy0tdjsgZ1t1XS5wdXNoX2JhY2sodik7IGdbdl0ucHVzaF9iYWNrKHUpOyB9CiAgYnVpbGQoMCk7IGRvd24oKTsgdXAoKTsgY29tcEUoKTsgR0UoKTsKCiAgUCBwID0gY250UGFpcnMoKTsKICB2ZWN0b3I8cGFpcjxNLGxsPj4gbHN0OwogIGxzdC5wdXNoX2JhY2soe21hdCgxLDEsMCwxKSwgcC5lZV9zYW1lfSk7CiAgbHN0LnB1c2hfYmFjayh7bWF0KDEsMSwwLDApLCBwLmVlX2RpZmZ9KTsKICBsc3QucHVzaF9iYWNrKHttYXQoMSwwLDAsMCksIHAuZW5MfSk7CiAgbHN0LnB1c2hfYmFjayh7bWF0KDAsMSwwLDApLCBwLmVuUn0pOwogIGxzdC5wdXNoX2JhY2soe21hdCgwLDAsMCwxKSwgcC5ubl9zYW1lfSk7CiAgbHN0LnB1c2hfYmFjayh7bWF0KDAsMCwxLDApLCBwLm5uX3RpZ2h0fSk7CiAgbHN0LnB1c2hfYmFjayh7bWF0KDAsMCwwLDApLCBwLm5uX290aGVyfSk7CiAgTSBzdGVwID0gYWdnMShsc3QpOwogIE0gbWlkID0gKGQ+PTI/IG1wb3coc3RlcCxkLTEpOiBNOjpJKCkpOwoKICBFQyBlID0gZW5kcygwKTsKICBsbCBhbnMgPSAwOwogIGZvcihpbnQgZXI9MDtlcjw9MTtlcisrKXsKICAgIFYyIHZOID0gVjI6OnNOKGVyKTsKICAgIFYyIHZSMCA9IFYyOjpzUihlciwwKTsKICAgIFYyIHZSMSA9IFYyOjpzUihlciwxKTsKICAgIFYyIHROID0gbXVsdm0odk4sbWlkKSwgdFIwID0gbXVsdm0odlIwLG1pZCksIHRSMSA9IG11bHZtKHZSMSxtaWQpOwogICAgZm9yKGludCBlbD0wO2VsPD0xO2VsKyspewogICAgICBWQyBWTiA9IGZpbih0TixlbCksIFZSMCA9IGZpbih0UjAsZWwpLCBWUjEgPSBmaW4odFIxLGVsKTsKICAgICAgaWYoZXNzWzBdKXsgaWYoVlIwLmMpIFZSMC52LT0xOyBpZihWUjEuYykgVlIxLnYtPTE7IH0KICAgICAgaW50IGNudFIgPSBlLnJbZXJdLCBjbnRSZSA9IChlcj09MD8gZS5leHI6MCksIGNudEwgPSBlLmxbZWxdOwogICAgICBpZihWTi52PlZSMC52KXsgbGwgYWRkID0gMUxMKigoY250UiAtIGNudFJlICsgTU9EKSVNT0QpKmNudEwlTU9EOyBhZGQgPSBhZGQqVk4uYyVNT0Q7IGFucz0oYW5zK2FkZCklTU9EOyB9CiAgICAgIGlmKGNudFJlICYmIFZOLnY+VlIxLnYpeyBsbCBhZGQgPSAxTEwqY250UmUqY250TCVNT0Q7IGFkZCA9IGFkZCpWTi5jJU1PRDsgYW5zPShhbnMrYWRkKSVNT0Q7IH0KICAgIH0KICB9CiAgY291dDw8YW5zJU1PRDw8IlxuIjsKICByZXR1cm4gMDsKfQ==