7 3
1 4 7
1 2 2
2 3 3
3 4 8
2 5 1
1 6 4
6 7 5
 10 2
1 5
5 3 2
8 4 8
7 6 9
7 10 1
10 1 4
9 5 1
5 8 2
7 2 9
6 5 6
 10 5
4 8 7 5 1
5 1 1
2 7 1
4 3 1
10 9 1
10 1 1
1 8 1
10 7 1
10 3 1
7 6 1
 10 9
9 7 6 10 3 5 2 8 1
9 4 10
10 8 3
3 6 2
5 1 8
5 2 5
1 10 10
6 7 1
9 1 7
1 6 3
 10 5
8 5 2 10 1
3 1 7
5 4 6
10 8 4
6 8 9
7 8 4
9 5 6
8 1 9
2 10 2
9 8 7

3 2
 2 3
 5 1
 0 1
 5 1

#include <bits/stdc++.h>
struct edge {
  int x, dist;
};
std::vector<std::vector<edge>> ad;
std::vector<char> mon;
std::vector<std::array<edge, 2>> dp;
std::vector<edge> par;
std::vector<int> postorder;
template <bool store>
std::array<edge, 2> farthestnode(int x, int parx) {
  std::array<edge, 2> ans{{{-1, -1}, {-1, -1}}};
  if (mon[x]) ans[0] = {x, 0};
  for (auto [y, elen] : ad[x])
    if (y != parx) {
      if (store) par[y] = {x, elen};
      auto [z, dist] = farthestnode<store>(y, x)[0];
      if (dist >= 0) {
        dist += elen;
        if (dist > ans[1].dist) {
          ans[1] = {z, dist};
          if (ans[1].dist > ans[0].dist) std::swap(ans[0], ans[1]);
        }
      }
    }
  if (store) {
    dp[x] = ans;
    postorder.push_back(x);
  }
  return ans;
}
int main() {
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  int n, nmon;
  std::cin >> n >> nmon;
  mon.resize(n);
  for (int z = nmon, x; z--;) {
    std::cin >> x;
    --x;
    mon[x] = true;
  }
  ad.resize(n);
  for (int z = n, u, v, w; --z;) {
    std::cin >> u >> v >> w;
    --u;
    --v;
    ad[u].push_back({v, w});
    ad[v].push_back({u, w});
  }
  int x = farthestnode<false>(0, -1)[0].x;
  dp.resize(n);
  par.resize(n);
  postorder.reserve(n);
  auto [y, diam] = farthestnode<true>(x, -1)[0];
  assert((int)postorder.size() == n);
  assert(mon[x]);
  assert(mon[y]);
  int xb = -1;
  int yb = -1;
  struct st {
    int node, base;
  };
  std::queue<st> sts;
  std::vector<char> visited(n);
  std::vector<int> dx_minus_dy_of(n);
  int dx = diam, dy = 0, node = y;
  while (true) {
    assert(dp[node][0].dist == dy);
    auto const d1 = dp[node][1].dist;
    assert(d1 <= std::min(dx, dy));
    if (dx * 2 <= diam and d1 == dx) {
      if (xb < 0) xb = node;
    }
    if (dy * 2 <= diam and d1 == dy) {
      yb = node;
    }
    dx_minus_dy_of[node] = dx - dy;
    sts.push({node, node});
    visited[node] = true;
    if (node == x) {
      assert(dx == 0);
      assert(dy == diam);
      break;
    }
    auto [nnode, elen] = par[node];
    std::tie(node, dx, dy) = std::make_tuple(nnode, dx - elen, dy + elen);
  }
  if (xb < 0) xb = x;
  if (yb < 0) yb = y;
  std::vector<int> val(n);
  while (not sts.empty()) {
    auto [node, base] = sts.front();
    sts.pop();
    if (mon[node]) {
      if (dx_minus_dy_of[base] > 0) {
        ++val[node];
        if (xb != x) --val[par[xb].x];
      } else if (dx_minus_dy_of[base] == 0) {
        assert(x != y);
        assert(x != base);
        ++val[node];
        --val[par[base].x];
      } else {
        ++val[node];
        ++val[yb];
        if (base != x) val[par[base].x] -= 2;
      }
    }
    for (auto [x, _] : ad[node])
      if (not visited[x]) {
        visited[x] = true;
        sts.push({x, base});
      }
  }
  assert(postorder.back() == x);
  postorder.pop_back();
  for (auto z : postorder) val[par[z].x] += val[z];
  for (int z = n; z--;)
    if (mon[z]) val[z] = -1;
  int max = *std::max_element(begin(val), end(val));
  std::cout << max << ' ' << std::count(begin(val), end(val), max) << '\n';
}
