#include <bits/stdc++.h>
template <class C>
inline void log_c(const C& c) {}
template <class C>
inline int sz(const C& c) {
  return static_cast<int>(c.size());
}
using namespace std;
using pii = pair<int, int>;
using num = int64_t;
using pll = pair<num, num>;
using pli = pair<num, int>;
const std::string eol = "\n";
using t4i = tuple<int, int, int, int>;
vector<t4i> edges;
vector<vector<int>> adj;
priority_queue<tuple<int64_t, int, int>> q[2];
int leaf_count(int p, int peidx, int64_t& s) {
  int cnt = 0;
  for (int eidx : adj[p])
    if (eidx != peidx) {
      auto [u, v, w, cost] = edges[eidx];
      if (u != p) swap(u, v);
      int c = leaf_count(v, eidx, s);
      cnt += c;
      int64_t ewt = static_cast<int64_t>(c) * w;
      int64_t nwt = static_cast<int64_t>(c) * (w / 2);
      if (w) {
        q[cost - 1].emplace(ewt - nwt, c, w);
      }
      s += ewt;
    }
  if (sz(adj[p]) <= 1) {
    ++cnt;
  }
  return cnt;
}
int main() {
  std::ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int test_sample_count;
  cin >> test_sample_count;
  vector<int64_t> p[2];
  while (test_sample_count--) {
    int n;
    cin >> n;
    int64_t s;
    cin >> s;
    edges.clear();
    adj.clear();
    adj.resize(n);
    for (int k = 0; k < (2); ++k)
      while (!q[k].empty()) q[k].pop();
    for (int k = 0; k < (n - 1); ++k) {
      int u, v, w, c;
      cin >> u >> v >> w >> c;
      --u, --v;
      adj[u].push_back(sz(edges));
      adj[v].push_back(sz(edges));
      edges.emplace_back(u, v, w, c);
    }
    int64_t sum = 0;
    leaf_count(0, -1, sum);
    const int64_t target_diff = sum - s;
    for (int bucket = 0; bucket < 2; ++bucket) {
      auto& qx = q[bucket];
      auto& px = p[bucket];
      px.clear();
      for (int64_t diff = 0; !qx.empty() && diff < target_diff;) {
        auto [wt, c, w] = qx.top();
        qx.pop();
        px.push_back(wt);
        diff += wt;
        w /= 2;
        if (w > 0) {
          qx.emplace(int64_t((w + 1) / 2) * c, c, w);
        }
      }
      sort(begin(px), end(px));
      px.push_back(0);
      partial_sum(px.rbegin(), px.rend(), px.rbegin());
    }
    int ans = 1000000000;
    int k1 = 0;
    for (int k2 = sz(p[1]) - 1; k2 >= 0; --k2) {
      for (; k1 < sz(p[0]) - 1 && p[0][k1 + 1] >= target_diff - p[1][k2];
           ++k1) {
      }
      if (p[0][k1] >= target_diff - p[1][k2]) {
        ans = min(ans, sz(p[0]) - 1 - k1 + (sz(p[1]) - 1 - k2) * 2);
      }
    }
    cout << ans << eol;
  }
  return 0;
}
