1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
#include<cstdio>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstring>
#include<set>
#include<assert.h>
using namespace std;
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define FORD(i,a,b) for(int i = a; i >= b; --i)
#define REP(i,n) FOR(i,0,(n)-1)
#define RI(i,n) FOR(i,1,n)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
#define mini(a,b) a=min(a,b)
#define maxi(a,b) a=max(a,b)
bool debug;
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int inf = 1e9 + 5;
const int nax = 5e5 + 5;

bool usuniety[nax];
ll res;
int n,m,a,b;
int lewy[nax], prawy[nax];
vi v[nax];
priority_queue<pii> secik_min_prawy, secik_max_lewy;

void dfs(int x, int f) {
  for (auto w: v[x]) if (w != f) {
    dfs(w, x);
  }
  
  if (x <= m) return;
  
  while (!secik_min_prawy.empty()) secik_min_prawy.pop();
  while (!secik_max_lewy.empty()) secik_max_lewy.pop();
  
  //printf("wierzcholek %d\n",x);
  for (auto w: v[x]) if (w != f) {
    //printf("przedzial %d %d\n",lewy[w], prawy[w]);
    secik_min_prawy.push(mp(-prawy[w], w));
    secik_max_lewy.push(mp(lewy[w], w));
  }
  
  lewy[x] = -1;
  prawy[x] = 1000000;
  
  while (!secik_min_prawy.empty()) {
    int l = secik_min_prawy.top().nd;
    int p = secik_max_lewy.top().nd;
    int lv = prawy[l];
    int pv = lewy[p];
    
    if (pv <= lv) {
      lewy[x] = max(lewy[x], pv);
      prawy[x] = min(prawy[x], lv);
      return;
    } else {
      res += pv - lv;
      lewy[x] = lv;
      prawy[x] = pv;
      usuniety[l] = usuniety[p] = true;
    }
    
    while (!secik_min_prawy.empty() && usuniety[secik_min_prawy.top().nd]) secik_min_prawy.pop();
    while (!secik_max_lewy.empty() && usuniety[secik_max_lewy.top().nd]) secik_max_lewy.pop();
  }
}

/*int psz[nax];

void przypisz(int x, int p, int f) {
  if (p > prawy[x]) p = prawy[x];
  if (p < lewy[x]) p = lewy[x];
  psz[x] = p;

  for (auto w: v[x]) if (w != f) {
    przypisz(w, p, x);
  }
}*/

int main(int argc, char * argv[]) {
	debug = argc > 1;
  scanf("%d%d",&n,&m);
  REP(i,n-1) {
    scanf("%d%d",&a,&b);
    v[a].pb(b);
    v[b].pb(a);
  }
  
  FOR(i,1,m) {
    int x; scanf("%d",&x);
    lewy[i] = prawy[i] = x;
  }
  dfs(n, -1);
  //przypisz(n, lewy[n], -1);
  
  //ll kupa = 0;
  //FOR(i,1,n) for (auto w: v[i]) kupa += abs(psz[i] - psz[w]);
  //kupa /= 2;
  printf("%lld\n",res);
	return 0;
}