#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>

#define INF 2E9
#define INF64 4E18

using namespace std;

template<class T1, class T2> void pr(const pair<T1,T2>& x);
template<class T, size_t SZ> void pr(const array<T,SZ>& x);
template<class T> void pr(const vector<T>& x);
template<class T> void pr(const set<T>& x);
template<class T1, class T2> void pr(const map<T1,T2>& x);
template<class T> void pr(const T& x) { cout << x; }
template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
  pr(first); pr(rest...);
}
template<class T1, class T2> void pr(const pair<T1,T2>& x) {
  pr("{",x.first,", ",x.second,"}");
}
template<class T> void prContain(const T& x) {
  pr("{");bool fst = 1; for(auto &a: x) pr(!fst?", ":"",a), fst = 0;pr("}");
}
template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
template<class T> void pr(const vector<T>& x) { prContain(x); }
template<class T> void pr(const set<T>& x) { prContain(x); }
template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

void ps() { pr("\n"); }
template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
  pr(first," "); ps(rest...); // print w/ spaces
}

template<typename T> int remin(T& a,const T& b){if(b<a){a=b;return true;}return false;}
template<typename T> int remax(T& a,const T& b){if(b>a){a=b;return true;}return false;}

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef vector<vi> vvi;
typedef pair<int, int> ii;
typedef tuple<ll, ll, ll> iii;
typedef vector<ii> vii;

int n;
ll S;
vector<vector<ii>> G;
int leaves[100005];
ll total;

int dfs(int u, int p = -1) {
  int total = 0;
  for (ii v: G[u]) if (v.first != p) {
    total += dfs(v.first, u);
  }
  return leaves[u] = max(1, total);
}

void dfs2(priority_queue<iii> &q, int u, int p = -1) {
  for (ii v: G[u]) if (v.first != p) {
    q.push(iii(1LL * leaves[v.first] * ((v.second + 1LL)/2), leaves[v.first], v.second));
    total += leaves[v.first] * v.second;
    dfs2(q, v.first, u);
  }
}

void solve() {
  scanf("%d%lld", &n, &S);
  priority_queue<iii> q;
  total = 0;
  for (int i = 0; i < n; ++i) leaves[i] = 0;
  G.assign(n, vector<ii>(0));
  for (int i = 0; i < n-1; ++i) {
    int u, v, w; scanf("%d%d%d", &u, &v, &w);
    --u, --v;
    G[u].push_back(ii(v, w));
    G[v].push_back(ii(u, w));
  }
  dfs(0);
  dfs2(q, 0);
  int ans = 0;
  while (total > S) {
    auto [c, a, b] = q.top();
    total -= a * b - a * (b/2);
    b /= 2;
    q.pop();
    q.push(iii(a*((b+1LL)/2), a, b));
    ++ans;
  }
  printf("%d\n", ans);
}

int main(int argc, const char **argv) {
  int TT; scanf("%d", &TT);
  for (int tt = 1; tt <= TT; ++tt) {
    solve();
  }
  return 0;
}


#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>

#define INF 2E9
#define INF64 4E18

using namespace std;

template<class T1, class T2> void pr(const pair<T1,T2>& x);
template<class T, size_t SZ> void pr(const array<T,SZ>& x);
template<class T> void pr(const vector<T>& x);
template<class T> void pr(const set<T>& x);
template<class T1, class T2> void pr(const map<T1,T2>& x);
template<class T> void pr(const T& x) { cout << x; }
template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
  pr(first); pr(rest...);
}
template<class T1, class T2> void pr(const pair<T1,T2>& x) {
  pr("{",x.first,", ",x.second,"}");
}
template<class T> void prContain(const T& x) {
  pr("{");bool fst = 1; for(auto &a: x) pr(!fst?", ":"",a), fst = 0;pr("}");
}
template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
template<class T> void pr(const vector<T>& x) { prContain(x); }
template<class T> void pr(const set<T>& x) { prContain(x); }
template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

void ps() { pr("\n"); }
template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
  pr(first," "); ps(rest...); // print w/ spaces
}

template<typename T> int remin(T& a,const T& b){if(b<a){a=b;return true;}return false;}
template<typename T> int remax(T& a,const T& b){if(b>a){a=b;return true;}return false;}

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef vector<vi> vvi;
typedef pair<int, int> ii;
typedef tuple<int, int, int> iii;
typedef vector<ii> vii;

int n;
ll S;
vector<vector<ii>> G;
int leaves[100005];
ll total;

int dfs(int u, int p = -1) {
  int total = 0;
  for (ii v: G[u]) if (v.first != p) {
    total += dfs(v.first, u);
  }
  return leaves[u] = max(1, total);
}

void dfs2(priority_queue<iii> &q, int u, int p = -1) {
  for (ii v: G[u]) if (v.first != p) {
    q.push(iii(leaves[v.first] * ((v.second + 1)/2), leaves[v.first], v.second));
    total += leaves[v.first] * v.second;
    dfs2(q, v.first, u);
  }
}

void solve() {
  scanf("%d%lld", &n, &S);
  priority_queue<iii> q;
  total = 0;
  for (int i = 0; i < n; ++i) leaves[i] = 0;
  G.assign(n, vector<ii>(0));
  for (int i = 0; i < n-1; ++i) {
    int u, v, w; scanf("%d%d%d", &u, &v, &w);
    --u, --v;
    G[u].push_back(ii(v, w));
    G[v].push_back(ii(u, w));
  }
  dfs(0);
  dfs2(q, 0);
  int ans = 0;
  while (total > S) {
    auto [c, a, b] = q.top();
    total -= a * b - a * (b/2);
    b /= 2;
    q.pop();
    q.push(iii(a*((b+1)/2), a, b));
    ++ans;
  }
  printf("%d\n", ans);
}

int main(int argc, const char **argv) {
  int TT; scanf("%d", &TT);
  for (int tt = 1; tt <= TT; ++tt) {
    solve();
  }
  return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
      return (l.first*l.second)-((l.first/2)*l.second)>(r.first*r.second)-((r.first/2)*r.second);
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{src,v,mp[lp]}]=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{v,src,mp[lp]}]=wtmp[{src,v,mp[lp]}];
            wtmp[{par,src,mp[p]}]+=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{src,par,mp[p]}]=wtmp[{par,src,mp[p]}];
        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0;
            while(1){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first*l.second==r.first*r.second) return l.second>r.second;
     return l.first*l.second>r.first*r.second;
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{par,src,mp[p]}]+=wtmp[{src,v,mp[lp]}];
            wtmp[{src,par,mp[p]}]+=wtmp[{v,src,mp[lp]}];

        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            /* cout<<m.first.first<<" "<<m.first.second<<'\n';
             cout<<m.second<<" "<<wtmp[{m.first.first,m.first.second,m.second}]<<'\n'; */
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first==r.first) return l.second>r.second;
     return l.first>r.first;
 }
};
map<pair<int,int>,int> mp; map<int,int> wtmp; set<pair<int,int>,cmp> q; bool visited[100002];
void dfs(int src,int par,vector<vector<int>> &adj){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            pair<int,int> lp={src,v}; dfs(v,src,adj);
            wtmp[mp[p]]+=wtmp[mp[lp]];
        }
    }
    if(adj[src].size()==1){
        wtmp[mp[p]]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[m.second]});
            }
            look.insert({m.first.second,m.first.first});
        }
         for(auto p:q) sum+=p.first*p.second;
         int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
          mp.clear(); q.clear(); wtmp.clear();
          for(int i=1;i<=n;i++) visited[i]=false;
       }
 return 0;
 }


#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int maxm (ll int a,ll int b)
{    if(a>b) return a;
     else return b;
}
ll int minm (ll int a,ll int b)
{    if(a>b) return b;
     else return a;
}

int fun(ll int src,vector<vector<pair<ll int,ll int>>> &adj,priority_queue<tuple<ll int,ll int,ll int>> &ans,priority_queue<tuple<ll int,ll int,ll int>> &cpy,vector<bool>&vst,vector<ll int>&dp)
{  vst[src]=true;
int chk=0;
for(auto v:adj[src])
{
  ll int b=v.first,w=v.second;
   if(!vst[b])
   {
       chk=1;
       dp[src]+=fun(b,adj,ans,cpy,vst,dp); ans.push({(w*dp[b])-(dp[b]*int(w/2)),w,b});
       cpy.push({(w*dp[b])-(int(w/2)*dp[b]),w,b});
   }
}
if(chk==0) dp[src]=1;
return int(dp[src]);
}

