#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
long long powmod(long long a, long long b) {
  long long res = 1;
  a %= mod;
  for (; b; b >>= 1) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
unsigned long long getGCD(unsigned long long a, unsigned long long b) {
  if (a < b) return getGCD(b, a);
  if (a % b == 0) return b;
  return getGCD(b, a % b);
}
int n, m, a, b, spanning;
vector<int> grh[123460];
bool attacked[123460];
bool visited[123460];
int checked[123460];
vector<pair<int, int> > getLongestOnes(int idx) {
  vector<pair<int, int> > ret;
  visited[idx] = 1;
  queue<pair<int, int> > q;
  q.push(make_pair(idx, 0));
  vector<int> parent(n, -1);
  parent[idx] = idx;
  vector<bool> ckd(n, 0);
  while (!q.empty()) {
    pair<int, int> t = q.front();
    q.pop();
    if (attacked[t.first]) {
      for (int j = t.first; j != parent[j]; j = parent[j]) {
        if (ckd[j]) break;
        ckd[j] = 1;
        spanning++;
      }
    }
    if (ret.empty()) {
      ret.push_back(t);
    } else if (ret[0].second < t.second && attacked[t.first]) {
      ret.clear();
      ret.push_back(t);
    } else if (ret[0].second == t.second && attacked[t.first]) {
      ret.push_back(t);
    }
    for (int i = 0; i < (int)grh[t.first].size(); i++) {
      int nIdx = grh[t.first][i];
      if (!visited[nIdx]) {
        q.push(make_pair(nIdx, t.second + 1));
        parent[nIdx] = t.first;
        visited[nIdx] = 1;
      }
    }
  }
  return ret;
}
vector<pair<int, int> > getLongestOnesPruning(int idx) {
  vector<pair<int, int> > ret;
  if (checked[idx]) return ret;
  visited[idx] = 1;
  queue<pair<int, int> > q;
  q.push(make_pair(idx, 0));
  vector<int> parent(n, -1);
  parent[idx] = idx;
  while (!q.empty()) {
    pair<int, int> t = q.front();
    q.pop();
    if (checked[t.first]) continue;
    if (ret.empty()) {
      ret.push_back(t);
    } else if (ret[0].second < t.second && attacked[t.first]) {
      ret.clear();
      ret.push_back(t);
    } else if (ret[0].second == t.second && attacked[t.first]) {
      ret.push_back(t);
    }
    for (int i = 0; i < (int)grh[t.first].size(); i++) {
      int nIdx = grh[t.first][i];
      if (!visited[nIdx]) {
        q.push(make_pair(nIdx, t.second + 1));
        parent[nIdx] = t.first;
      }
      visited[nIdx] = 1;
    }
  }
  int maxLen = (ret.size()) ? ret[0].second : 0;
  for (int i = 0; i < (int)ret.size(); i++) {
    int idx = ret[i].first;
    int len = maxLen + 1;
    for (int j = idx; j != parent[j]; j = parent[j], len--) {
      checked[j] = len;
    }
  }
  return ret;
}
int main() {
  memset(checked, 0, sizeof(checked));
  memset(attacked, 0, sizeof(attacked));
  scanf("%d%d", &n, &m);
  for (int i = 0; i < (int)n - 1; i++) {
    scanf("%d%d", &a, &b);
    a--;
    b--;
    grh[a].push_back(b);
    grh[b].push_back(a);
  }
  int retIdx = 0, maxLen = 0;
  for (int i = 0; i < (int)m; i++) {
    scanf("%d", &a);
    attacked[a - 1] = 1;
    retIdx = max(retIdx, a - 1);
  }
  vector<pair<int, int> > x = getLongestOnes(a - 1);
  for (int i = 0; i < (int)x.size(); i++) {
    memset(visited, 0, sizeof(visited));
    vector<pair<int, int> > ys = getLongestOnesPruning(x[i].first);
    retIdx = min(retIdx, x[i].first);
    if (ys.size()) {
      if (ys[0].second < maxLen)
        continue;
      else if (ys[0].second >= maxLen) {
        maxLen = ys[0].second;
        retIdx = min(retIdx, x[i].first);
        for (int j = 0; j < (int)ys.size(); j++) {
          pair<int, int> y = ys[j];
          retIdx = min(retIdx, y.first);
        }
      }
    }
  }
  printf("%d\n%d\n", retIdx + 1, spanning * 2 - maxLen);
  return 0;
}
