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>
char ch;
inline void read(int &x) {
  x = 0;
  ch = getchar();
  while (ch <= 32) ch = getchar();
  while (ch > 32) {
    x = x * 10 + ch - 48;
    ch = getchar();
  };
};
int n, m;
inline int max(int a, int b) { return a > b ? a : b; }
inline int min(int a, int b) { return a < b ? a : b; }
struct splaynode {
  splaynode *s[2], *fa;
  bool rev;
  int add;
  int x;
  inline void add_rev_tag() {
    splaynode *t = s[0];
    s[0] = s[1];
    s[1] = t;
    rev ^= 1;
  };
  inline void add_tag(int t) {
    add += t;
    x += t;
  };
  inline void down() {
    if (rev) {
      if (s[0]) s[0]->add_rev_tag();
      if (s[1]) s[1]->add_rev_tag();
      rev = 0;
    };
    if (s[0]) s[0]->add_tag(add);
    if (s[1]) s[1]->add_tag(add);
    add = 0;
  };
};
splaynode lct[100005];
inline int get_parent(splaynode *x, splaynode *&fa) {
  return (fa = x->fa) ? fa->s[0] == x ? 0 : fa->s[1] == x ? 1 : -1 : -1;
};
inline void rotate(splaynode *x) {
  splaynode *fa, *gfa;
  int t1, t2;
  t1 = get_parent(x, fa);
  t2 = get_parent(fa, gfa);
  fa->down();
  x->down();
  if ((fa->s[t1] = x->s[t1 ^ 1])) fa->s[t1]->fa = fa;
  fa->fa = x;
  x->fa = gfa;
  x->s[t1 ^ 1] = fa;
  if (t2 != -1) gfa->s[t2] = x;
};
inline splaynode *splay(splaynode *x) {
  while (1) {
    splaynode *fa, *gfa;
    int t1, t2;
    t1 = get_parent(x, fa);
    if (t1 == -1) break;
    t2 = get_parent(fa, gfa);
    if (t2 == -1) {
      rotate(x);
      break;
    };
    if (t1 == t2) {
      rotate(fa);
      rotate(x);
    } else {
      rotate(x);
      rotate(x);
    };
  };
  x->down();
  return x;
};
inline splaynode *access(splaynode *x) {
  splaynode *ret = NULL;
  while (x) {
    splay(x)->s[1] = ret;
    ret = x;
    x = x->fa;
  };
  return ret;
};
inline void setroot(splaynode *x) { splay(x)->add_rev_tag(); };
inline void add1(int x, int y) {
  setroot(lct + x);
  access(lct + y)->add_tag(1);
};
inline int getval(int x) { return splay(lct + x)->x; };
struct edge {
  edge *next;
  int y, len;
} * se[100005], e[100005 * 2], *etot = e;
inline void addedge(int x, int y, int len) {
  *++etot = (edge){se[x], y, len};
  se[x] = etot;
};
int list[100005];
bool inl[100005];
struct data {
  int ma;
  int posL, posR;
};
inline data operator+(data a, data b) {
  if (a.ma < b.ma) return b;
  if (a.ma > b.ma) return a;
  return (data){a.ma, a.posL, b.posR};
};
struct segnode {
  segnode *l, *r;
  int add;
  data x;
  inline void add_tag(int tag) {
    add += tag;
    x.ma += tag;
  };
  inline void down() {
    l->add_tag(add);
    r->add_tag(add);
    add = 0;
  };
  inline void update() { x = l->x + r->x; };
};
segnode _seg[100005 * 2];
segnode *_segtot = _seg, *root;
inline segnode *build(int L, int R) {
  segnode *ret = ++_segtot;
  if (L == R) {
    ret->x.posL = ret->x.posR = L;
    ret->x.ma = -1000000000;
    return ret;
  };
  int mid = (L + R) >> 1;
  ret->l = build(L, mid);
  ret->r = build(mid + 1, R);
  ret->update();
  return ret;
};
inline void modify(segnode *a, int pos, int L, int R, int val) {
  if (L == R) {
    a->x.ma = val;
    return;
  };
  a->down();
  int mid = (L + R) >> 1;
  if (pos <= mid) {
    modify(a->l, pos, L, mid, val);
  } else {
    modify(a->r, pos, mid + 1, R, val);
  };
  a->update();
};
inline void add(segnode *a, int l, int r, int L, int R, int val) {
  if (l == L && r == R) {
    a->add_tag(val);
    return;
  };
  a->down();
  int mid = (L + R) >> 1;
  if (r <= mid) {
    add(a->l, l, r, L, mid, val);
  } else if (l > mid) {
    add(a->r, l, r, mid + 1, R, val);
  } else {
    add(a->l, l, mid, L, mid, val);
    add(a->r, mid + 1, r, mid + 1, R, val);
  };
  a->update();
};
inline data query(segnode *a, int l, int r, int L, int R) {
  if (l == L && r == R) return a->x;
  a->down();
  int mid = (L + R) >> 1;
  if (r <= mid) {
    return query(a->l, l, r, L, mid);
  } else if (l > mid) {
    return query(a->r, l, r, mid + 1, R);
  } else {
    return query(a->l, l, mid, L, mid) + query(a->r, mid + 1, r, mid + 1, R);
  };
};
inline data query(int l, int r) {
  if (l > r) {
    return (data){-1000000000, 0, 0};
  } else {
    return query(root, l, r, 1, n);
  };
};
int d1[100005], d2[100005];
int dseq[100005];
int dfstot;
int nowdist;
int pt[100005][17];
int h[100005];
inline void dfs(int x, int last) {
  d1[x] = ++dfstot;
  dseq[dfstot] = x;
  h[x] = h[last] + 1;
  pt[x][0] = last;
  if (last) lct[x].fa = lct + last;
  if (inl[x]) {
    modify(root, d1[x], 1, n, nowdist);
  };
  edge *te = se[x];
  while (te) {
    int ty = te->y;
    if (ty ^ last) {
      nowdist += te->len;
      dfs(ty, x);
      nowdist -= te->len;
    };
    te = te->next;
  };
  d2[x] = dfstot;
};
inline void init() {
  root = build(1, n);
  dfs(1, 0);
  int i, j;
  for (i = 1; i <= 16; i++) {
    for (j = 1; j <= n; j++) {
      pt[j][i] = pt[pt[j][i - 1]][i - 1];
    };
  };
};
inline int jump(int x, int d) {
  int i = 0, j = 1;
  while (j <= d) ++i, j <<= 1;
  while (d) {
    --i;
    j >>= 1;
    if (j <= d) d -= j, x = pt[x][i];
  };
  return x;
};
inline int getlca(int x, int y) {
  if (h[x] > h[y])
    x = jump(x, h[x] - h[y]);
  else
    y = jump(y, h[y] - h[x]);
  if (x == y) return x;
  int i;
  for (i = 16; i >= 0; i--) {
    if (pt[x][i] ^ pt[y][i]) {
      x = pt[x][i];
      y = pt[y][i];
    };
  };
  return pt[x][0];
};
inline void solve1(int x, int L1, int R1) {
  int L = d1[x], R = d2[x];
  data a1 = query(L, L1 - 1), a2 = query(R1 + 1, R);
  data b1 = query(1, L - 1), b2 = query(R + 1, n);
  int lca;
  if (a1.ma < a2.ma) {
    lca = getlca(dseq[a2.posL], dseq[a2.posR]);
  } else if (a2.ma < a1.ma) {
    lca = getlca(dseq[a1.posL], dseq[a1.posR]);
  } else {
    lca = getlca(getlca(dseq[a2.posL], dseq[a2.posR]),
                 getlca(dseq[a1.posL], dseq[a1.posR]));
  };
  int ma = max(a1.ma, a2.ma);
  int ma1 = max(b1.ma, b2.ma);
  if (ma1 == ma) {
    lca = x;
  };
  add1(x, lca);
};
inline void solve(int x) {
  int L = d1[x], R = d2[x];
  data a = query(L, R);
  data a1, a2;
  a1 = query(1, L - 1);
  a2 = query(R + 1, n);
  if (a.ma > 0) {
    int t = max(a1.ma, a2.ma);
    if (t < a.ma) {
      add1(x, getlca(dseq[a.posL], dseq[a.posR]));
      return;
    } else if (t == a.ma) {
      return;
    };
  };
  int lca = 1;
  if (a1.ma > 0) {
    int t = getlca(dseq[a1.posR], x);
    if (h[t] > h[lca]) lca = t;
  };
  if (a2.ma > 0) {
    int t = getlca(dseq[a2.posL], x);
    if (h[t] > h[lca]) lca = t;
  };
  int p = jump(x, h[x] - h[lca] - 1);
  add1(x, p);
  solve1(lca, d1[p], d2[p]);
};
inline void dfs1(int x) {
  if (inl[x]) {
    solve(x);
  };
  edge *te = se[x];
  while (te) {
    int ty = te->y;
    if (h[ty] > h[x]) {
      add(root, d1[ty], d2[ty], 1, n, -2 * te->len);
      add(root, 1, n, 1, n, te->len);
      dfs1(ty);
      add(root, 1, n, 1, n, -te->len);
      add(root, d1[ty], d2[ty], 1, n, 2 * te->len);
    };
    te = te->next;
  };
};
inline void solve() {
  dfs1(1);
  int ma = -1, cnt = 0;
  int i;
  for (i = 1; i <= m; i++) {
    if (inl[i]) continue;
    int tmp = getval(i);
    if (tmp > ma) {
      ma = tmp;
      cnt = 1;
    } else if (tmp == ma) {
      ++cnt;
    };
  };
  printf("%d %d\n", ma, cnt);
};
int main() {
  read(n);
  read(m);
  int i;
  for (i = 1; i <= m; i++) {
    read(list[i]);
    inl[list[i]] = 1;
  };
  for (i = 1; i < n; i++) {
    int a, b, c;
    read(a);
    read(b);
    read(c);
    addedge(a, b, c);
    addedge(b, a, c);
  };
  init();
  solve();
}