void cal()
{  ll int n,tar,i;cin>>n>>tar; vector<vector<pair<ll int,ll int>>>adj(100001);
    vector<bool>vst(100001,false);
      vector<ll int>dp(100001,0);
          priority_queue<tuple<ll int,ll int,ll int>> ans,cpy;

    for(i=0;i<n-1;i++)
    {
        int a,b,w;cin>>a>>b>>w;
        adj[a].push_back({b,w});
        adj[b].push_back({a,w});

    }
    ll int tp=fun(1,adj,ans,cpy,vst,dp);
    ll int sum=0;
   while(!ans.empty())
   {
      ll int a,b,w;
      tie(a,b,w)=ans.top();
      sum+=dp[w]*b;ans.pop();
   }
    ll int op=0;
    while(sum>tar)
    {   op++;
        ll int dif,wt,src;
        tie(dif,wt,src)=cpy.top();
        sum=sum-dif;
        cpy.pop();
        wt/=2;
        cpy.push({wt*dp[src]-dp[src]*(wt/2),wt,src});

    }cout<<op<<endl;

}

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(NULL);cout.tie(NULL);
   int t;cin>>t;while(t--)cal();
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first==r.first) return l.second>r.second;
     return l.first>r.first;
 }
};
map<pair<int,int>,int> mp; map<int,int> wtmp; set<pair<int,int>,cmp> q; bool visited[100002];
void dfs(int src,int par,vector<vector<int>> &adj){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            pair<int,int> lp={src,v}; dfs(v,src,adj);
            wtmp[mp[p]]+=wtmp[mp[lp]];
        }
    }
    if(adj[src].size()==1){
        wtmp[mp[p]]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[m.second]});
            }
            look.insert({m.first.second,m.first.first});
        }
         for(auto p:q) sum+=p.first*p.second;
         int moves=0; bool check=false;
            while(1){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
          mp.clear(); q.clear(); wtmp.clear();
          for(int i=1;i<=n;i++) visited[i]=false;
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first*l.second==r.first*r.second) return (l.first/2)*l.second<(r.first/2)*r.second;
     return l.first*l.second>r.first*r.second;
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{par,src,mp[p]}]+=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            /* cout<<m.first.first<<" "<<m.first.second<<'\n';
             cout<<m.second<<" "<<wtmp[{m.first.first,m.first.second,m.second}]<<'\n'; */
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first*l.second==r.first*r.second) return (l.first/2)*l.second<(r.first/2)*r.second;
     return l.first*l.second>r.first*r.second;
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{par,src,mp[p]}]+=wtmp[{src,v,mp[lp]}];
            wtmp[{src,par,mp[p]}]+=wtmp[{v,src,mp[lp]}];
        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            /* cout<<m.first.first<<" "<<m.first.second<<'\n';
             cout<<m.second<<" "<<wtmp[{m.first.first,m.first.second,m.second}]<<'\n'; */
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
      return (l.first*l.second)-((l.first/2)*l.second)>(r.first*r.second)-((r.first/2)*r.second);
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{src,v,mp[lp]}]=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{v,src,mp[lp]}]=wtmp[{src,v,mp[lp]}];
            wtmp[{par,src,mp[p]}]+=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{src,par,mp[p]}]=wtmp[{par,src,mp[p]}];
        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first==r.first) return l.second>r.second;
     return l.first>r.first;
 }
};
map<pair<int,int>,int> mp; map<int,int> wtmp; set<pair<int,int>,cmp> q; bool visited[100002];
void dfs(int src,int par,vector<vector<int>> &adj){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            pair<int,int> lp={src,v}; dfs(v,src,adj);
            wtmp[mp[p]]+=wtmp[mp[lp]];
        }
    }
    if(adj[src].size()==1){
        wtmp[mp[p]]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[m.second]});
            }
            look.insert({m.first.second,m.first.first});
        }
         for(auto p:q) sum+=p.first*p.second;
         int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++{
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
          mp.clear(); q.clear(); wtmp.clear();
          for(int i=1;i<=n;i++) visited[i]=false;
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first*l.second==r.first*r.second) return (l.first/2)*l.second<(r.first/2)*r.second;
      if(l.first*l.second==r.first*r.second&&(l.first/2)*l.second==(r.first/2)*r.second) return ((l.first/2)/2)*l.second<((r.first/2)/2)*r.second;
     return l.first*l.second>r.first*r.second;
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{src,v,mp[lp]}]=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{v,src,mp[lp]}]=wtmp[{src,v,mp[lp]}];
            wtmp[{par,src,mp[p]}]+=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{src,par,mp[p]}]=wtmp[{par,src,mp[p]}];
        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            /* cout<<m.first.first<<" "<<m.first.second<<'\n';
             cout<<m.second<<" "<<wtmp[{m.first.first,m.first.second,m.second}]<<'\n'; */
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
const int N = 2e7 + 7;
const int mod=1e9+7;
const int INF=1e18+7;
const int dx[] = {-1, 1, 0,  0}; // UDLR
const int dy[] = { 0, 0, -1, 1}; // UDLR
inline int maximum (int a,int b) {int c=a>b?a:b; return c;}
inline int minimum (int a,int b) {int c=a>b?b:a; return c;}
struct cmp{
 template<typename T>
 bool operator()(const T& l,const T& r) const{
     if(l.first*l.second==r.first*r.second) return (l.first/2)*l.second<(r.first/2)*r.second;
     return l.first*l.second>r.first*r.second;
 }
};
void dfs(int src,int par,vector<vector<int>> &adj,map<pair<int,int>,int> &mp,map<tuple<int,int,int>,int> &wtmp,bool visited[]){
    visited[src]=true; pair<int,int> p={par,src};
    for(auto v:adj[src]){
        if(!visited[v]){
            dfs(v,src,adj,mp,wtmp,visited);
            pair<int,int> lp={src,v};
            wtmp[{src,v,mp[lp]}]=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{v,src,mp[lp]}]=wtmp[{src,v,mp[lp]}];
            wtmp[{par,src,mp[p]}]+=maximum(wtmp[{src,v,mp[lp]}],wtmp[{v,src,mp[lp]}]);
            wtmp[{src,par,mp[p]}]=wtmp[{par,src,mp[p]}];
        }
    }
    if(adj[src].size()==1){
        wtmp[{par,src,mp[p]}]=1; wtmp[{src,par,mp[p]}]=1;
    }
}
int32_t main (){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);cout.tie(NULL);

       int t; cin>>t;
       while(t--){
       int n,s,sum=0; cin>>n>>s;  vector<vector<int>> adj(n+1); set<pair<int,int>> look;
       map<pair<int,int>,int> mp; map<tuple<int,int,int>,int> wtmp; multiset<pair<int,int>,cmp> q; bool visited[n+1]={false};
       for(int i=1;i<=n-1;i++){
         int u,v,wt; cin>>u>>v>>wt;
         adj[u].push_back(v); adj[v].push_back(u);
         mp[{u,v}]=wt; mp[{v,u}]=wt;
       }
         dfs(1,0,adj,mp,wtmp,visited);
        for(auto m:mp){
            if(look.count({m.first.first,m.first.second})==0){
             q.insert({m.second,wtmp[{m.first.first,m.first.second,m.second}]});
            /* cout<<m.first.first<<" "<<m.first.second<<'\n';
             cout<<m.second<<" "<<wtmp[{m.first.first,m.first.second,m.second}]<<'\n'; */
            }
            look.insert({m.first.second,m.first.first});
        }

            for(auto p:q) sum+=p.first*p.second;
            int moves=0; bool check=false;
            for(int i=1;i<=1000000;i++){
            auto it=q.begin();
            if(sum<=s) break;
            sum-=(it->first)*(it->second);
            sum+=(it->first/2)*(it->second);
            int ins_first=it->first/2,ins_second=it->second; moves++;
            q.erase(it); q.insert({ins_first,ins_second});
          }
          cout<<moves<<'\n';
       }
 return 0;
 }


#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int maxm (ll int a,ll int b)
{    if(a>b) return a;
     else return b;
}
ll int minm (ll int a,ll int b)
{    if(a>b) return b;
     else return a;
}
vector<pair<ll int,ll int>>adj[100001];
vector<bool>vst(100001);
vector<ll int>dp(100001,0);
priority_queue<tuple<ll int,ll int,ll int>> ans,cpy;

int fun(ll int src )
{  vst[src]=true;
int chk=0;
for(auto v:adj[src])
{
  ll int b=v.first,w=v.second;
   if(!vst[b])
   {
       chk=1;
       dp[src]+=fun(b); ans.push({w*dp[b]-dp[b]*(w/2),w,b});
       cpy.push({w*dp[b]-(w/2)*dp[b],w,b});
   }
}
if(chk==0)dp[src]=1;
return (dp[src]);
}

