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;
int nextInt() {
  char c;
  int i;
  for (c = getchar(); c < '0' || c > '9'; c = getchar())
    ;
  for (i = c - '0', c = getchar(); c >= '0' && c <= '9';
       i = i * 10 + c - '0', c = getchar())
    ;
  return i;
}
const int inf = 1 << 30;
struct Edge {
  int v, w;
  Edge(int v = 0, int w = 0) : v(v), w(w) {}
};
struct Info {
  int dis, lca;
  Info(int dis = 0, int lca = 0) : dis(dis), lca(lca) {}
  Info inc_dist(int w) const { return Info(dis + w, lca); }
};
Info up[101000], down[101000];
int anc[101000][20], fa[101000], dep[101000], w[101000];
bool live[101000];
vector<Edge> e[101000];
int n, m;
Info merge_info(const Info& a, const Info& b, int w, int v) {
  Info info = b.inc_dist(w);
  if (info.dis > a.dis) {
    return info;
  } else if (info.dis == a.dis) {
    info.lca = v;
    return info;
  } else {
    return a;
  }
}
void calc_up(int x) {
  vector<Edge> son;
  for (Edge edge : e[x])
    if (edge.v != fa[x]) son.push_back(edge);
  int deg = son.size();
  vector<Info> pre_max = vector<Info>(deg);
  for (int i = 0; i < deg; ++i) {
    pre_max[i] =
        (i == 0 ? down[son[i].v].inc_dist(son[i].w)
                : merge_info(pre_max[i - 1], down[son[i].v], son[i].w, x));
  }
  vector<Info> suf_max = vector<Info>(deg);
  for (int i = deg - 1; i >= 0; --i) {
    suf_max[i] = (i == deg - 1 ? down[son[i].v].inc_dist(son[i].w)
                               : merge_info(suf_max[i + 1], down[son[i].v],
                                            son[i].w, x));
  }
  for (int i = 0; i < deg; ++i) {
    int v = son[i].v, w = son[i].w;
    Info info = up[x];
    if (i != 0) info = merge_info(info, pre_max[i - 1], 0, x);
    if (i != deg - 1) info = merge_info(info, suf_max[i + 1], 0, x);
    up[v] = merge_info(Info(live[v] ? 0 : -inf, v), info, w, v);
    calc_up(v);
  }
}
void calc_down(int x) {
  down[x] = Info(live[x] ? 0 : -inf, x);
  anc[x][0] = fa[x];
  for (int i = 1; (1 << i) <= dep[x]; ++i) {
    anc[x][i] = anc[anc[x][i - 1]][i - 1];
  }
  for (Edge edge : e[x])
    if (edge.v != fa[x]) {
      int v = edge.v;
      fa[v] = x, dep[v] = dep[x] + 1, calc_down(v);
      down[x] = merge_info(down[x], down[v], edge.w, x);
    }
}
int lca(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = 20 - 1; i >= 0; --i)
    if (dep[anc[x][i]] >= dep[y]) x = anc[x][i];
  if (x == y) return x;
  for (int i = 20 - 1; i >= 0; --i)
    if (anc[x][i] != anc[y][i]) x = anc[x][i], y = anc[y][i];
  return fa[x];
}
void chain_inc(int x, int y) {
  int z = lca(x, y);
  ++w[x], ++w[y], --w[z], --w[fa[z]];
}
void calc_ans(int x) {
  for (Edge edge : e[x])
    if (edge.v != fa[x]) {
      calc_ans(edge.v), w[x] += w[edge.v];
    }
}
int main() {
  dep[0] = -1;
  n = nextInt();
  m = nextInt();
  for (int i = 1; i <= m; ++i) {
    int v = nextInt();
    live[v] = true;
  }
  for (int i = 1; i <= n - 1; ++i) {
    int u = nextInt();
    int v = nextInt();
    int w = nextInt();
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
  }
  int root = 1;
  calc_down(root);
  up[root] = Info(live[root] ? 0 : -inf, root);
  calc_up(root);
  for (int i = 1; i <= n; ++i)
    if (live[i]) {
      if (up[i].dis > down[i].dis) {
        chain_inc(i, up[i].lca);
      } else if (up[i].dis < down[i].dis) {
        chain_inc(i, down[i].lca);
      }
    }
  calc_ans(1);
  int ans = 0, ans_cnt = 0;
  for (int i = 1; i <= n; ++i)
    if (!live[i]) {
      if (w[i] > ans)
        ans = w[i], ans_cnt = 1;
      else if (w[i] == ans)
        ++ans_cnt;
    }
  printf("%d %d\n", ans, ans_cnt);
  return 0;
}
