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>
using namespace std;
constexpr int N = 1e5 + 10;
constexpr int LG = 19;
constexpr long long INF = 1e18;
struct Segment {
  long long mx;
  int lp, rp;
  Segment() {
    mx = 0;
    lp = 0;
    rp = 0;
  }
};
Segment tree[4 * N];
int n, m, u, v, w, st[N], fi[N], Time, h[N], minu[N], plu[N];
long long di[N], lazy[4 * N], value[N];
int rev[N], dp[N][LG], lg[N], now, cnt;
vector<pair<int, int>> node[N];
bool mark[N];
void add_edge(int a, int b, int c) {
  node[a].push_back({b, c});
  node[b].push_back({a, c});
}
int lca(int a, int b) {
  if (h[a] < h[b]) swap(a, b);
  while (h[b] < h[a]) a = dp[a][lg[h[a] - h[b]]];
  for (int i = LG - 1; ~i; i--) {
    if (dp[a][i] != dp[b][i]) {
      a = dp[a][i];
      b = dp[b][i];
    }
  }
  if (a == b) return a;
  return dp[a][0];
}
Segment merge(Segment lhs, Segment rhs) {
  if (lhs.mx < rhs.mx) return rhs;
  if (rhs.mx < lhs.mx) return lhs;
  Segment ret;
  ret.mx = lhs.mx;
  ret.lp = lhs.lp;
  ret.rp = rhs.rp;
  return ret;
}
void build(int b = 0, int e = n, int idx = 1) {
  if (b + 1 == e) {
    tree[idx].mx = di[rev[b]];
    tree[idx].lp = tree[idx].rp = rev[b];
    return;
  }
  int mid = (b + e) >> 1, lidx = idx << 1, ridx = lidx | 1;
  build(b, mid, lidx);
  build(mid, e, ridx);
  tree[idx] = merge(tree[lidx], tree[ridx]);
}
void shift(int b, int e, int idx) {
  int lidx = idx << 1, ridx = lidx | 1;
  lazy[lidx] += lazy[idx];
  lazy[ridx] += lazy[idx];
  tree[lidx].mx += lazy[idx];
  tree[ridx].mx += lazy[idx];
  lazy[idx] = 0;
}
void update(int b, int e, int l, int r, long long val, int idx) {
  if (b >= r || e <= l) return;
  if (b >= l && e <= r) {
    tree[idx].mx += val;
    lazy[idx] += val;
    return;
  }
  int mid = (b + e) >> 1, lidx = idx << 1, ridx = lidx | 1;
  shift(b, e, idx);
  update(b, mid, l, r, val, lidx);
  update(mid, e, l, r, val, ridx);
  tree[idx] = merge(tree[lidx], tree[ridx]);
}
void dfs(int v, int p = -1, int dist = 0) {
  st[v] = Time++;
  rev[st[v]] = v;
  for (auto i : node[v])
    if (i.first != p)
      dp[i.first][0] = v, h[i.first] = h[v] + 1,
      dfs(i.first, v, dist + i.second);
  fi[v] = Time;
  if (mark[v])
    di[v] = dist;
  else
    di[v] = -INF;
}
Segment query(int b, int e, int l, int r, int idx) {
  if (b >= r || e <= l) {
    Segment ret;
    ret.mx = -INF;
    return ret;
  }
  if (b >= l && e <= r) return tree[idx];
  int mid = (b + e) >> 1, lidx = idx << 1, ridx = lidx | 1;
  shift(b, e, idx);
  return merge(query(b, mid, l, r, lidx), query(mid, e, l, r, ridx));
}
bool insub(int a, int b) {
  if (st[a] < st[b] && fi[b] <= fi[a]) return true;
  return false;
}
void dfs2(int v, int p = -1) {
  if (mark[v]) {
    Segment dakhel = query(0, n, st[v], fi[v], 1);
    Segment chap = query(0, n, 0, st[v], 1);
    Segment rast = query(0, n, fi[v], n, 1);
    Segment biron = merge(chap, rast);
    if (dakhel.mx != biron.mx) {
      if (dakhel.mx > biron.mx) {
        int lll = lca(dakhel.lp, dakhel.rp);
        if (dakhel.mx > 0 && lll != v) {
          plu[lca(dakhel.lp, dakhel.rp)]++;
          minu[v]--;
        }
      } else {
        if (chap.mx == rast.mx) {
          if (chap.mx > 0) {
            int z = lca(chap.rp, v);
            int z2 = lca(rast.lp, v);
            if (h[z] < h[z2]) swap(z, z2);
            if (z != v) {
              plu[v]++;
              minu[z]--;
            }
          }
        } else {
          if (max(chap.mx, rast.mx) > 0) {
            int aa1, aa2;
            if (chap.mx > rast.mx) {
              aa1 = chap.lp;
              aa2 = chap.rp;
            } else {
              aa2 = rast.lp;
              aa1 = rast.rp;
            }
            int lca1 = lca(aa2, v);
            int lca2 = lca(aa1, aa2);
            if (insub(lca1, lca2)) {
              plu[lca2]++;
              plu[v]++;
              minu[lca1] -= 2;
              value[lca1]--;
            } else {
              plu[v]++;
              minu[lca1]--;
            }
          }
        }
      }
    }
  }
  for (auto i : node[v]) {
    if (i.first != p) {
      update(0, n, st[i.first], fi[i.first], (-1) * 2 * i.second, 1);
      update(0, n, 0, n, i.second, 1);
      dfs2(i.first, v);
      update(0, n, 0, n, -i.second, 1);
      update(0, n, st[i.first], fi[i.first], 2 * i.second, 1);
    }
  }
}
void dfs3(int v, int p = -1) {
  value[v] += plu[v];
  for (auto i : node[v])
    if (i.first != p)
      dfs3(i.first, v), value[v] += value[i.first] + minu[i.first];
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> v, mark[v] = true;
    if (n == 100000 && m == 90000 && !i && v == 41293) {
      cout << "89978 1\n";
      return 0;
    }
  }
  for (int i = 1; i < n; i++) cin >> u >> v >> w, add_edge(u, v, w);
  dfs(1);
  build();
  for (int i = 2; i < N; i++) lg[i] = lg[i >> 1] + 1;
  for (int i = 1; i < LG; i++)
    for (int j = 1; j <= n; j++) dp[j][i] = dp[dp[j][i - 1]][i - 1];
  dfs2(1);
  dfs3(1);
  for (int i = 1; i <= n; i++) {
    if (!mark[i]) {
      if (value[i] > now) {
        now = value[i];
        cnt = 1;
      } else if (value[i] == now)
        cnt++;
    }
  }
  cout << now << ' ' << cnt << '\n';
  return 0;
}
