#include<iostream> //#include<fstream> #include<vector> #include<unordered_map> #include<algorithm> #include<vector> #include<cstring> using namespace std; typedef int var; #define fin cin #define fout cout //ifstream fin("date.in"); //ofstream fout("date.out"); #define MAXN 20002 #define MAXNLOGN 20 var n, m; vector<var> G[MAXN]; var SPEC[MAXN], SERV[MAXN]; vector<var> EULER(1), DEPTH(1); var BEG[MAXN], D[MAXN], LOG[MAXN]; var RMQ[MAXNLOGN][MAXN], SOL[MAXNLOGN][MAXN]; struct Edge { var n, c; Edge(var a, var b) { n = a; c = b; } }; vector<Edge> Gr[MAXN]; void euler(var node) { BEG[node] = EULER.size(); EULER.push_back(node); DEPTH.push_back(D[node]); for(auto vec : G[node]) { if(!BEG[vec]) { D[vec] = D[node] + 1; euler(vec); EULER.push_back(node); DEPTH.push_back(D[node]); } } } void build_log_table(var maxx) { for(var i=2; i<=maxx; i++) { LOG[i] = LOG[i/2] + 1; } } void build_lookup_table(var maxx) { for(var i=1; i<=maxx; i++) { RMQ[0][i] = DEPTH[i]; SOL[0][i] = EULER[i]; } for(var i=1; (1<<i) <= maxx; i++) { for(var j=1; j + (1<<i) - 1 <= maxx; j++) { if(RMQ[i-1][j] < RMQ[i-1][j + (1 << (i-1))]) { RMQ[i][j] = RMQ[i-1][j]; SOL[i][j] = SOL[i-1][j]; } else { RMQ[i][j] = RMQ[i-1][j + (1 << (i-1))]; SOL[i][j] = SOL[i-1][j + (1 << (i-1))]; } } } } var lca(var a, var b) { a = BEG[a]; b = BEG[b]; if(a > b) swap(a, b); var len = LOG[b-a+1]; if(RMQ[len][a] < RMQ[len][b-(1<<len)+1]) { return SOL[len][a]; } else { return SOL[len][b-(1<<len)+1]; } } var getD(var a, var b) { var lc = lca(a, b); return D[a] + D[b] - 2*D[lc]; } bool VIZ[MAXN], L[MAXN], R[MAXN]; bool pairup(const int i, var cost) { if(VIZ[i]) return false; VIZ[i] = true; for(int t=0; t<Gr[i].size(); t++) { int vec = Gr[i][t].n; if(Gr[i][t].c > cost) continue; if(!R[vec]) { R[vec] = i; L[i] = vec; return true; } } for(int t=0; t<Gr[i].size(); t++) { int vec = Gr[i][t].n; if(Gr[i][t].c > cost) continue; if(pairup(R[vec], cost)) { R[vec] = i; L[i] = vec; return true; } } return false; } bool solve(var cost) { bool ok = 1; memset(L, 0, sizeof(L)); memset(R, 0, sizeof(R)); while(ok) { ok = 0; memset(VIZ, false, sizeof(VIZ)); for(int i=1; i<=n; i++) { if(!L[i]) ok |= pairup(i, cost); } } for(var i=1; i<=m; i++) { if(!R[i]) return false; } return true; } var maxD = -1; int main() { var a, b; fin>>n>>m; for(var i=1; i<=m; i++) { fin>>SPEC[i]; } for(var i=1; i<=m; i++) { fin>>SERV[i]; } for(var i=2; i<=n; i++) { fin>>a>>b; G[a].push_back(b); G[b].push_back(a); } euler(1); build_log_table(3*n+5); build_lookup_table(EULER.size() - 1); for(var i=1; i<=m; i++) { for(var j=1; j<=m; j++) { var d = getD(SPEC[i], SERV[j]); maxD = max(maxD, d); Gr[i].push_back(Edge(j, d)); } } var sol = 0; var i; for(i=1; i<=n; i<<=1); for(i>>=1; i; i>>=1) { if(!solve(sol+i)) sol += i; } while(!solve(sol)) { sol++; } fout<<sol; return 0; }