#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;
}