func_code_string: #include <bits/stdc++.h>   #pragma GCC optimize( O3 )   using namespace std;   const int MAX_N = 3e5 + 10, MAX_LOG_N = 20;   const long long MOD1 = 1e9 + 7, BASE1 = 29, MOD2 = 1e9 + 9, BASE2 = 37;   long long sq(long long a, long long p) { return a * a % p; }   long long qpow(long long a, long long b, long long p) {     return b ? sq(qpow(a, b / 2, p), p) * (b & 1 ? a : 1) % p : 1;   }   long long inv(long long a, long long p) { return qpow(a, p - 2, p); }   int N, M, logN, log_table[MAX_N], pa[MAX_N], jmp[MAX_N][MAX_LOG_N],       depth[MAX_N], down_len[MAX_N], chain_content[MAX_N * 2],       *chain_content_alloc = chain_content, *pos[MAX_N];   char S[MAX_N];   long long pow_base1[MAX_N], pow_base1i[MAX_N], pow_base2[MAX_N],       pow_base2i[MAX_N];   long long pref_hash1_up[MAX_N], pref_hash1_down[MAX_N], pref_hash2_up[MAX_N],       pref_hash2_down[MAX_N];   vector<int> edge[MAX_N], child[MAX_N];   void construct_dfs1(int x) {     pref_hash1_down[x] =         (pref_hash1_down[pa[x]] + (S[x] -  a ) * pow_base1[depth[x]]) % MOD1;     pref_hash1_up[x] =         (pref_hash1_up[pa[x]] + (S[x] -  a ) * pow_base1i[depth[x]]) % MOD1;     pref_hash2_down[x] =         (pref_hash2_down[pa[x]] + (S[x] -  a ) * pow_base2[depth[x]]) % MOD2;     pref_hash2_up[x] =         (pref_hash2_up[pa[x]] + (S[x] -  a ) * pow_base2i[depth[x]]) % MOD2;     for (int i : edge[x]) {       if (i == pa[x]) continue;       child[x].push_back(i);       pa[i] = x;       depth[i] = depth[x] + 1;       construct_dfs1(i);       down_len[x] = max(down_len[x], down_len[i]);     }     down_len[x]++;     sort(child[x].begin(), child[x].end(),          [](int a, int b) { return down_len[a] > down_len[b]; });   }   void construct_dfs2(int x) {     vector<int> light;     int y = x;     while (!child[y].empty()) {       for (int i = 1; i < child[y].size(); i++) light.push_back(child[y][i]);       y = child[y][0];     }     chain_content_alloc += 2 * down_len[x];     int *t = chain_content_alloc;     for (int i = 1; i <= 2 * down_len[x]; i++) {       *--t = y;       if (i <= down_len[x]) {         pos[y] = t;       }       y = pa[y];     }     for (int i : light) {       construct_dfs2(i);     }   }   void init() {     scanf( %d , &N);     for (int i = 1; i <= N; i++) {       log_table[i] = log_table[i - 1];       if (1 << log_table[i] + 1 < i) log_table[i]++;     }     logN = log_table[N];     pow_base1[0] = pow_base1i[0] = pow_base2[0] = pow_base2i[0] = 1;     pow_base1[1] = BASE1;     pow_base1i[1] = inv(BASE1, MOD1);     pow_base2[1] = BASE2;     pow_base2i[1] = inv(BASE2, MOD2);     for (long long *arr : {pow_base1, pow_base1i}) {       for (int i = 2; i <= N; i++) arr[i] = arr[1] * arr[i - 1] % MOD1;     }     for (long long *arr : {pow_base2, pow_base2i}) {       for (int i = 2; i <= N; i++) arr[i] = arr[1] * arr[i - 1] % MOD2;     }     scanf( %s , S + 1);     for (int i = 1; i < N; i++) {       int a, b;       scanf( %d%d , &a, &b);       edge[a].push_back(b);       edge[b].push_back(a);     }     construct_dfs1(1);     for (int i = 1; i <= N; i++) jmp[i][0] = pa[i];     for (int i = 1; i <= logN; i++) {       for (int j = 1; j <= N; j++) {         jmp[j][i] = jmp[jmp[j][i - 1]][i - 1];       }     }     construct_dfs2(1);   }   int kth_ancestor(int x, int k) {     if (k) {       int t = log_table[k];       x = jmp[x][t];       k -= 1 << t;     }     return pos[x][-k];   }   int LCA(int a, int b) {     if (depth[a] > depth[b]) swap(a, b);     b = kth_ancestor(b, depth[b] - depth[a]);     if (a == b) return a;     for (int i = logN; i >= 0; i--) {       if (jmp[a][i] != jmp[b][i]) {         a = jmp[a][i];         b = jmp[b][i];       }     }     return pa[a];   }   long long hash1_up(int a, int b) {     return (pref_hash1_up[a] - pref_hash1_up[pa[b]] + MOD1) *            pow_base1[depth[a]] % MOD1;   }   long long hash1_down(int a, int b) {     return (pref_hash1_down[a] - pref_hash1_down[pa[b]] + MOD1) *            pow_base1i[depth[b]] % MOD1;   }   long long hash1(int a, int b, int c, int len) {     if (len <= depth[a] - depth[b] + 1) {       return hash1_up(a, kth_ancestor(a, len - 1));     } else {       int dis = depth[a] + depth[c] - 2 * depth[b] + 1;       long long res =           hash1_up(a, b) + hash1_down(kth_ancestor(c, dis - len),                                       kth_ancestor(c, depth[c] - depth[b] - 1)) *                                pow_base1[depth[a] - depth[b] + 1];       return res % MOD1;     }   }   long long hash2_up(int a, int b) {     return (pref_hash2_up[a] - pref_hash2_up[pa[b]] + MOD2) *            pow_base2[depth[a]] % MOD2;   }   long long hash2_down(int a, int b) {     return (pref_hash2_down[a] - pref_hash2_down[pa[b]] + MOD2) *            pow_base2i[depth[b]] % MOD2;   }   long long hash2(int a, int b, int c, int len) {     if (len <= depth[a] - depth[b] + 1) {       return hash2_up(a, kth_ancestor(a, len - 1));     } else {       int dis = depth[a] + depth[c] - 2 * depth[b] + 1;       long long res =           hash2_up(a, b) + hash2_down(kth_ancestor(c, dis - len),                                       kth_ancestor(c, depth[c] - depth[b] - 1)) *                                pow_base2[depth[a] - depth[b] + 1];       return res % MOD2;     }   }   void solve() {     int s1, t1, s2, t2;     scanf( %d%d%d%d , &s1, &t1, &s2, &t2);     int c1 = LCA(s1, t1), c2 = LCA(s2, t2);     int l = 0, r = min(depth[s1] + depth[t1] - 2 * depth[c1] + 1,                        depth[s2] + depth[t2] - 2 * depth[c2] + 1);     while (l != r) {       int m = (l + r + 1) / 2;       if (hash1(s1, c1, t1, m) == hash1(s2, c2, t2, m) &&           hash2(s1, c1, t1, m) == hash2(s2, c2, t2, m)) {         l = m;       } else {         r = m - 1;       }     }     printf( %d n , l);   }   int main() {     init();     scanf( %d , &M);     for (int i = 1; i <= M; i++) {       solve();     }   }   