func_code_string: #include <bits/stdc++.h>   using namespace std;   const int INF = ((long long)1E9 + 7);   template <class C>   void mini(C& a, C b) {     a = min(a, b);   }   template <class C>   void maxi(C& a, C b) {     a = max(a, b);   }   const int LG = 20;   struct node {     int par;     vector<int> inc;     bool monk;     int aim;     vector<pair<int, int> > mx;     int up[LG];     int depth;     int dlow, dup;     node() : par(-1), inc(), monk(false), aim(-1), depth(0), dlow(0), dup(0) {}   };   struct dart {     bool down;     int rev;     int dist;     int head;     int far;     list<int> pil;     dart(int _head = 0, int _dist = 0)         : down(false), rev(0), dist(_dist), head(_head), far(-INF), pil() {}   };   const int MN = 100100;   node T[MN];   dart D[2 * MN];   void assign(int i, int up, int d = 0) {     T[i].par = up;     T[i].depth = d;     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it == up) continue;       D[*it].down = true;       assign(D[*it].head, D[*it].rev, d + 1);     }   }   void distUp(int i) {     int mx = -INF;     int up = T[i].par;     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it == up) continue;       distUp(D[*it].head);       maxi(mx, D[*it].far);     }     if (T[i].monk) maxi(mx, 0);     if (up != -1) {       D[D[up].rev].far = mx + D[up].dist;     }   }   void distDown(int i) {     int up = T[i].par;     T[i].mx.push_back((up != -1) ? pair<int, int>(D[up].far, up)                                  : pair<int, int>(-INF, -1));     T[i].mx.push_back((T[i].monk) ? pair<int, int>(0, -1)                                   : pair<int, int>(-INF, -1));     T[i].mx.push_back(pair<int, int>(-INF, -1));     sort((T[i].mx).begin(), (T[i].mx).end(), greater<pair<int, int> >());     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it == up) continue;       if (D[*it].far > T[i].mx[2].first) {         T[i].mx[2] = make_pair(D[*it].far, *it);         sort((T[i].mx).begin(), (T[i].mx).end(), greater<pair<int, int> >());       }     }     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it == up) continue;       int j = (*it == T[i].mx[0].second);       D[D[*it].rev].far = T[i].mx[j].first + D[*it].dist;       distDown(D[*it].head);     }   }   void goUp(int i) {     int up = T[i].par;     if (T[i].monk) {       if (T[i].mx[0].first == T[i].mx[1].first)         T[i].aim = i;       else {         int rv = D[T[i].mx[0].second].rev;         D[rv].pil.insert(D[rv].pil.end(), i);       }     }     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it == up) continue;       goUp(D[*it].head);       int j = 0, k = 1;       if (T[i].mx[0].second == *it)         j = 1, k = 2;       else if (T[i].mx[1].second == *it)         k = 2;       int a = T[i].mx[j].second;       int b = T[i].mx[k].second;       if (a == -1 || (b != -1 && D[a].far == D[b].far)) {         for (__typeof((D[*it].pil).begin()) jt = ((D[*it].pil).begin());              jt != (D[*it].pil).end(); ++jt) {           T[*jt].aim = i;         }       } else {         D[D[a].rev].pil.splice(D[D[a].rev].pil.end(), D[*it].pil);       }     }   }   void goDown(int i) {     int up = T[i].par;     if (up != -1) {       int j = 0, k = 1;       if (T[i].mx[0].second == up)         j = 1, k = 2;       else if (T[i].mx[1].second == up)         k = 2;       int a = T[i].mx[j].second;       int b = T[i].mx[k].second;       if (a == -1 || (b != -1 && D[a].far == D[b].far)) {         for (__typeof((D[up].pil).begin()) jt = ((D[up].pil).begin());              jt != (D[up].pil).end(); ++jt) {           T[*jt].aim = i;         }       } else {         D[D[a].rev].pil.splice(D[D[a].rev].pil.end(), D[up].pil);       }     }     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it != up) goDown(D[*it].head);     }   }   void add(int i, int j) {     if (T[i].depth < T[j].depth) swap(i, j);     T[i].dlow++;     T[j].dlow++;     int dd = T[i].depth - T[j].depth;     for (int k = 0; k < (LG); ++k) {       if (dd & (1 << k)) {         i = T[i].up[k];       }     }     for (int k = (LG - 1); k >= (0); --k) {       if (T[i].up[k] != T[j].up[k]) {         i = T[i].up[k];         j = T[j].up[k];       }     }     if (i != j) {       i = T[i].up[0];       j = T[j].up[0];     }     T[i].dup++;   }   int bst = 0;   int cnt = 0;   int final(int i) {     int v = 0;     for (__typeof((T[i].inc).begin()) it = ((T[i].inc).begin());          it != (T[i].inc).end(); ++it) {       if (*it != T[i].par) v += final(D[*it].head);     }     v += T[i].dlow;     v -= T[i].dup;     if (!T[i].monk) {       if (v > bst) {         bst = v;         cnt = 0;       }       if (v == bst) ++cnt;     }     return v - T[i].dup;   }   int main() {     ios_base::sync_with_stdio(false);     int n, m;     cin >> n >> m;     for (int i = 0; i < (m); ++i) {       int x;       cin >> x;       --x;       T[x].monk = true;     }     for (int i = 0; i < (n - 1); ++i) {       int a, b, c;       cin >> a >> b >> c;       --a;       --b;       D[2 * i] = dart(b, c);       T[a].inc.push_back(2 * i);       D[2 * i + 1] = dart(a, c);       T[b].inc.push_back(2 * i + 1);     }     for (int i = 0; i < (2 * (n - 1)); ++i) D[i].rev = i ^ 1;     assign(0, -1);     distUp(0);     distDown(0);     goUp(0);     goDown(0);     for (int i = 0; i < (n); ++i) {       for (int j = 0; j < (LG); ++j) T[i].up[j] = -1;       int up = T[i].par;       if (up != -1) T[i].up[0] = D[up].head;     }     for (int j = 0; j < (LG - 1); ++j) {       for (int i = 0; i < (n); ++i) {         if (T[i].up[j] != -1) T[i].up[j + 1] = T[T[i].up[j]].up[j];       }     }     for (int i = 0; i < (n); ++i) {       if (T[i].monk) add(i, T[i].aim);     }     final(0);     cout << bst <<     << cnt << endl;     return 0;   }   