void cal()
{  ll int n,tar,i;cin>>n>>tar;
    for(i=0;i<n-1;i++)
    {
        int a,b,w;cin>>a>>b>>w;
        adj[a].push_back({b,w});
        adj[b].push_back({a,w});

    }
    ll int tp=fun(1);
    ll int sum=0;
   while(!ans.empty())
   {
      ll int a,b,w;
      tie(a,b,w)=ans.top();
      sum+=dp[w]*b;ans.pop();
   }
    ll int op=0;
    while(sum>tar)
    {   op++;
        ll int dif,wt,src;
        tie(dif,wt,src)=cpy.top();
        sum=sum-dif;
        cpy.pop();
        wt/=2;
        cpy.push({wt*dp[src]-dp[src]*(wt/2),wt,src});

    }cout<<op<<endl;

    for(ll int i=0;i<=100001;i++){adj[i].clear(); vst[i]=false; dp[i]=0;}
    for(int i=0;i<ans.size()&&!ans.empty();i++) ans.pop();
    for(int i=0;i<cpy.size()&&!cpy.empty();i++) cpy.pop();
}

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(NULL);cout.tie(NULL);
   int t;cin>>t;while(t--)cal();
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int maxm (ll int a,ll int b)
{    if(a>b) return a;
     else return b;
}
ll int minm (ll int a,ll int b)
{    if(a>b) return b;
     else return a;
}
vector<pair<ll int,ll int>>adj[100001];
vector<bool>vst(100001);
vector<ll int>dp(100001,0);
priority_queue<tuple<ll int,ll int,ll int>> ans,cpy;

int fun(ll int src )
{  vst[src]=true;
int chk=0;
for(auto v:adj[src])
{
  ll int b=v.first,w=v.second;
   if(!vst[b])
   {
       chk=1;
       dp[src]+=fun(b); ans.push({w*dp[b]-dp[b]*(w/2),w,b});
       cpy.push({w*dp[b]-(w/2)*dp[b],w,b});
   }
}
if(chk==0)dp[src]=1;
return (dp[src]);
}

