func_code_string: #include <bits/stdc++.h>   #define debug(x) cout << #x <<   =   << x << endl   #define REP(i, n) for (Long i = 0; i < (Long)n; i++)   using namespace std;      typedef long long Long;      const int MX = 3e5;   vector<Long> adj[MX];   set<pair<Long,Long>> queries[MX];   Long saved[MX];   Long single[MX];   Long cnt[2 * MX + 8];   Long ans = 0;      void merge(Long u, Long v, Long gU, Long gV, Long lowLimit, Long &curGroup, map<pair<Long, Long>, Long> &crossedCnt) {    //u to v    if (queries[saved[u]].size() > queries[saved[v]].size()) {     swap(u, v);     swap(gU, gV);    }     for (auto p : queries[saved[u]]) {     Long x = p.first;     auto it = queries[saved[v]].lower_bound({x, -1});     if (it != queries[saved[v]].end() && it->first == x) {      pair<Long, Long> pairIndex = {p.second, it->second};      queries[saved[v]].erase(it);      if (pairIndex.first < lowLimit) {       pairIndex.first = gU;      }      if (pairIndex.second < lowLimit) {       pairIndex.second = gV;      }           Long a = min(pairIndex.first, pairIndex.second);      Long b = max(pairIndex.first, pairIndex.second);      if (a != lowLimit) {       crossedCnt[{a, b}]++;       cnt[a]--;       cnt[b]--;      } else {       cnt[b]--;      }           } else {      Long gInsert = p.second;      if (gInsert < lowLimit) {       gInsert = gU;      }      queries[saved[v]].insert({x, gInsert});     }    }    curGroup = gV;    saved[u] = saved[v];   }      Long groups = 1;   void dfs(Long u, Long p = -1) {    Long sz = queries[u].size();    Long T = 2 * single[u] + sz;    Long cur = 0;        map<pair<Long, Long>, Long> crossedCnt;        for (Long v : adj[u]) {     if (v != p) {      dfs(v, u);     }    }    Long lowLimit = groups;    groups++;    Long curGroup = lowLimit;;    for (Long v : adj[u]) {     if (v != p) {      sz = queries[saved[v]].size();      T += sz;      cur -= sz * (sz - 1) / 2;      Long g = groups++;      cnt[g] += sz;      Long gU = curGroup;      merge(u, v, gU, g, lowLimit, curGroup, crossedCnt);     }    }    sz = queries[saved[u]].size();    T += sz;    cur -= sz * (sz - 1) / 2;    assert(T % 2 == 0);    T /= 2;        cur += T * (T - 1) / 2;    for (auto crossed : crossedCnt) {     sz = crossed.second;     cur += sz * (sz - 1) / 2;    }    for (Long i = lowLimit + 1; i < groups; i++) {     cur += cnt[i] * (cnt[i] - 1) / 2;    }    ans += cur;   }      int main() {    ios_base::sync_with_stdio(false);    cin.tie(NULL);    cout.tie(NULL);    Long n;    cin >> n;    REP(i , n - 1) {     Long u, v;     cin >> u >> v;     u--;     v--;     adj[u].push_back(v);     adj[v].push_back(u);    }    REP(i , n) {     saved[i] = i;    }    Long m;    cin >> m;        REP(i, m) {     Long u , v;     cin >> u >> v;     u--;     v--;     if (u != v) {      queries[u].insert({i, 0});      queries[v].insert({i, 0});     } else {      single[u]++;     }       }    dfs(0);    assert(groups <= 2 * n);    cout << ans <<   n ;          return 0;   }   