#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
#ifdef DEBUG_
#include "../program_contest_library/memo/dump.hpp"
#else
#define dump(...)
#endif
const ll INF = 1LL<<60;
template<ll MOD>
struct modint {
ll x;
modint(): x(0) {}
modint(ll y) : x(y>=0 ? y%MOD : y%MOD+MOD) {}
static constexpr ll mod() { return MOD; }
// e乗
modint pow(ll e) {
ll a = 1, p = x;
while(e > 0) {
if(e%2 == 0) {p = (p*p) % MOD; e /= 2;}
else {a = (a*p) % MOD; e--;}
}
return modint(a);
}
modint inv() const {
ll a=x, b=MOD, u=1, y=1, v=0, z=0;
while(a) {
ll q = b/a;
swap(z -= q*u, u);
swap(y -= q*v, v);
swap(b -= q*a, a);
}
return z;
}
// Comparators
bool operator <(modint b) { return x < b.x; }
bool operator >(modint b) { return x > b.x; }
bool operator<=(modint b) { return x <= b.x; }
bool operator>=(modint b) { return x >= b.x; }
bool operator!=(modint b) { return x != b.x; }
bool operator==(modint b) { return x == b.x; }
// Basic Operations
modint operator+(modint r) const { return modint(*this) += r; }
modint operator-(modint r) const { return modint(*this) -= r; }
modint operator*(modint r) const { return modint(*this) *= r; }
modint operator/(modint r) const { return modint(*this) /= r; }
modint &operator+=(modint r) {
if((x += r.x) >= MOD) x -= MOD;
return *this;
}
modint &operator-=(modint r) {
if((x -= r.x) < 0) x += MOD;
return *this;
}
modint &operator*=(modint r) {
#if !defined(_WIN32) || defined(_WIN64)
x = x * r.x % MOD; return *this;
#endif
unsigned long long y = x * r.x;
unsigned xh = (unsigned) (y >> 32), xl = (unsigned) y, d, m;
asm(
"divl %4; \n\t"
: "=a" (d), "=d" (m)
: "d" (xh), "a" (xl), "r" (MOD)
);
x = m;
return *this;
}
modint &operator/=(modint r) { return *this *= r.inv(); }
// increment, decrement
modint operator++() { x++; return *this; }
modint operator++(signed) { modint t = *this; x++; return t; }
modint operator--() { x--; return *this; }
modint operator--(signed) { modint t = *this; x--; return t; }
// 平方剰余のうち一つを返す なければ-1
friend modint sqrt(modint a) {
if(a == 0) return 0;
ll q = MOD-1, s = 0;
while((q&1)==0) q>>=1, s++;
modint z=2;
while(1) {
if(z.pow((MOD-1)/2) == MOD-1) break;
z++;
}
modint c = z.pow(q), r = a.pow((q+1)/2), t = a.pow(q);
ll m = s;
while(t.x>1) {
modint tp=t;
ll k=-1;
FOR(i, 1, m) {
tp *= tp;
if(tp == 1) { k=i; break; }
}
if(k==-1) return -1;
modint cp=c;
REP(i, m-k-1) cp *= cp;
c = cp*cp, t = c*t, r = cp*r, m = k;
}
return r.x;
}
template<class T>
friend modint operator*(T l, modint r) { return modint(l) *= r; }
template<class T>
friend modint operator+(T l, modint r) { return modint(l) += r; }
template<class T>
friend modint operator-(T l, modint r) { return modint(l) -= r; }
template<class T>
friend modint operator/(T l, modint r) { return modint(l) /= r; }
template<class T>
friend bool operator==(T l, modint r) { return modint(l) == r; }
template<class T>
friend bool operator!=(T l, modint r) { return modint(l) != r; }
// Input/Output
friend ostream &operator<<(ostream& os, modint a) { return os << a.x; }
friend istream &operator>>(istream& is, modint &a) {
is >> a.x;
a.x = ((a.x%MOD)+MOD)%MOD;
return is;
}
friend string to_frac(modint v) {
static map<ll, PII> mp;
if(mp.empty()) {
mp[0] = mp[MOD] = {0, 1};
FOR(i, 2, 1001) FOR(j, 1, i) if(__gcd(i, j) == 1) {
mp[(modint(i) / j).x] = {i, j};
}
}
auto itr = mp.lower_bound(v.x);
if(itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x) --itr;
string ret = to_string(itr->second.first + itr->second.second * ((int)v.x - itr->first));
if(itr->second.second > 1) {
ret += '/';
ret += to_string(itr->second.second);
}
return ret;
}
};
using mint = modint<1000000007>;
int main(void) {
ll n, m;
cin >> n >> m;
vector<vector<ll>> g(n);
REP(i, n-1) {
ll a, b;
cin >> a >> b;
a--, b--;
g[a].push_back(b);
g[b].push_back(a);
}
vector<ll> sz(n), dead(n);
auto find_centroid = [&](ll root) {
auto get_size = [&](auto &&self, ll v, ll p) -> void {
sz[v] = 1;
for(auto to: g[v]) if(to != p && !dead[to]) {
self(self, to, v);
sz[v] += sz[to];
}
};
get_size(get_size, root, -1);
auto dfs = [&](auto &&self, ll v, ll p) -> ll {
for(auto to: g[v]) if(to != p && !dead[to]) {
if(sz[to] > sz[root]/2) return self(self, to, v);
}
return v;
};
return dfs(dfs, root, -1);
};
mint ret = 0;
vector<ll> cnt_dist(n);
auto centroid_decomposition = [&](auto &&self, ll root) -> void {
ll c = find_centroid(root);
dead[c] = true;
for(auto to: g[c]) if(!dead[to]) {
self(self, to);
}
vector<vector<ll>> dist;
auto dfs = [&](auto &&self, ll v, ll p, ll d) -> void {
dist.back().emplace_back(d);
for(auto to: g[v]) if(to!=p && !dead[to]) {
self(self, to, v, d+1);
}
};
dist.push_back({0});
for(auto to: g[c]) if(!dead[to]) {
dist.emplace_back();
dfs(dfs, to, -1, 1);
sort(ALL(dist.back()));
}
vector<ll> flat;
for(auto v: dist) for(auto i: v) flat.push_back(i);
sort(ALL(flat));
for(auto v: dist) for(auto i: v) {
// 距離 m-i の頂点が何個?
auto lb1 = lower_bound(ALL(flat), m-i);
auto ub1 = upper_bound(ALL(flat), m-i);
ret += ub1 - lb1;
auto lb2 = lower_bound(ALL(v), m-i);
auto ub2 = upper_bound(ALL(v), m-i);
ret -= ub2 - lb2;
}
dead[c] = false;
};
centroid_decomposition(centroid_decomposition, 0);
ret *= m;
ret *= m+1;
ret /= 2;
cout << ret/2 << endl;
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnVzaW5nIGxsID0gbG9uZyBsb25nOwp1c2luZyBQSUkgPSBwYWlyPGxsLCBsbD47CiNkZWZpbmUgRk9SKGksIGEsIG4pIGZvciAobGwgaSA9IChsbClhOyBpIDwgKGxsKW47ICsraSkKI2RlZmluZSBSRVAoaSwgbikgRk9SKGksIDAsIG4pCiNkZWZpbmUgQUxMKHgpIHguYmVnaW4oKSwgeC5lbmQoKQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB2b2lkIGNobWluKFQgJmEsIGNvbnN0IFQgJmIpIHsgYSA9IG1pbihhLCBiKTsgfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB2b2lkIGNobWF4KFQgJmEsIGNvbnN0IFQgJmIpIHsgYSA9IG1heChhLCBiKTsgfQpzdHJ1Y3QgRmFzdElPIHtGYXN0SU8oKSB7IGNpbi50aWUoMCk7IGlvczo6c3luY193aXRoX3N0ZGlvKDApOyB9fWZhc3Rpb2Zhc3RpbzsKI2lmZGVmIERFQlVHXyAKI2luY2x1ZGUgIi4uL3Byb2dyYW1fY29udGVzdF9saWJyYXJ5L21lbW8vZHVtcC5ocHAiCiNlbHNlCiNkZWZpbmUgZHVtcCguLi4pCiNlbmRpZgpjb25zdCBsbCBJTkYgPSAxTEw8PDYwOwoKdGVtcGxhdGU8bGwgTU9EPgpzdHJ1Y3QgbW9kaW50IHsKICAgIGxsIHg7CiAgICBtb2RpbnQoKTogeCgwKSB7fQogICAgbW9kaW50KGxsIHkpIDogeCh5Pj0wID8geSVNT0QgOiB5JU1PRCtNT0QpIHt9CiAgICBzdGF0aWMgY29uc3RleHByIGxsIG1vZCgpIHsgcmV0dXJuIE1PRDsgfQogICAgLy8gZeS5lwogICAgbW9kaW50IHBvdyhsbCBlKSB7CiAgICAgICAgbGwgYSA9IDEsIHAgPSB4OwogICAgICAgIHdoaWxlKGUgPiAwKSB7CiAgICAgICAgICAgIGlmKGUlMiA9PSAwKSB7cCA9IChwKnApICUgTU9EOyBlIC89IDI7fQogICAgICAgICAgICBlbHNlIHthID0gKGEqcCkgJSBNT0Q7IGUtLTt9CiAgICAgICAgfQogICAgICAgIHJldHVybiBtb2RpbnQoYSk7CiAgICB9CiAgICBtb2RpbnQgaW52KCkgY29uc3QgewogICAgICAgIGxsIGE9eCwgYj1NT0QsIHU9MSwgeT0xLCB2PTAsIHo9MDsKICAgICAgICB3aGlsZShhKSB7CiAgICAgICAgICAgIGxsIHEgPSBiL2E7CiAgICAgICAgICAgIHN3YXAoeiAtPSBxKnUsIHUpOwogICAgICAgICAgICBzd2FwKHkgLT0gcSp2LCB2KTsKICAgICAgICAgICAgc3dhcChiIC09IHEqYSwgYSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB6OwogICAgfQogICAgLy8gQ29tcGFyYXRvcnMKICAgIGJvb2wgb3BlcmF0b3IgPChtb2RpbnQgYikgeyByZXR1cm4geCA8IGIueDsgfQogICAgYm9vbCBvcGVyYXRvciA+KG1vZGludCBiKSB7IHJldHVybiB4ID4gYi54OyB9CiAgICBib29sIG9wZXJhdG9yPD0obW9kaW50IGIpIHsgcmV0dXJuIHggPD0gYi54OyB9CiAgICBib29sIG9wZXJhdG9yPj0obW9kaW50IGIpIHsgcmV0dXJuIHggPj0gYi54OyB9CiAgICBib29sIG9wZXJhdG9yIT0obW9kaW50IGIpIHsgcmV0dXJuIHggIT0gYi54OyB9CiAgICBib29sIG9wZXJhdG9yPT0obW9kaW50IGIpIHsgcmV0dXJuIHggPT0gYi54OyB9CiAgICAvLyBCYXNpYyBPcGVyYXRpb25zCiAgICBtb2RpbnQgb3BlcmF0b3IrKG1vZGludCByKSBjb25zdCB7IHJldHVybiBtb2RpbnQoKnRoaXMpICs9IHI7IH0KICAgIG1vZGludCBvcGVyYXRvci0obW9kaW50IHIpIGNvbnN0IHsgcmV0dXJuIG1vZGludCgqdGhpcykgLT0gcjsgfQogICAgbW9kaW50IG9wZXJhdG9yKihtb2RpbnQgcikgY29uc3QgeyByZXR1cm4gbW9kaW50KCp0aGlzKSAqPSByOyB9CiAgICBtb2RpbnQgb3BlcmF0b3IvKG1vZGludCByKSBjb25zdCB7IHJldHVybiBtb2RpbnQoKnRoaXMpIC89IHI7IH0KICAgIG1vZGludCAmb3BlcmF0b3IrPShtb2RpbnQgcikgewogICAgICAgIGlmKCh4ICs9IHIueCkgPj0gTU9EKSB4IC09IE1PRDsKICAgICAgICByZXR1cm4gKnRoaXM7CiAgICB9CiAgICBtb2RpbnQgJm9wZXJhdG9yLT0obW9kaW50IHIpIHsKICAgICAgICBpZigoeCAtPSByLngpIDwgMCkgeCArPSBNT0Q7CiAgICAgICAgcmV0dXJuICp0aGlzOwogICAgfQogICAgbW9kaW50ICZvcGVyYXRvcio9KG1vZGludCByKSB7CiAgICAjaWYgIWRlZmluZWQoX1dJTjMyKSB8fCBkZWZpbmVkKF9XSU42NCkKICAgICAgICB4ID0geCAqIHIueCAlIE1PRDsgcmV0dXJuICp0aGlzOwogICAgI2VuZGlmCiAgICAgICAgdW5zaWduZWQgbG9uZyBsb25nIHkgPSB4ICogci54OwogICAgICAgIHVuc2lnbmVkIHhoID0gKHVuc2lnbmVkKSAoeSA+PiAzMiksIHhsID0gKHVuc2lnbmVkKSB5LCBkLCBtOwogICAgICAgIGFzbSgKICAgICAgICAgICAgImRpdmwgJTQ7IFxuXHQiCiAgICAgICAgICAgIDogIj1hIiAoZCksICI9ZCIgKG0pCiAgICAgICAgICAgIDogImQiICh4aCksICJhIiAoeGwpLCAiciIgKE1PRCkKICAgICAgICApOwogICAgICAgIHggPSBtOwogICAgICAgIHJldHVybiAqdGhpczsKICAgIH0KICAgIG1vZGludCAmb3BlcmF0b3IvPShtb2RpbnQgcikgeyByZXR1cm4gKnRoaXMgKj0gci5pbnYoKTsgfQogICAgLy8gaW5jcmVtZW50LCBkZWNyZW1lbnQKICAgIG1vZGludCBvcGVyYXRvcisrKCkgeyB4Kys7IHJldHVybiAqdGhpczsgfQogICAgbW9kaW50IG9wZXJhdG9yKysoc2lnbmVkKSB7IG1vZGludCB0ID0gKnRoaXM7IHgrKzsgcmV0dXJuIHQ7IH0KICAgIG1vZGludCBvcGVyYXRvci0tKCkgeyB4LS07IHJldHVybiAqdGhpczsgfQogICAgbW9kaW50IG9wZXJhdG9yLS0oc2lnbmVkKSB7IG1vZGludCB0ID0gKnRoaXM7IHgtLTsgcmV0dXJuIHQ7IH0KICAgIC8vIOW5s+aWueWJsOS9meOBruOBhuOBoeS4gOOBpOOCkui/lOOBmSDjgarjgZHjgozjgbAtMQogICAgZnJpZW5kIG1vZGludCBzcXJ0KG1vZGludCBhKSB7CiAgICAgICAgaWYoYSA9PSAwKSByZXR1cm4gMDsKICAgICAgICBsbCBxID0gTU9ELTEsIHMgPSAwOwogICAgICAgIHdoaWxlKChxJjEpPT0wKSBxPj49MSwgcysrOwogICAgICAgIG1vZGludCB6PTI7CiAgICAgICAgd2hpbGUoMSkgewogICAgICAgICAgICBpZih6LnBvdygoTU9ELTEpLzIpID09IE1PRC0xKSBicmVhazsKICAgICAgICAgICAgeisrOwogICAgICAgIH0KICAgICAgICBtb2RpbnQgYyA9IHoucG93KHEpLCByID0gYS5wb3coKHErMSkvMiksIHQgPSBhLnBvdyhxKTsKICAgICAgICBsbCBtID0gczsKICAgICAgICB3aGlsZSh0Lng+MSkgewogICAgICAgICAgICBtb2RpbnQgdHA9dDsKICAgICAgICAgICAgbGwgaz0tMTsKICAgICAgICAgICAgRk9SKGksIDEsIG0pIHsKICAgICAgICAgICAgICAgIHRwICo9IHRwOwogICAgICAgICAgICAgICAgaWYodHAgPT0gMSkgeyBrPWk7IGJyZWFrOyB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoaz09LTEpIHJldHVybiAtMTsKICAgICAgICAgICAgbW9kaW50IGNwPWM7CiAgICAgICAgICAgIFJFUChpLCBtLWstMSkgY3AgKj0gY3A7CiAgICAgICAgICAgIGMgPSBjcCpjcCwgdCA9IGMqdCwgciA9IGNwKnIsIG0gPSBrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gci54OwogICAgfQoKICAgIHRlbXBsYXRlPGNsYXNzIFQ+CiAgICBmcmllbmQgbW9kaW50IG9wZXJhdG9yKihUIGwsIG1vZGludCByKSB7IHJldHVybiBtb2RpbnQobCkgKj0gcjsgfQogICAgdGVtcGxhdGU8Y2xhc3MgVD4KICAgIGZyaWVuZCBtb2RpbnQgb3BlcmF0b3IrKFQgbCwgbW9kaW50IHIpIHsgcmV0dXJuIG1vZGludChsKSArPSByOyB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBUPgogICAgZnJpZW5kIG1vZGludCBvcGVyYXRvci0oVCBsLCBtb2RpbnQgcikgeyByZXR1cm4gbW9kaW50KGwpIC09IHI7IH0KICAgIHRlbXBsYXRlPGNsYXNzIFQ+CiAgICBmcmllbmQgbW9kaW50IG9wZXJhdG9yLyhUIGwsIG1vZGludCByKSB7IHJldHVybiBtb2RpbnQobCkgLz0gcjsgfQogICAgdGVtcGxhdGU8Y2xhc3MgVD4KICAgIGZyaWVuZCBib29sIG9wZXJhdG9yPT0oVCBsLCBtb2RpbnQgcikgeyByZXR1cm4gbW9kaW50KGwpID09IHI7IH0KICAgIHRlbXBsYXRlPGNsYXNzIFQ+CiAgICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KFQgbCwgbW9kaW50IHIpIHsgcmV0dXJuIG1vZGludChsKSAhPSByOyB9CiAgICAvLyBJbnB1dC9PdXRwdXQKICAgIGZyaWVuZCBvc3RyZWFtICZvcGVyYXRvcjw8KG9zdHJlYW0mIG9zLCBtb2RpbnQgYSkgeyByZXR1cm4gb3MgPDwgYS54OyB9CiAgICBmcmllbmQgaXN0cmVhbSAmb3BlcmF0b3I+Pihpc3RyZWFtJiBpcywgbW9kaW50ICZhKSB7IAogICAgICAgIGlzID4+IGEueDsKICAgICAgICBhLnggPSAoKGEueCVNT0QpK01PRCklTU9EOwogICAgICAgIHJldHVybiBpczsKICAgIH0KICAgIGZyaWVuZCBzdHJpbmcgdG9fZnJhYyhtb2RpbnQgdikgewogICAgICAgIHN0YXRpYyBtYXA8bGwsIFBJST4gbXA7CiAgICAgICAgaWYobXAuZW1wdHkoKSkgewogICAgICAgICAgICBtcFswXSA9IG1wW01PRF0gPSB7MCwgMX07CiAgICAgICAgICAgIEZPUihpLCAyLCAxMDAxKSBGT1IoaiwgMSwgaSkgaWYoX19nY2QoaSwgaikgPT0gMSkgewogICAgICAgICAgICAgICAgbXBbKG1vZGludChpKSAvIGopLnhdID0ge2ksIGp9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGF1dG8gaXRyID0gbXAubG93ZXJfYm91bmQodi54KTsKICAgICAgICBpZihpdHIgIT0gbXAuYmVnaW4oKSAmJiB2LnggLSBwcmV2KGl0ciktPmZpcnN0IDwgaXRyLT5maXJzdCAtIHYueCkgLS1pdHI7CiAgICAgICAgc3RyaW5nIHJldCA9IHRvX3N0cmluZyhpdHItPnNlY29uZC5maXJzdCArIGl0ci0+c2Vjb25kLnNlY29uZCAqICgoaW50KXYueCAtIGl0ci0+Zmlyc3QpKTsKICAgICAgICBpZihpdHItPnNlY29uZC5zZWNvbmQgPiAxKSB7CiAgICAgICAgICAgIHJldCArPSAnLyc7CiAgICAgICAgICAgIHJldCArPSB0b19zdHJpbmcoaXRyLT5zZWNvbmQuc2Vjb25kKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgIH0KfTsKdXNpbmcgbWludCA9IG1vZGludDwxMDAwMDAwMDA3PjsKCmludCBtYWluKHZvaWQpIHsKICAgIGxsIG4sIG07CiAgICBjaW4gPj4gbiA+PiBtOwogICAgdmVjdG9yPHZlY3RvcjxsbD4+IGcobik7CiAgICBSRVAoaSwgbi0xKSB7CiAgICAgICAgbGwgYSwgYjsKICAgICAgICBjaW4gPj4gYSA+PiBiOwogICAgICAgIGEtLSwgYi0tOwogICAgICAgIGdbYV0ucHVzaF9iYWNrKGIpOwogICAgICAgIGdbYl0ucHVzaF9iYWNrKGEpOwogICAgfQoKICAgIHZlY3RvcjxsbD4gc3oobiksIGRlYWQobik7CiAgICBhdXRvIGZpbmRfY2VudHJvaWQgPSBbJl0obGwgcm9vdCkgewogICAgICAgIGF1dG8gZ2V0X3NpemUgPSBbJl0oYXV0byAmJnNlbGYsIGxsIHYsIGxsIHApIC0+IHZvaWQgewogICAgICAgICAgICBzelt2XSA9IDE7CiAgICAgICAgICAgIGZvcihhdXRvIHRvOiBnW3ZdKSBpZih0byAhPSBwICYmICFkZWFkW3RvXSkgewogICAgICAgICAgICAgICAgc2VsZihzZWxmLCB0bywgdik7CiAgICAgICAgICAgICAgICBzelt2XSArPSBzelt0b107CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIGdldF9zaXplKGdldF9zaXplLCByb290LCAtMSk7CiAgICAgICAgYXV0byBkZnMgPSBbJl0oYXV0byAmJnNlbGYsIGxsIHYsIGxsIHApIC0+IGxsIHsKICAgICAgICAgICAgZm9yKGF1dG8gdG86IGdbdl0pIGlmKHRvICE9IHAgJiYgIWRlYWRbdG9dKSB7CiAgICAgICAgICAgICAgICBpZihzelt0b10gPiBzeltyb290XS8yKSByZXR1cm4gc2VsZihzZWxmLCB0bywgdik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gZGZzKGRmcywgcm9vdCwgLTEpOwogICAgfTsKCiAgICBtaW50IHJldCA9IDA7CiAgICB2ZWN0b3I8bGw+IGNudF9kaXN0KG4pOwogICAgYXV0byBjZW50cm9pZF9kZWNvbXBvc2l0aW9uID0gWyZdKGF1dG8gJiZzZWxmLCBsbCByb290KSAtPiB2b2lkIHsKICAgICAgICBsbCBjID0gZmluZF9jZW50cm9pZChyb290KTsKICAgICAgICBkZWFkW2NdID0gdHJ1ZTsKICAgICAgICBmb3IoYXV0byB0bzogZ1tjXSkgaWYoIWRlYWRbdG9dKSB7CiAgICAgICAgICAgIHNlbGYoc2VsZiwgdG8pOwogICAgICAgIH0KCiAgICAgICAgdmVjdG9yPHZlY3RvcjxsbD4+IGRpc3Q7CiAgICAgICAgYXV0byBkZnMgPSBbJl0oYXV0byAmJnNlbGYsIGxsIHYsIGxsIHAsIGxsIGQpIC0+IHZvaWQgewogICAgICAgICAgICBkaXN0LmJhY2soKS5lbXBsYWNlX2JhY2soZCk7CiAgICAgICAgICAgIGZvcihhdXRvIHRvOiBnW3ZdKSBpZih0byE9cCAmJiAhZGVhZFt0b10pIHsKICAgICAgICAgICAgICAgIHNlbGYoc2VsZiwgdG8sIHYsIGQrMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIGRpc3QucHVzaF9iYWNrKHswfSk7CiAgICAgICAgZm9yKGF1dG8gdG86IGdbY10pIGlmKCFkZWFkW3RvXSkgewogICAgICAgICAgICBkaXN0LmVtcGxhY2VfYmFjaygpOwogICAgICAgICAgICBkZnMoZGZzLCB0bywgLTEsIDEpOwogICAgICAgICAgICBzb3J0KEFMTChkaXN0LmJhY2soKSkpOwogICAgICAgIH0KCiAgICAgICAgdmVjdG9yPGxsPiBmbGF0OwogICAgICAgIGZvcihhdXRvIHY6IGRpc3QpIGZvcihhdXRvIGk6IHYpIGZsYXQucHVzaF9iYWNrKGkpOwogICAgICAgIHNvcnQoQUxMKGZsYXQpKTsKCiAgICAgICAgZm9yKGF1dG8gdjogZGlzdCkgZm9yKGF1dG8gaTogdikgewogICAgICAgICAgICAvLyDot53pm6IgbS1pIOOBrumggueCueOBjOS9leWAi++8nwogICAgICAgICAgICBhdXRvIGxiMSA9IGxvd2VyX2JvdW5kKEFMTChmbGF0KSwgbS1pKTsKICAgICAgICAgICAgYXV0byB1YjEgPSB1cHBlcl9ib3VuZChBTEwoZmxhdCksIG0taSk7CiAgICAgICAgICAgIHJldCArPSB1YjEgLSBsYjE7CiAgICAgICAgICAgIGF1dG8gbGIyID0gbG93ZXJfYm91bmQoQUxMKHYpLCBtLWkpOwogICAgICAgICAgICBhdXRvIHViMiA9IHVwcGVyX2JvdW5kKEFMTCh2KSwgbS1pKTsKICAgICAgICAgICAgcmV0IC09IHViMiAtIGxiMjsKICAgICAgICB9CgogICAgICAgIGRlYWRbY10gPSBmYWxzZTsKICAgIH07CiAgICBjZW50cm9pZF9kZWNvbXBvc2l0aW9uKGNlbnRyb2lkX2RlY29tcG9zaXRpb24sIDApOwoKICAgIHJldCAqPSBtOwogICAgcmV0ICo9IG0rMTsKICAgIHJldCAvPSAyOwogICAgY291dCA8PCByZXQvMiA8PCBlbmRsOwoKICAgIHJldHVybiAwOwp9