#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<pair<int, int> > grh[123460];
vector<int> refIdx[123460];
bool attacked[123460];
bool visited[123460];
int checked[123460];
pair<bool, int> dfs(int idx) {
  pair<bool, int> ret(0, 0);
  visited[idx] = 1;
  for (int i = 0; i < (int)grh[idx].size(); i++) {
    int nIdx = grh[idx][i].first;
    if (!visited[nIdx]) {
      pair<bool, int> ret1 = dfs(nIdx);
      if (ret1.first) {
        grh[idx][i].second = 1;
        grh[nIdx][refIdx[idx][i]].second = 1;
      }
      if (ret1.first) {
        ret.first = 1;
        ret.second += ret1.second + 1;
      }
    }
  }
  if (!ret.second && attacked[idx]) return make_pair(1, 0);
  if (!ret.first) ret.second = 0;
  return ret;
}
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));
  while (!q.empty()) {
    pair<int, int> t = q.front();
    q.pop();
    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].first;
      if (!visited[nIdx] && grh[t.first][i].second == 1) {
        q.push(make_pair(nIdx, t.second + 1));
      }
      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;
  bool possible = false;
  while (!q.empty()) {
    pair<int, int> t = q.front();
    q.pop();
    if (checked[t.first]) {
      if (checked[t.first] == t.second + 1) possible = true;
      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].first;
      if (!visited[nIdx] && grh[t.first][i].second == 1) {
        q.push(make_pair(nIdx, t.second + 1));
        parent[nIdx] = t.first;
      }
      visited[nIdx] = 1;
    }
  }
  if (ret.size() == 0 && possible) ret.push_back(make_pair(idx, -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;
}
pair<int, int> getLongestPt(int idx) {
  pair<int, int> ret(0, 0);
  visited[idx] = 1;
  queue<pair<int, int> > q;
  q.push(make_pair(idx, 0));
  while (!q.empty()) {
    pair<int, int> t = q.front();
    if (ret.second < t.second && attacked[t.first]) ret = t;
    q.pop();
    for (int i = 0; i < (int)grh[t.first].size(); i++) {
      int nIdx = grh[t.first][i].first;
      if (!visited[nIdx] && grh[t.first][i].second == 1) {
        q.push(make_pair(nIdx, t.second + 1));
      }
      visited[nIdx] = 1;
    }
  }
  return ret;
}
int main() {
  memset(checked, 0, sizeof(checked));
  memset(attacked, 0, sizeof(attacked));
  cin >> n >> m;
  for (int i = 0; i < (int)n - 1; i++) {
    cin >> a >> b;
    a--;
    b--;
    refIdx[a].push_back(grh[b].size());
    refIdx[b].push_back(grh[a].size());
    grh[a].push_back(make_pair(b, 0));
    grh[b].push_back(make_pair(a, 0));
  }
  int retIdx = 0, maxLen = 0;
  for (int i = 0; i < (int)m; i++) {
    cin >> a;
    attacked[a - 1] = 1;
    retIdx = max(retIdx, a - 1);
  }
  spanning = dfs(a - 1).second;
  memset(visited, 0, sizeof(visited));
  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() == 1 && ys[0].second == -1) {
      retIdx = min(retIdx, ys[0].first);
      continue;
    }
    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);
        }
      }
    }
  }
  cout << retIdx + 1 << endl << spanning * 2 - maxLen << endl;
  return 0;
}
