#include <bits/stdc++.h>
using namespace std;
const int dbg = 0;
struct FatalMessage {
  FatalMessage(const char* file, int line, const char* cond) {
    std::cerr << file << " L" << line << " failed: " << cond << ". ";
  }
  ~FatalMessage() {
    std::cerr << std::endl;
    std::terminate();
  }
};
template <typename T>
const FatalMessage& operator<<(const FatalMessage& s, const T& t) {
  std::cerr << t;
  return s;
}
template <typename C>
void SortAndUniq(C& c) {
  sort(c.begin(), c.end());
  c.erase(unique(c.begin(), c.end()), c.end());
}
struct Tree {
  int N, root;
  vector<vector<int>> sons;
  vector<int> fa, ord, rev_ord;
  void AddEdge(int a, int b) {
    sons[a].push_back(b);
    sons[b].push_back(a);
  }
  void MakeRooted(int _root) {
    root = _root;
    fa.assign(N, -2);
    ord.clear();
    fa[root] = -1;
    ord.push_back(root);
    for (int i = 0; i < ord.size(); ++i) {
      int u = ord[i];
      if (fa[u] != -1) {
        auto iter = find(sons[u].begin(), sons[u].end(), fa[u]);
        sons[u].erase(iter);
      }
      for (int v : sons[u]) {
        fa[v] = u;
        ord.push_back(v);
      }
    }
    rev_ord = ord;
    reverse(rev_ord.begin(), rev_ord.end());
  }
  void Read(istream& in) {
    in >> N;
    sons.clear();
    sons.resize(N);
    for (int i = 1; i < N; ++i) {
      int a, b;
      in >> a >> b;
      AddEdge(a - 1, b - 1);
    }
  }
};
using vii = vector<pair<long long, long long>>;
void Combine(const vii& a, const vii& b, vii& r) {
  r.assign(a.size() + b.size() - 1, {-1, -1});
  for (int i = 0; i < a.size(); ++i) {
    for (int j = 0; j < b.size(); ++j) {
      auto t = a[i];
      t.first += b[j].first;
      t.second += b[j].second;
      r[i + j] = max(r[i + j], t);
    }
  }
}
int Solve() {
  int N, M;
  cin >> N >> M;
  vector<int> B(N), W(N);
  for (int& x : B) {
    cin >> x;
  }
  for (int& x : W) {
    cin >> x;
  }
  Tree tree;
  tree.N = N;
  tree.sons.resize(N);
  for (int i = 1; i < N; ++i) {
    int a, b;
    cin >> a >> b;
    tree.AddEdge(a - 1, b - 1);
  }
  tree.MakeRooted(0);
  vector<int> stsize(N, 1);
  for (int u : tree.rev_ord) {
    for (int v : tree.sons[u]) {
      stsize[u] += stsize[v];
    }
  }
  vector<vector<long long>> F(N);
  vector<vector<pair<long long, long long>>> G(N);
  vector<pair<long long, long long>> G0, G1;
  vector<int> sons;
  for (int u : tree.rev_ord) {
    long long d = W[u] - B[u];
    auto sons = tree.sons[u];
    sort(sons.begin(), sons.end(),
         [&stsize](int a, int b) { return stsize[a] > stsize[b]; });
    if (sons.empty()) {
      G[u] = {{0, d}, {d > 0 ? 1 : 0, 0}};
    } else {
      G1 = {{0, 0}};
      while (!sons.empty()) {
        int v = sons.back();
        sons.pop_back();
        Combine(G1, G[v], G0);
        swap(G0, G1);
      }
      auto& Gu = G[u];
      Gu.assign(G1.size() + 1, {-1, -1});
      for (int i = 0; i < G1.size(); ++i) {
        auto t = G1[i];
        t.second += d;
        Gu[i] = max(Gu[i], t);
        if (t.second > 0) {
          ++t.first;
        }
        t.second = 0;
        Gu[i + 1] = max(Gu[i + 1], t);
      }
    }
    F[u].resize(G[u].size(), 0);
    for (int i = 0; i + 1 < G[u].size(); ++i) {
      F[u][i + 1] = G[u][i].first + (G[u][i].second > 0 ? 1 : 0);
    }
  }
  if (dbg) {
    for (int u = 0; u < N; ++u) {
      cerr << "G[" << u << "]:";
      for (int i = 0; i < G[u].size(); ++i) {
        cerr << "  " << i << ':' << G[u][i].first << '/' << G[u][i].second;
      }
      cerr << '\n';
    }
  }
  return F[0][M];
}
int main() {
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  int T;
  for (cin >> T; T--;) {
    cout << Solve() << '\n';
  }
}
