#include <bits/stdc++.h>   using namespace std;   const int inf = int(1e9);   const double eps = 1e-4;   const double pi = 4 * atan(double(1));   const int N = int(3e5) + 100;   const int M = int(1e6) + 100;   const int sizes[] = {3600, 60, 1, -1};   const int MOD1 = int(1e9) + 7;   const int X1 = 4243;   struct _hash {     int a;     _hash() {}     _hash(int a) : a(a) {}   };   _hash operator+(const _hash& a, const _hash& b) {     _hash c(a.a + b.a);     if (c.a >= MOD1) {       c.a -= MOD1;     }     return c;   }   _hash operator-(const _hash& a, const _hash& b) {     _hash c(a.a - b.a);     if (c.a < 0) {       c.a += MOD1;     }     return c;   }   _hash operator*(const _hash& a, const _hash& b) {     return _hash((1LL * a.a * b.a) % MOD1);   }   bool operator==(const _hash& a, const _hash& b) { return a.a == b.a; }   struct tq {     int a, b, ab, c, d, cd;   };   struct node {     int val;     node** _next;   };   const _hash X(X1);   int n;   int h[N], _prev[N], _rank[N], val[N], p[N];   bool used[N];   _hash st[N], rev_st[N];   _hash pw[2 * N];   vector<pair<int, int*> > lca[N];   node* ver[N];   vector<int> g[N];   tq q[M];   char s[N];   int get(int a) {     if (_prev[a] != a) {       _prev[a] = get(_prev[a]);     }     return _prev[a];   }   inline void merge(int a, int b, int c) {     a = get(a);     b = get(b);     if (_rank[a] < _rank[b]) {       swap(a, b);     }     _prev[b] = a;     if (_rank[a] == _rank[b]) {       ++_rank[a];     }     val[a] = c;   }   inline node* clone(node* v, int lev) {     node* res = new node();     res->val = v->val;     if (sizes[lev] != -1) {       int cnt =           max(((lev == 0 ? n : sizes[lev - 1]) + sizes[lev] - 1) / sizes[lev], 1);       res->_next = new node*[cnt];       for (int i = 0; i < cnt; ++i) {         res->_next[i] = v->_next[i];       }     }     return res;   }   node* set_val(node* v, int lev, int pos, int val) {     v = clone(v, lev);     if (sizes[lev] == -1) {       v->val = val;       return v;     }     v->_next[pos / sizes[lev]] =         set_val(v->_next[pos / sizes[lev]], lev + 1, pos % sizes[lev], val);     return v;   }   int get_val(node* v, int pos) {     int lev = 0;     while (sizes[lev] != -1) {       v = v->_next[pos / sizes[lev]];       pos %= sizes[lev];       ++lev;     }     return v->val;   }   void dfs(int v, int pv, node* cur) {     used[v] = true;     p[v] = pv;     if (pv != -1) {       g[v].erase(find((g[v]).begin(), (g[v]).end(), pv));       h[v] = h[pv] + 1;     } else {       h[v] = 0;     }     cur = set_val(cur, 0, h[v], v);     ver[v] = cur;     st[v] = (pv == -1 ? _hash(0) : st[pv]) + pw[h[v]] * _hash(s[v]);     rev_st[v] = (pv == -1 ? _hash(0) : rev_st[pv]) + pw[n - h[v]] * _hash(s[v]);     for (int i = 0; i < int((lca[v]).size()); ++i) {       if (used[lca[v][i].first]) {         *(lca[v][i].second) = val[get(lca[v][i].first)];       }     }     for (int i = 0; i < int((g[v]).size()); ++i) {       dfs(g[v][i], v, cur);       merge(g[v][i], v, v);     }   }   inline int len(int a, int b, int ab) { return h[a] + h[b] - 2 * h[ab] + 1; }   inline _hash get(int v, int lca) {     return (rev_st[v] - (p[lca] == -1 ? _hash(0) : rev_st[p[lca]])) * pw[h[v]];   }   inline int get_ver(int v, int len) {     len = h[v] - len + 1;     return get_val(ver[v], len);   }   inline _hash get_hash(int a, int b, int ab, int len) {     int first = h[a] - h[ab] + 1;     if (len <= first) {       return get(a, get_ver(a, len));     }     len -= first;     int ver = get_ver(b, h[b] - h[ab] + 1 - len);     return get(a, ab) + (st[ver] - st[ab]) * pw[n + first - (h[ab] + 1)];   }   int main() {     scanf( %d , &n);     gets(s);     gets(s);     for (int i = 0; i < n - 1; ++i) {       int a, b;       scanf( %d %d , &a, &b);       --a;       --b;       g[a].push_back(b);       g[b].push_back(a);     }     pw[0] = _hash(1);     for (int i = 1; i <= 2 * n; ++i) {       pw[i] = pw[i - 1] * X;     }     int m;     scanf( %d , &m);     for (int i = 0; i < m; ++i) {       scanf( %d %d %d %d , &q[i].a, &q[i].b, &q[i].c, &q[i].d);       --q[i].a;       --q[i].b;       --q[i].c;       --q[i].d;       lca[q[i].a].push_back(make_pair(q[i].b, &q[i].ab));       lca[q[i].b].push_back(make_pair(q[i].a, &q[i].ab));       lca[q[i].c].push_back(make_pair(q[i].d, &q[i].cd));       lca[q[i].d].push_back(make_pair(q[i].c, &q[i].cd));     }     for (int i = 0; i < n; ++i) {       _prev[i] = i;       _rank[i] = 1;       val[i] = i;     }     int root = 0;     node* vers = new node[100];     int lev;     for (lev = 0; sizes[lev] != -1; ++lev) {       vers[lev]._next = new node*[max(           ((lev == 0 ? n : sizes[lev - 1]) + sizes[lev] - 1) / sizes[lev], 1)];     }     for (--lev; lev >= 0; --lev) {       for (int j = 0; j < max(((lev == 0 ? n : sizes[lev - 1]) + sizes[lev] - 1) /                                   sizes[lev],                               1);            ++j) {         vers[lev]._next[j] = &vers[lev + 1];       }     }     dfs(root, -1, &vers[0]);     for (int i = 0; i < m; ++i) {       int ans = 0, l = 1,           r = min(len(q[i].a, q[i].b, q[i].ab), len(q[i].c, q[i].d, q[i].cd));       while (l <= r) {         int mid = (l + r) / 2;         _hash h1 = get_hash(q[i].a, q[i].b, q[i].ab, mid);         _hash h2 = get_hash(q[i].c, q[i].d, q[i].cd, mid);         if (h1 == h2) {           ans = mid;           l = mid + 1;         } else {           r = mid - 1;         }       }       printf( %d n , ans);     }     return 0;   }