func_code_string: #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;   }   