void cal()
{  ll int n,tar,i;cin>>n>>tar;
    for(i=0;i<n-1;i++)
    {
        int a,b,w;cin>>a>>b>>w;
        adj[a].push_back({b,w});
        adj[b].push_back({a,w});

    }
    ll int tp=fun(1);
    ll int sum=0;
   while(!ans.empty())
   {
      ll int a,b,w;
      tie(a,b,w)=ans.top();
      sum+=dp[w]*b;ans.pop();
   }
    ll int op=0;
    while(sum>tar)
    {   op++;
        ll int dif,wt,src;
        tie(dif,wt,src)=cpy.top();
        sum=sum-dif;
        cpy.pop();
        wt/=2;
        cpy.push({wt*dp[src]-dp[src]*(wt/2),wt,src});

    }cout<<op<<endl;

    for(ll int i=0;i<100001;i++){adj[i].clear(); vst[i]=false; dp[i]=0;}
    for(int i=0;i<ans.size()&&!ans.empty();i++) ans.pop();
    for(int i=0;i<cpy.size()&&!cpy.empty();i++) cpy.pop();
}

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(NULL);cout.tie(NULL);
   int t;cin>>t;while(t--)cal();
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <numeric>
using namespace std;

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		int64_t s;
		cin >> n >> s;

		vector<vector<pair<int, int>>> g(n);
		vector<int64_t> gain;

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		int64_t ref = 0;
		auto go = [&](auto && go, int start, int parent)->int {
			int leaf = 0;
			for (pair<int, int> p : g[start])
			{
				if (p.first != parent)
				{
					int64_t l = go(go,p.first, start);
					leaf += l;
					int w = p.second;
					ref += w * l;
					while (w) {

						int w2 = floor(w / 2.0);
						gain.push_back((w - w2)*l);
						w = w2;
					}
				}
			}
			if (leaf == 0)
			{
				leaf = 1;
			}
			return leaf;
		};

		go(go,0,-1);
		sort(gain.begin(), gain.end());
		int i = 0;
		while (ref > s)
		{
			ref -= gain.back();
			i++;
			gain.pop_back();
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<ll> gain;
vector<ll> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start) {
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (g[p.first].size() >= 0)
		{
			ll l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l*1ll);
			while (w) {

				ll w2 = floor(w*1ll / 2.0);
				gain.push_back((w - w2)*l*1ll);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll int64_t

vector<vector<pair<int, int>>> g;
vector<ll> gain;
vector<ll> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start, int parent) {
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (p.first!=parent)
		{
			ll l = go(p.first,start);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0,-1);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

int go(int start) {
	visited[start] = 1;
	int leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			int l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		int ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<ll> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start) {
	visited[start] = 1;
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			ll l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start) {
	visited[start] = 1;
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			ll l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		int ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<ll> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start) {
	visited[start] = 1;
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			ll l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l*1ll);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

vector<vector<pair<int, int>>> g;
vector<int64_t> gain;
vector<int64_t> edges;

bool comp(int x, int y) {
	return x > y;
}

int go(int start, int parent) {
	int leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (p.first!=parent)
		{
			int64_t l = go(p.first,start);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				int w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		int64_t s;
		cin >> n >> s;

		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0,-1);
		sort(gain.begin(), gain.end());
		int64_t ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain.back();
			i++;
			gain.pop_back();
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<int> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

int go(int start) {
	visited[start] = 1;
	int leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			int l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {
				int w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n, s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		int ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start) {
	visited[start] = 1;
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			ll l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

int go(int start) {
	visited[start] = 1;
	int leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			int l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {
				int w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		int ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

int go(int start) {
	visited[start] = 1;
	int leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			int l = go(p.first);
			leaf += l;
			edges.push_back(p.second*l);
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n, s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(edges.begin(), edges.end(), comp);
		int ref = accumulate(edges.begin(), edges.end(), 0);
		int count = 0;
		while (ref > s) {
			auto mx = max_element(edges.begin(), edges.end());
			auto i = distance(edges.begin(), mx);
			edges[i] /= 2;
			if (edges[i] % 2 == 1)
			{
				ref--;
			}
			ref -= edges[i];
			count++;
		}
		cout << count << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<ll> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start) {
	visited[start] = 1;
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			ll l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		ll i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll long long

vector<vector<pair<int, int>>> g;
vector<ll> gain;
vector<ll> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start, int parent) {
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (p.first!=parent)
		{
			ll l = go(p.first,start);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l*1ll);
			while (w) {

				ll w2 = floor(w*1ll / 2.0);
				gain.push_back((w - w2)*l*1ll);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0,-1);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

vector<vector<pair<int, int>>> g;
vector<int> visited;
vector<int> gain;
vector<int> edges;

bool comp(int x, int y) {
	return x > y;
}

int go(int start) {
	visited[start] = 1;
	int leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (visited[p.first] == 0)
		{
			int l = go(p.first);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w > 1) {
				int w2 = floor(w / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n, s;
		cin >> n >> s;

		visited = vector<int>(n);
		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0);
		sort(gain.begin(), gain.end(), comp);
		int ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
using namespace std;

#define ll int64_t

vector<vector<pair<int, int>>> g;
vector<ll> gain;
vector<ll> edges;

bool comp(int x, int y) {
	return x > y;
}

ll go(int start, int parent) {
	ll leaf = 0;
	for (pair<int, int> p : g[start])
	{
		if (p.first!=parent)
		{
			ll l = go(p.first,start);
			leaf += l;
			int w = p.second;
			edges.push_back(w*l);
			while (w) {

				ll w2 = floor(w* / 2.0);
				gain.push_back((w - w2)*l);
				w = w2;
			}
		}
	}
	if (leaf == 0)
	{
		leaf = 1;
	}
	return leaf;
}

int main()
{
	int t;
	cin >> t;
	while (t--) {
		int n;
		ll s;
		cin >> n >> s;

		g = vector<vector<pair<int, int>>>(n);
		gain.clear();
		edges.clear();

		for (int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			u--;
			v--;
			g[u].push_back({ v,w });
			g[v].push_back({ u,w });
		}
		go(0,-1);
		sort(gain.begin(), gain.end(), comp);
		ll ref = accumulate(edges.begin(), edges.end(), 0);
		int i = 0;
		while (ref > s)
		{
			ref -= gain[i];
			i++;
		}
		cout << i << endl;
	}
	return 0;
}


// Problem : E1. Weights Division (easy version)
// Contest : Codeforces - Codeforces Round #661 (Div. 3)
// URL : https://codeforces.com/contest/1399/problem/E1
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;

#define endl                    '\n'
#define rep()                   for(LL i = 0 ; i < n ; i++)
#define f(i,s,n)                for(LL i = s ; i < n ; i++)
#define fe(i,s,n)               for(LL i = s ; i <= n ; i++)
#define rfe(i,s,n)              for(LL i = s ; i >= n ; i--)
#define auto(m)                 for(auto &it:m)
#define f2(it,v)                for(it = v.begin(); it != v.end(); ++it)
#define fori(it, x)             for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define ip(n,a)                 LL n;cin>>n;LL a[n];rep(){cin>>a[i];}
#define op(n,a)                 f(i,0,n){cout<<a[i]<<" ";}cout<<endl;
#define i2p(n,k,a)              LL n,k;cin>>n>>k;LL a[n];rep{cin>>a[i];}
#define TCs(x)                  LL x; cin>>x; while(x--)
#define TC(x)                   LL x=1; while(x--)
#define mp                      make_pair
#define pb                      push_back
#define ff                      first
#define ss                      second
#define all(v)                  v.begin(), v.end()
#define mem(a,x)                memset(a,x,sizeof(a))
#define Max(x,y,z)              max(x,max(y,z))
#define Min(x,y,z)              min(x,min(y,z))
#define fastIO                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define ps(x)                   std::cout << std::fixed; std::cout << std::setprecision(x);
#define clz(a)                  __builtin_clz(a) // count leading zeroes (geeksforgeeks.org/builtin-functions-gcc-compiler/)
#define ctz(a)                  __builtin_ctz(a) // count trailing zeroes
#define popc(a)                 __builtin_popcount(a) // count set bits (for ints only diff for ll)
#define GCD(A,B)                __gcd(A,B)
#define d1(x)                   cout<<#x<<": "<<x<<endl
#define d2(x, y)                cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define d3(x, y, z)             cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define d4(a, b, c, d)          cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define d5(a, b, c, d, e)       cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define d6(a, b, c, d, e, f)    cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define c1(a);                  LL a;cin>>a;
#define c2(a,b);                LL a,b;cin>>a>>b;
#define c3(a,b,c);              LL a,b,c;cin>>a>>b>>c;
#define c4(a,b,c,d);            LL a,b,c,d;cin>>a>>b>>c>>d;
#define c5(a,b,c,d,e);          LL a,b,c,d,e;cin>>a>>b>>c>>d>>e;
#define c6(a,b,c,d,e,f);        LL a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
#define c(a,n);                 LL a[n];f(i,0,n){cin>>a[i];}
#define ce(a,n);                LL a[n+1];fe(i,1,n){cin>>a[i];}

//Typedefs:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef string                  S;
typedef long long               LL;
typedef long double             LD;
typedef unsigned long long      ULL;
typedef vector<long long>       VL;
typedef vector<VL>              VVL;
typedef vector<string>          VS;
typedef vector<char>            VC;
typedef pair<LL,LL>             PLL;
typedef pair<string,LL>         PSL;
typedef pair<LL,string>         PLS;
typedef pair<char,LL>           PCL;
typedef pair<LL,char>           PLC;
typedef pair<string,string>     PSS;
typedef pair<char,char>         PCC;
typedef vector<PLL>             VPLL;
typedef vector<PSL>             VPSL;
typedef vector<PLS>             VPLS;
typedef vector<PCL>             VPCL;
typedef vector<PLC>             VPLC;
typedef vector<PSS>             VPSS;
typedef vector<PCC>             VPCC;
typedef map<LL,LL>              MLL;
typedef map<string,LL>          MSL;
typedef map<char,LL>            MCL;
typedef map<char,char>          MCC;
typedef set<LL>                 SL;
typedef set<string>             SS;
typedef set<char>               SC;

int power(LL x,LL y)
{
    if (y == 0)
    return 1;
    LL p = power(x, y/2);
    p = (p * p);

    return (y%2 == 0)? p : (x * p);
}
const long long N=(long long)(1e5+1);
const long long N2=(long long)(1e6+1);
const long long MOD=(long long)(1e9+7);
const long long INF=(long long)(2e18);
map<LL,vector<PLL> > adj;
bool vis[N];
LL depth[N];
LL leaf[N];
void dfs(LL n,LL p){
	vis[n]=true;
	depth[n]=depth[p]+1;
	//VPLL v=adj[n].ss;
	//if(v.size()==0){
	//	leaf[n]=1;
	//}
	//else{
		LL f=0;
		for(auto it:adj[n]){
			if(!vis[it.ff]){
				f=1;
				dfs(it.ff,n);
				leaf[n]+=leaf[it.ff];
			}
		}
		if(f==0){
			leaf[n]=1;
		}
	//}
}
/*struct comp{
    constexpr bool operator()(pair<LL, PLL> const& a,pair<LL, PLL> const& b)
        const noexcept
        {
        	if(a.ff==b.ff){
        		if(a.ss.ff%2!=b.ss.ff%2){
        			return a.ss.ff%2 < b.ss.ff%2;
        		}
        		else{
        			return a.ss.ff > b.ss.ff;
        		}
        	}
        	else{
        		return a.ff < b.ff;
        	}
        }
};
void showpq(priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> gq)
{
    priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> g = gq;
    while (!g.empty())
    {
        pair<LL,PLL> top=g.top();
	LL x1=top.ff;
	LL x2=top.ss.ff;
	LL x3=top.ss.ss;
	d3(x1,x2,x3);
        g.pop();
    }
    cout << '\n';
}*/
LL impact(LL a,LL b){
	LL sum=a*b;
	a=a/2;
	LL new_sum=a*b;
	LL dif=sum-new_sum;
	return dif;
}
void solve()
{
	LL n,s;
	cin>>n>>s;
	LL q=n-1;
	while(q--){
		LL x,y,z;
		cin>>x>>y>>z;
		adj[x].pb(mp(y,z));
		adj[y].pb(mp(x,z));
	}
	/*fe(i,1,n){
		cout<<i<<": ";
		for(auto it:adj[i]){
			cout<<"("<<it.ff<<","<<it.ss<<") ";
		}
		cout<<endl;

	}*/
	dfs(1,0);
	//fe(i,1,n){
	//	d3(i,depth[i],leaf[i]);
	//}
	//priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> pq,pq2;
	priority_queue<pair<LL,PLL> > pq;
	LL sum=0;
	fe(i,1,n){
		for(auto it:adj[i]){
			if(depth[it.ff]<depth[i]){
				LL x=leaf[i]*it.ss;
				sum+=x;
				LL y=impact(it.ss,leaf[i]);
				pq.push(mp(y,mp(it.ss,leaf[i])));
				//pq2.push(mp(x,mp(it.ss,leaf[i])));
			}
		}
	}
	//while(!pq2.empty()){
	//	pair<LL,PLL> top=pq2.top();
	//	LL x1=top.ff;
	//	LL x2=top.ss.ff;
	//	LL x3=top.ss.ss;
	//	d3(x1,x2,x3);
	//	pq2.pop();
	//}
	//cout<<endl;
	//d1(sum);
	LL ans=0;
	while(sum>s){
		pair<LL,PLL> top=pq.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		x2=x2/2;
		//LL z=x2*x3;
		//sum-=x1;
		//sum+=z;
		sum-=x1;
		LL z=impact(x2,x3);
		pq.pop();
		pq.push(mp(z,mp(x2,x3)));
		ans++;
		//pair<LL,PLL> top1=pq.top();
		//LL y1=top1.ff;
		//LL y2=top1.ss.ff;
		//LL y3=top1.ss.ss;
		//d2(sum,ans);
		//showpq(pq);
	}
	cout<<ans<<endl;
	adj.clear();
	f(i,0,N){
		vis[i]=false;
		depth[i]=0;
		leaf[i]=0;
	}

}
int main()
{
        fastIO
        LL t;
        cin>>t;
        LL ff=0;
        if(t==20000 && ff==1){
        	MLL mn;
        	fe(i,1,t){
        		LL n,s;
        		cin>>n>>s;

        		mn[n]++;
        		LL q=n-1;
        		while(q--){
        			LL x,y,z;
        			cin>>x>>y>>z;
        		}
        	}
        	auto(mn){
        		cout<<it.ff<<" "<<it.ss<<endl;
        	}
        }
        else{
        	if(t==20000){
        		ff=1;
        	}
        	while(t--){
        		solve();
        	}
        }
        return 0;
}


// Problem : E1. Weights Division (easy version)
// Contest : Codeforces - Codeforces Round #661 (Div. 3)
// URL : https://codeforces.com/contest/1399/problem/E1
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;

#define endl                    '\n'
#define rep()                   for(LL i = 0 ; i < n ; i++)
#define f(i,s,n)                for(LL i = s ; i < n ; i++)
#define fe(i,s,n)               for(LL i = s ; i <= n ; i++)
#define rfe(i,s,n)              for(LL i = s ; i >= n ; i--)
#define auto(m)                 for(auto &it:m)
#define f2(it,v)                for(it = v.begin(); it != v.end(); ++it)
#define fori(it, x)             for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define ip(n,a)                 LL n;cin>>n;LL a[n];rep(){cin>>a[i];}
#define op(n,a)                 f(i,0,n){cout<<a[i]<<" ";}cout<<endl;
#define i2p(n,k,a)              LL n,k;cin>>n>>k;LL a[n];rep{cin>>a[i];}
#define TCs(x)                  LL x; cin>>x; while(x--)
#define TC(x)                   LL x=1; while(x--)
#define mp                      make_pair
#define pb                      push_back
#define ff                      first
#define ss                      second
#define all(v)                  v.begin(), v.end()
#define mem(a,x)                memset(a,x,sizeof(a))
#define Max(x,y,z)              max(x,max(y,z))
#define Min(x,y,z)              min(x,min(y,z))
#define fastIO                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define ps(x)                   std::cout << std::fixed; std::cout << std::setprecision(x);
#define clz(a)                  __builtin_clz(a) // count leading zeroes (geeksforgeeks.org/builtin-functions-gcc-compiler/)
#define ctz(a)                  __builtin_ctz(a) // count trailing zeroes
#define popc(a)                 __builtin_popcount(a) // count set bits (for ints only diff for ll)
#define GCD(A,B)                __gcd(A,B)
#define d1(x)                   cout<<#x<<": "<<x<<endl
#define d2(x, y)                cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define d3(x, y, z)             cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define d4(a, b, c, d)          cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define d5(a, b, c, d, e)       cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define d6(a, b, c, d, e, f)    cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define c1(a);                  LL a;cin>>a;
#define c2(a,b);                LL a,b;cin>>a>>b;
#define c3(a,b,c);              LL a,b,c;cin>>a>>b>>c;
#define c4(a,b,c,d);            LL a,b,c,d;cin>>a>>b>>c>>d;
#define c5(a,b,c,d,e);          LL a,b,c,d,e;cin>>a>>b>>c>>d>>e;
#define c6(a,b,c,d,e,f);        LL a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
#define c(a,n);                 LL a[n];f(i,0,n){cin>>a[i];}
#define ce(a,n);                LL a[n+1];fe(i,1,n){cin>>a[i];}

//Typedefs:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef string                  S;
typedef long long               LL;
typedef long double             LD;
typedef unsigned long long      ULL;
typedef vector<long long>       VL;
typedef vector<VL>              VVL;
typedef vector<string>          VS;
typedef vector<char>            VC;
typedef pair<LL,LL>             PLL;
typedef pair<string,LL>         PSL;
typedef pair<LL,string>         PLS;
typedef pair<char,LL>           PCL;
typedef pair<LL,char>           PLC;
typedef pair<string,string>     PSS;
typedef pair<char,char>         PCC;
typedef vector<PLL>             VPLL;
typedef vector<PSL>             VPSL;
typedef vector<PLS>             VPLS;
typedef vector<PCL>             VPCL;
typedef vector<PLC>             VPLC;
typedef vector<PSS>             VPSS;
typedef vector<PCC>             VPCC;
typedef map<LL,LL>              MLL;
typedef map<string,LL>          MSL;
typedef map<char,LL>            MCL;
typedef map<char,char>          MCC;
typedef set<LL>                 SL;
typedef set<string>             SS;
typedef set<char>               SC;

int power(LL x,LL y)
{
    if (y == 0)
    return 1;
    LL p = power(x, y/2);
    p = (p * p);

    return (y%2 == 0)? p : (x * p);
}
const long long N=(long long)(1e5+1);
const long long N2=(long long)(1e6+1);
const long long MOD=(long long)(1e9+7);
const long long INF=(long long)(2e18);
map<LL,vector<PLL> > adj;
bool vis[N];
LL depth[N];
LL leaf[N];
void dfs(LL n,LL p){
	vis[n]=true;
	depth[n]=depth[p]+1;
	//VPLL v=adj[n].ss;
	//if(v.size()==0){
	//	leaf[n]=1;
	//}
	//else{
		LL f=0;
		for(auto it:adj[n]){
			if(!vis[it.ff]){
				f=1;
				dfs(it.ff,n);
				leaf[n]+=leaf[it.ff];
			}
		}
		if(f==0){
			leaf[n]=1;
		}
	//}
}
struct comp{
    constexpr bool operator()(pair<LL, PLL> const& a,pair<LL, PLL> const& b)
        const noexcept
        {
        	if(a.ff==b.ff){
        		if(a.ss.ff%2!=b.ss.ff){
        			return a.ss.ff%2 > b.ss.ff%2;
        		}
        		else{
        			return a.ss.ff < b.ss.ff;
        		}
        	}
        	else{
        		return a.ff > b.ff;
        	}
        }
};
void solve()
{
	LL n,s;
	cin>>n>>s;
	LL q=n-1;
	while(q--){
		LL x,y,z;
		cin>>x>>y>>z;
		adj[x].pb(mp(y,z));
		adj[y].pb(mp(x,z));
	}
	/*fe(i,1,n){
		cout<<i<<": "<<endl;
		for(auto it:adj[i]){
			cout<<it.ff<<" "<<it.ss<<endl;
		}

	}*/
	dfs(1,0);
	fe(i,1,n){
		//d3(i,depth[i],leaf[i]);
	}
	priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> pq,pq2;
	LL sum=0;
	fe(i,1,n){
		for(auto it:adj[i]){
			if(depth[it.ff]<depth[i]){
				LL x=leaf[i]*it.ss;
				sum+=x;
				pq.push(mp(x,mp(it.ss,leaf[i])));
				pq2.push(mp(x,mp(it.ss,leaf[i])));
			}
		}
	}
	while(!pq2.empty()){
		pair<LL,PLL> top=pq2.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		//d3(x1,x2,x3);
		pq2.pop();
	}
	//cout<<endl;
	//d1(sum);
	LL ans=0;
	while(sum>s){
		pair<LL,PLL> top=pq.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		x2=x2/2;
		LL z=x2*x3;
		sum-=x1;
		sum+=z;
		pq.pop();
		pq.push(mp(z,mp(x2,x3)));
		ans++;
		pair<LL,PLL> top1=pq.top();
		LL y1=top1.ff;
		LL y2=top1.ss.ff;
		LL y3=top1.ss.ss;
		//d2(sum,ans);
		//d3(y1,y2,y3);
	}
	cout<<ans<<endl;
	adj.clear();
	f(i,0,N){
		vis[i]=false;
		depth[i]=0;
		leaf[i]=0;
	}

}
int main()
{
        fastIO
        TCs(t){solve();}
        return 0;
}


// Problem : E1. Weights Division (easy version)
// Contest : Codeforces - Codeforces Round #661 (Div. 3)
// URL : https://codeforces.com/contest/1399/problem/E1
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;

#define endl                    '\n'
#define rep()                   for(LL i = 0 ; i < n ; i++)
#define f(i,s,n)                for(LL i = s ; i < n ; i++)
#define fe(i,s,n)               for(LL i = s ; i <= n ; i++)
#define rfe(i,s,n)              for(LL i = s ; i >= n ; i--)
#define auto(m)                 for(auto &it:m)
#define f2(it,v)                for(it = v.begin(); it != v.end(); ++it)
#define fori(it, x)             for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define ip(n,a)                 LL n;cin>>n;LL a[n];rep(){cin>>a[i];}
#define op(n,a)                 f(i,0,n){cout<<a[i]<<" ";}cout<<endl;
#define i2p(n,k,a)              LL n,k;cin>>n>>k;LL a[n];rep{cin>>a[i];}
#define TCs(x)                  LL x; cin>>x; while(x--)
#define TC(x)                   LL x=1; while(x--)
#define mp                      make_pair
#define pb                      push_back
#define ff                      first
#define ss                      second
#define all(v)                  v.begin(), v.end()
#define mem(a,x)                memset(a,x,sizeof(a))
#define Max(x,y,z)              max(x,max(y,z))
#define Min(x,y,z)              min(x,min(y,z))
#define fastIO                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define ps(x)                   std::cout << std::fixed; std::cout << std::setprecision(x);
#define clz(a)                  __builtin_clz(a) // count leading zeroes (geeksforgeeks.org/builtin-functions-gcc-compiler/)
#define ctz(a)                  __builtin_ctz(a) // count trailing zeroes
#define popc(a)                 __builtin_popcount(a) // count set bits (for ints only diff for ll)
#define GCD(A,B)                __gcd(A,B)
#define d1(x)                   cout<<#x<<": "<<x<<endl
#define d2(x, y)                cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define d3(x, y, z)             cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define d4(a, b, c, d)          cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define d5(a, b, c, d, e)       cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define d6(a, b, c, d, e, f)    cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define c1(a);                  LL a;cin>>a;
#define c2(a,b);                LL a,b;cin>>a>>b;
#define c3(a,b,c);              LL a,b,c;cin>>a>>b>>c;
#define c4(a,b,c,d);            LL a,b,c,d;cin>>a>>b>>c>>d;
#define c5(a,b,c,d,e);          LL a,b,c,d,e;cin>>a>>b>>c>>d>>e;
#define c6(a,b,c,d,e,f);        LL a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
#define c(a,n);                 LL a[n];f(i,0,n){cin>>a[i];}
#define ce(a,n);                LL a[n+1];fe(i,1,n){cin>>a[i];}

//Typedefs:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef string                  S;
typedef long long               LL;
typedef long double             LD;
typedef unsigned long long      ULL;
typedef vector<long long>       VL;
typedef vector<VL>              VVL;
typedef vector<string>          VS;
typedef vector<char>            VC;
typedef pair<LL,LL>             PLL;
typedef pair<string,LL>         PSL;
typedef pair<LL,string>         PLS;
typedef pair<char,LL>           PCL;
typedef pair<LL,char>           PLC;
typedef pair<string,string>     PSS;
typedef pair<char,char>         PCC;
typedef vector<PLL>             VPLL;
typedef vector<PSL>             VPSL;
typedef vector<PLS>             VPLS;
typedef vector<PCL>             VPCL;
typedef vector<PLC>             VPLC;
typedef vector<PSS>             VPSS;
typedef vector<PCC>             VPCC;
typedef map<LL,LL>              MLL;
typedef map<string,LL>          MSL;
typedef map<char,LL>            MCL;
typedef map<char,char>          MCC;
typedef set<LL>                 SL;
typedef set<string>             SS;
typedef set<char>               SC;

int power(LL x,LL y)
{
    if (y == 0)
    return 1;
    LL p = power(x, y/2);
    p = (p * p);

    return (y%2 == 0)? p : (x * p);
}
const long long N=(long long)(1e5+1);
const long long N2=(long long)(1e6+1);
const long long MOD=(long long)(1e9+7);
const long long INF=(long long)(2e18);
map<LL,vector<PLL> > adj;
bool vis[N];
LL depth[N],leaf[N];
void dfs(LL n,LL p){
	vis[n]=true;
	depth[n]=depth[p]+1;
	LL f=0;
	for(auto it:adj[n]){
		if(!vis[it.ff]){
			f=1;
			dfs(it.ff,n);
			leaf[n]+=leaf[it.ff];
		}
	}
	if(f==0){
		leaf[n]=1;
	}
}
LL impact(LL a,LL b){
	LL sum=a*b;
	a=a/2;
	LL new_sum=a*b;
	LL dif=sum-new_sum;
	return dif;
}
void solve()
{
	LL n,s;
	cin>>n>>s;
	LL q=n-1;
	while(q--){
		LL x,y,z;
		cin>>x>>y>>z;
		adj[x].pb(mp(y,z));
		adj[y].pb(mp(x,z));
	}
	dfs(1,0);    //dfs for updating the depth array & leaf array
	priority_queue<pair<LL,PLL> > pq;
	multiset<pair<LL,PLL> > st;
	LL sum=0;
	fe(i,1,n){
		for(auto it:adj[i]){
			if(depth[it.ff]<depth[i]){	//only considering parent edge
				sum+=leaf[i]*it.ss;	//total value of that edge
				LL y=impact(it.ss,leaf[i]);	//impact produced by each edge
				st.insert(mp(y,mp(it.ss,leaf[i])));
			}
		}
	}
	LL ans=0;
	while(sum>s){
		auto it = st.end();
		it--;
		pair<LL,PLL> last=*it;	//taking the edge with highest impact
		LL x1=last.ff;
		LL x2=last.ss.ff;
		LL x3=last.ss.ss;
		x2=x2/2;
		sum-=x1;
		LL z=impact(x2,x3);	//again calculating the impact with new edge
		st.erase(last);
		st.insert(mp(z,mp(x2,x3)));
		ans++;
	}
	cout<<ans<<endl;
	adj.clear();
	f(i,0,N){
		vis[i]=false;
		depth[i]=0;
		leaf[i]=0;
	}
}
int main()
{
        fastIO
        TCs(t){solve();}
        return 0;
}


// Problem : E1. Weights Division (easy version)
// Contest : Codeforces - Codeforces Round #661 (Div. 3)
// URL : https://codeforces.com/contest/1399/problem/E1
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;

#define endl                    '\n'
#define rep()                   for(LL i = 0 ; i < n ; i++)
#define f(i,s,n)                for(LL i = s ; i < n ; i++)
#define fe(i,s,n)               for(LL i = s ; i <= n ; i++)
#define rfe(i,s,n)              for(LL i = s ; i >= n ; i--)
#define auto(m)                 for(auto &it:m)
#define f2(it,v)                for(it = v.begin(); it != v.end(); ++it)
#define fori(it, x)             for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define ip(n,a)                 LL n;cin>>n;LL a[n];rep(){cin>>a[i];}
#define op(n,a)                 f(i,0,n){cout<<a[i]<<" ";}cout<<endl;
#define i2p(n,k,a)              LL n,k;cin>>n>>k;LL a[n];rep{cin>>a[i];}
#define TCs(x)                  LL x; cin>>x; while(x--)
#define TC(x)                   LL x=1; while(x--)
#define mp                      make_pair
#define pb                      push_back
#define ff                      first
#define ss                      second
#define all(v)                  v.begin(), v.end()
#define mem(a,x)                memset(a,x,sizeof(a))
#define Max(x,y,z)              max(x,max(y,z))
#define Min(x,y,z)              min(x,min(y,z))
#define fastIO                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define ps(x)                   std::cout << std::fixed; std::cout << std::setprecision(x);
#define clz(a)                  __builtin_clz(a) // count leading zeroes (geeksforgeeks.org/builtin-functions-gcc-compiler/)
#define ctz(a)                  __builtin_ctz(a) // count trailing zeroes
#define popc(a)                 __builtin_popcount(a) // count set bits (for ints only diff for ll)
#define GCD(A,B)                __gcd(A,B)
#define d1(x)                   cout<<#x<<": "<<x<<endl
#define d2(x, y)                cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define d3(x, y, z)             cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define d4(a, b, c, d)          cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define d5(a, b, c, d, e)       cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define d6(a, b, c, d, e, f)    cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define c1(a);                  LL a;cin>>a;
#define c2(a,b);                LL a,b;cin>>a>>b;
#define c3(a,b,c);              LL a,b,c;cin>>a>>b>>c;
#define c4(a,b,c,d);            LL a,b,c,d;cin>>a>>b>>c>>d;
#define c5(a,b,c,d,e);          LL a,b,c,d,e;cin>>a>>b>>c>>d>>e;
#define c6(a,b,c,d,e,f);        LL a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
#define c(a,n);                 LL a[n];f(i,0,n){cin>>a[i];}
#define ce(a,n);                LL a[n+1];fe(i,1,n){cin>>a[i];}

//Typedefs:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef string                  S;
typedef long long               LL;
typedef long double             LD;
typedef unsigned long long      ULL;
typedef vector<long long>       VL;
typedef vector<VL>              VVL;
typedef vector<string>          VS;
typedef vector<char>            VC;
typedef pair<LL,LL>             PLL;
typedef pair<string,LL>         PSL;
typedef pair<LL,string>         PLS;
typedef pair<char,LL>           PCL;
typedef pair<LL,char>           PLC;
typedef pair<string,string>     PSS;
typedef pair<char,char>         PCC;
typedef vector<PLL>             VPLL;
typedef vector<PSL>             VPSL;
typedef vector<PLS>             VPLS;
typedef vector<PCL>             VPCL;
typedef vector<PLC>             VPLC;
typedef vector<PSS>             VPSS;
typedef vector<PCC>             VPCC;
typedef map<LL,LL>              MLL;
typedef map<string,LL>          MSL;
typedef map<char,LL>            MCL;
typedef map<char,char>          MCC;
typedef set<LL>                 SL;
typedef set<string>             SS;
typedef set<char>               SC;

int power(LL x,LL y)
{
    if (y == 0)
    return 1;
    LL p = power(x, y/2);
    p = (p * p);

    return (y%2 == 0)? p : (x * p);
}
const long long N=(long long)(1e5+1);
const long long N2=(long long)(1e6+1);
const long long MOD=(long long)(1e9+7);
const long long INF=(long long)(2e18);
map<LL,vector<PLL> > adj;
bool vis[N];
LL depth[N],leaf[N];
void dfs(LL n,LL p){
	vis[n]=true;
	depth[n]=depth[p]+1;
	LL f=0;
	for(auto it:adj[n]){
		if(!vis[it.ff]){
			f=1;
			dfs(it.ff,n);
			leaf[n]+=leaf[it.ff];
		}
	}
	if(f==0){
		leaf[n]=1;
	}
}
LL impact(LL a,LL b){
	LL sum=a*b;
	a=a/2;
	LL new_sum=a*b;
	LL dif=sum-new_sum;
	return dif;
}
void solve()
{
	LL n,s;
	cin>>n>>s;
	LL q=n-1;
	while(q--){
		LL x,y,z;
		cin>>x>>y>>z;
		adj[x].pb(mp(y,z));
		adj[y].pb(mp(x,z));
	}
	dfs(1,0);    //dfs for updating the depth array & leaf array
	priority_queue<pair<LL,PLL> > pq;
	set<pair<LL,PLL> > st;
	LL sum=0;
	fe(i,1,n){
		for(auto it:adj[i]){
			if(depth[it.ff]<depth[i]){	//only considering parent edge
				sum+=leaf[i]*it.ss;	//total value of that edge
				LL y=impact(it.ss,leaf[i]);	//impact produced by each edge
				st.insert(mp(y,mp(it.ss,leaf[i])));
			}
		}
	}
	LL ans=0;
	while(sum>s){
		auto it = st.end();
		it--;
		pair<LL,PLL> last=*it;	//taking the edge with highest impact
		LL x1=last.ff;
		LL x2=last.ss.ff;
		LL x3=last.ss.ss;
		x2=x2/2;
		sum-=x1;
		LL z=impact(x2,x3);	//again calculating the impact with new edge
		st.erase(last);
		st.insert(mp(z,mp(x2,x3)));
		ans++;
	}
	cout<<ans<<endl;
	adj.clear();
	f(i,0,N){
		vis[i]=false;
		depth[i]=0;
		leaf[i]=0;
	}
}
int main()
{
        fastIO
        TCs(t){solve();}
        return 0;
}


// Problem : E1. Weights Division (easy version)
// Contest : Codeforces - Codeforces Round #661 (Div. 3)
// URL : https://codeforces.com/contest/1399/problem/E1
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;

#define endl                    '\n'
#define rep()                   for(LL i = 0 ; i < n ; i++)
#define f(i,s,n)                for(LL i = s ; i < n ; i++)
#define fe(i,s,n)               for(LL i = s ; i <= n ; i++)
#define rfe(i,s,n)              for(LL i = s ; i >= n ; i--)
#define auto(m)                 for(auto &it:m)
#define f2(it,v)                for(it = v.begin(); it != v.end(); ++it)
#define fori(it, x)             for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define ip(n,a)                 LL n;cin>>n;LL a[n];rep(){cin>>a[i];}
#define op(n,a)                 f(i,0,n){cout<<a[i]<<" ";}cout<<endl;
#define i2p(n,k,a)              LL n,k;cin>>n>>k;LL a[n];rep{cin>>a[i];}
#define TCs(x)                  LL x; cin>>x; while(x--)
#define TC(x)                   LL x=1; while(x--)
#define mp                      make_pair
#define pb                      push_back
#define ff                      first
#define ss                      second
#define all(v)                  v.begin(), v.end()
#define mem(a,x)                memset(a,x,sizeof(a))
#define Max(x,y,z)              max(x,max(y,z))
#define Min(x,y,z)              min(x,min(y,z))
#define fastIO                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define ps(x)                   std::cout << std::fixed; std::cout << std::setprecision(x);
#define clz(a)                  __builtin_clz(a) // count leading zeroes (geeksforgeeks.org/builtin-functions-gcc-compiler/)
#define ctz(a)                  __builtin_ctz(a) // count trailing zeroes
#define popc(a)                 __builtin_popcount(a) // count set bits (for ints only diff for ll)
#define GCD(A,B)                __gcd(A,B)
#define d1(x)                   cout<<#x<<": "<<x<<endl
#define d2(x, y)                cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define d3(x, y, z)             cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define d4(a, b, c, d)          cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define d5(a, b, c, d, e)       cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define d6(a, b, c, d, e, f)    cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define c1(a);                  LL a;cin>>a;
#define c2(a,b);                LL a,b;cin>>a>>b;
#define c3(a,b,c);              LL a,b,c;cin>>a>>b>>c;
#define c4(a,b,c,d);            LL a,b,c,d;cin>>a>>b>>c>>d;
#define c5(a,b,c,d,e);          LL a,b,c,d,e;cin>>a>>b>>c>>d>>e;
#define c6(a,b,c,d,e,f);        LL a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
#define c(a,n);                 LL a[n];f(i,0,n){cin>>a[i];}
#define ce(a,n);                LL a[n+1];fe(i,1,n){cin>>a[i];}

//Typedefs:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef string                  S;
typedef long long               LL;
typedef long double             LD;
typedef unsigned long long      ULL;
typedef vector<long long>       VL;
typedef vector<VL>              VVL;
typedef vector<string>          VS;
typedef vector<char>            VC;
typedef pair<LL,LL>             PLL;
typedef pair<string,LL>         PSL;
typedef pair<LL,string>         PLS;
typedef pair<char,LL>           PCL;
typedef pair<LL,char>           PLC;
typedef pair<string,string>     PSS;
typedef pair<char,char>         PCC;
typedef vector<PLL>             VPLL;
typedef vector<PSL>             VPSL;
typedef vector<PLS>             VPLS;
typedef vector<PCL>             VPCL;
typedef vector<PLC>             VPLC;
typedef vector<PSS>             VPSS;
typedef vector<PCC>             VPCC;
typedef map<LL,LL>              MLL;
typedef map<string,LL>          MSL;
typedef map<char,LL>            MCL;
typedef map<char,char>          MCC;
typedef set<LL>                 SL;
typedef set<string>             SS;
typedef set<char>               SC;

int power(LL x,LL y)
{
    if (y == 0)
    return 1;
    LL p = power(x, y/2);
    p = (p * p);

    return (y%2 == 0)? p : (x * p);
}
const long long N=(long long)(1e5+1);
const long long N2=(long long)(1e6+1);
const long long MOD=(long long)(1e9+7);
const long long INF=(long long)(2e18);
map<LL,vector<PLL> > adj;
bool vis[N];
LL depth[N];
LL leaf[N];
void dfs(LL n,LL p){
	vis[n]=true;
	depth[n]=depth[p]+1;
	//VPLL v=adj[n].ss;
	//if(v.size()==0){
	//	leaf[n]=1;
	//}
	//else{
		LL f=0;
		for(auto it:adj[n]){
			if(!vis[it.ff]){
				f=1;
				dfs(it.ff,n);
				leaf[n]+=leaf[it.ff];
			}
		}
		if(f==0){
			leaf[n]=1;
		}
	//}
}
struct comp{
    constexpr bool operator()(pair<LL, PLL> const& a,pair<LL, PLL> const& b)
        const noexcept
        {
        	if(a.ff==b.ff){
        		if(a.ss.ff%2!=b.ss.ff%2){
        			return a.ss.ff%2 < b.ss.ff%2;
        		}
        		else{
        			return a.ss.ff > b.ss.ff;
        		}
        	}
        	else{
        		return a.ff < b.ff;
        	}
        }
};
void showpq(priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> gq)
{
    priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> g = gq;
    while (!g.empty())
    {
        pair<LL,PLL> top=g.top();
	LL x1=top.ff;
	LL x2=top.ss.ff;
	LL x3=top.ss.ss;
	d3(x1,x2,x3);
        g.pop();
    }
    cout << '\n';
}
void solve()
{
	LL n,s;
	cin>>n>>s;
	LL q=n-1;
	while(q--){
		LL x,y,z;
		cin>>x>>y>>z;
		adj[x].pb(mp(y,z));
		adj[y].pb(mp(x,z));
	}
	/*fe(i,1,n){
		cout<<i<<": "<<endl;
		for(auto it:adj[i]){
			cout<<it.ff<<" "<<it.ss<<endl;
		}

	}*/
	dfs(1,0);
	fe(i,1,n){
		//d3(i,depth[i],leaf[i]);
	}
	priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> pq,pq2;
	LL sum=0;
	fe(i,1,n){
		for(auto it:adj[i]){
			if(depth[it.ff]<depth[i]){
				LL x=leaf[i]*it.ss;
				sum+=x;
				pq.push(mp(x,mp(it.ss,leaf[i])));
				pq2.push(mp(x,mp(it.ss,leaf[i])));
			}
		}
	}
	while(!pq2.empty()){
		pair<LL,PLL> top=pq2.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		d3(x1,x2,x3);
		pq2.pop();
	}
	//cout<<endl;
	d1(sum);
	LL ans=0;
	while(sum>s){
		pair<LL,PLL> top=pq.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		x2=x2/2;
		LL z=x2*x3;
		sum-=x1;
		sum+=z;
		pq.pop();
		pq.push(mp(z,mp(x2,x3)));
		ans++;
		pair<LL,PLL> top1=pq.top();
		LL y1=top1.ff;
		LL y2=top1.ss.ff;
		LL y3=top1.ss.ss;
		d2(sum,ans);
		showpq(pq);
	}
	cout<<ans<<endl;
	adj.clear();
	f(i,0,N){
		vis[i]=false;
		depth[i]=0;
		leaf[i]=0;
	}

}
int main()
{
        fastIO
        TCs(t){solve();}
        return 0;
}


// Problem : E1. Weights Division (easy version)
// Contest : Codeforces - Codeforces Round #661 (Div. 3)
// URL : https://codeforces.com/contest/1399/problem/E1
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;

#define endl                    '\n'
#define rep()                   for(LL i = 0 ; i < n ; i++)
#define f(i,s,n)                for(LL i = s ; i < n ; i++)
#define fe(i,s,n)               for(LL i = s ; i <= n ; i++)
#define rfe(i,s,n)              for(LL i = s ; i >= n ; i--)
#define auto(m)                 for(auto &it:m)
#define f2(it,v)                for(it = v.begin(); it != v.end(); ++it)
#define fori(it, x)             for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define ip(n,a)                 LL n;cin>>n;LL a[n];rep(){cin>>a[i];}
#define op(n,a)                 f(i,0,n){cout<<a[i]<<" ";}cout<<endl;
#define i2p(n,k,a)              LL n,k;cin>>n>>k;LL a[n];rep{cin>>a[i];}
#define TCs(x)                  LL x; cin>>x; while(x--)
#define TC(x)                   LL x=1; while(x--)
#define mp                      make_pair
#define pb                      push_back
#define ff                      first
#define ss                      second
#define all(v)                  v.begin(), v.end()
#define mem(a,x)                memset(a,x,sizeof(a))
#define Max(x,y,z)              max(x,max(y,z))
#define Min(x,y,z)              min(x,min(y,z))
#define fastIO                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define ps(x)                   std::cout << std::fixed; std::cout << std::setprecision(x);
#define clz(a)                  __builtin_clz(a) // count leading zeroes (geeksforgeeks.org/builtin-functions-gcc-compiler/)
#define ctz(a)                  __builtin_ctz(a) // count trailing zeroes
#define popc(a)                 __builtin_popcount(a) // count set bits (for ints only diff for ll)
#define GCD(A,B)                __gcd(A,B)
#define d1(x)                   cout<<#x<<": "<<x<<endl
#define d2(x, y)                cout<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define d3(x, y, z)             cout<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define d4(a, b, c, d)          cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define d5(a, b, c, d, e)       cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define d6(a, b, c, d, e, f)    cout<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define c1(a);                  LL a;cin>>a;
#define c2(a,b);                LL a,b;cin>>a>>b;
#define c3(a,b,c);              LL a,b,c;cin>>a>>b>>c;
#define c4(a,b,c,d);            LL a,b,c,d;cin>>a>>b>>c>>d;
#define c5(a,b,c,d,e);          LL a,b,c,d,e;cin>>a>>b>>c>>d>>e;
#define c6(a,b,c,d,e,f);        LL a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
#define c(a,n);                 LL a[n];f(i,0,n){cin>>a[i];}
#define ce(a,n);                LL a[n+1];fe(i,1,n){cin>>a[i];}

//Typedefs:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef string                  S;
typedef long long               LL;
typedef long double             LD;
typedef unsigned long long      ULL;
typedef vector<long long>       VL;
typedef vector<VL>              VVL;
typedef vector<string>          VS;
typedef vector<char>            VC;
typedef pair<LL,LL>             PLL;
typedef pair<string,LL>         PSL;
typedef pair<LL,string>         PLS;
typedef pair<char,LL>           PCL;
typedef pair<LL,char>           PLC;
typedef pair<string,string>     PSS;
typedef pair<char,char>         PCC;
typedef vector<PLL>             VPLL;
typedef vector<PSL>             VPSL;
typedef vector<PLS>             VPLS;
typedef vector<PCL>             VPCL;
typedef vector<PLC>             VPLC;
typedef vector<PSS>             VPSS;
typedef vector<PCC>             VPCC;
typedef map<LL,LL>              MLL;
typedef map<string,LL>          MSL;
typedef map<char,LL>            MCL;
typedef map<char,char>          MCC;
typedef set<LL>                 SL;
typedef set<string>             SS;
typedef set<char>               SC;

int power(LL x,LL y)
{
    if (y == 0)
    return 1;
    LL p = power(x, y/2);
    p = (p * p);

    return (y%2 == 0)? p : (x * p);
}
const long long N=(long long)(1e5+1);
const long long N2=(long long)(1e6+1);
const long long MOD=(long long)(1e9+7);
const long long INF=(long long)(2e18);
map<LL,vector<PLL> > adj;
bool vis[N];
LL depth[N];
LL leaf[N];
void dfs(LL n,LL p){
	vis[n]=true;
	depth[n]=depth[p]+1;
	//VPLL v=adj[n].ss;
	//if(v.size()==0){
	//	leaf[n]=1;
	//}
	//else{
		LL f=0;
		for(auto it:adj[n]){
			if(!vis[it.ff]){
				f=1;
				dfs(it.ff,n);
				leaf[n]+=leaf[it.ff];
			}
		}
		if(f==0){
			leaf[n]=1;
		}
	//}
}
struct comp{
    constexpr bool operator()(pair<LL, PLL> const& a,pair<LL, PLL> const& b)
        const noexcept
        {
        	if(a.ff==b.ff){
        		if(a.ss.ff%2!=b.ss.ff){
        			return a.ss.ff%2 < b.ss.ff%2;
        		}
        		else{
        			return a.ss.ff < b.ss.ff;
        		}
        	}
        	else{
        		return a.ff < b.ff;
        	}
        }
};
void solve()
{
	LL n,s;
	cin>>n>>s;
	LL q=n-1;
	while(q--){
		LL x,y,z;
		cin>>x>>y>>z;
		adj[x].pb(mp(y,z));
		adj[y].pb(mp(x,z));
	}
	/*fe(i,1,n){
		cout<<i<<": "<<endl;
		for(auto it:adj[i]){
			cout<<it.ff<<" "<<it.ss<<endl;
		}

	}*/
	dfs(1,0);
	fe(i,1,n){
		//d3(i,depth[i],leaf[i]);
	}
	priority_queue<pair<LL,PLL> ,vector<pair<LL,PLL>>,comp> pq,pq2;
	LL sum=0;
	fe(i,1,n){
		for(auto it:adj[i]){
			if(depth[it.ff]<depth[i]){
				LL x=leaf[i]*it.ss;
				sum+=x;
				pq.push(mp(x,mp(it.ss,leaf[i])));
				pq2.push(mp(x,mp(it.ss,leaf[i])));
			}
		}
	}
	while(!pq2.empty()){
		pair<LL,PLL> top=pq2.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		//d3(x1,x2,x3);
		pq2.pop();
	}
	//cout<<endl;
	//d1(sum);
	LL ans=0;
	while(sum>s){
		pair<LL,PLL> top=pq.top();
		LL x1=top.ff;
		LL x2=top.ss.ff;
		LL x3=top.ss.ss;
		x2=x2/2;
		LL z=x2*x3;
		sum-=x1;
		sum+=z;
		pq.pop();
		pq.push(mp(z,mp(x2,x3)));
		ans++;
		pair<LL,PLL> top1=pq.top();
		LL y1=top1.ff;
		LL y2=top1.ss.ff;
		LL y3=top1.ss.ss;
		//d2(sum,ans);
		//d3(y1,y2,y3);
	}
	cout<<ans<<endl;
	adj.clear();
	f(i,0,N){
		vis[i]=false;
		depth[i]=0;
		leaf[i]=0;
	}

}
int main()
{
        fastIO
        TCs(t){solve();}
        return 0;
}