#include <bits/stdc++.h>
using namespace std;
struct Query {
  int a, b, c, d, l1, l2;
};
const int MOD = 1000000123;
const int BASE = 29;
const int INV = 758620783;
int powB[300013], powI[300013];
int n, m;
char s[300013];
vector<int> adj[300013];
int up[19][300013];
int h[300013];
inline int go(int a, int d) {
  int i = 0;
  while (d) {
    if (d & 1) a = up[i][a];
    d >>= 1, i += 1;
  }
  return a;
}
inline int lca(int a, int b) {
  if (h[a] > h[b]) swap(a, b);
  b = go(b, h[b] - h[a]);
  if (a == b) return a;
  for (int i = 18; i >= 0; i--)
    if (up[i][a] != up[i][b]) a = up[i][a], b = up[i][b];
  return up[0][a];
}
vector<int> topo;
int hash_[300013], hsah[300013];
inline void dfs(int x, int p = 0) {
  up[0][x] = p;
  h[x] = h[p] + 1;
  topo.push_back(x);
  hash_[x] = ((long long)(s[x] - 'a' + 1) * powB[h[x]] + hash_[p]) % MOD;
  hsah[x] = ((long long)hsah[p] * BASE + (s[x] - 'a' + 1)) % MOD;
  for (int i : adj[x])
    if (i != p) dfs(i, x);
}
inline void build() {
  powB[0] = 1;
  for (int i = 1; i < 300013; i++)
    powB[i] = ((long long)BASE * powB[i - 1]) % MOD;
  powI[0] = 1;
  for (int i = 1; i < 300013; i++)
    powI[i] = ((long long)INV * powI[i - 1]) % MOD;
  h[0] = -1;
  dfs(1);
  for (int i = 1; i < 19; i++)
    for (int j = 1; j <= n; j++) {
      up[i][j] = up[i - 1][up[i - 1][j]];
    }
}
inline int get(int a, int l, int b, int len) {
  if (len <= h[a] - h[l] + 1) {
    b = up[0][b];
    return ((long long)(hash_[a] - hash_[b] + MOD) * powI[h[b] + 1]) % MOD;
  } else {
    int one = ((long long)(hash_[a] - hash_[l] + MOD) * powI[h[l] + 1]) % MOD;
    l = up[0][l];
    int two = (hsah[b] - (long long)hsah[l] * powB[h[b] - h[l]]) % MOD;
    return ((long long)one * powB[h[b] - h[l]] + two + MOD) % MOD;
  }
}
Query q[1000013];
pair<int, int> bound[1000013];
int len[1000013][2];
int res[2 * 1000013];
int last[300013];
vector<pair<int, int> > need[300013];
inline void solve() {
  for (int i = 0; i < m; i++) {
    q[i].l1 = lca(q[i].a, q[i].b);
    q[i].l2 = lca(q[i].c, q[i].d);
    len[i][0] = h[q[i].a] + h[q[i].b] - 2 * h[q[i].l1] + 1;
    len[i][1] = h[q[i].c] + h[q[i].d] - 2 * h[q[i].l2] + 1;
    bound[i] = make_pair(0, min(len[i][0], len[i][1]) + 1);
  }
  for (int r = 0; r < 19; r++) {
    for (int i = 1; i <= n; i++) need[i].clear();
    for (int i = 0; i < m; i++)
      if (bound[i].second - bound[i].first > 1) {
        int mid = (bound[i].first + bound[i].second) / 2;
        if (mid <= h[q[i].a] - h[q[i].l1] + 1)
          need[q[i].a].push_back(make_pair(mid - 1, i * 2));
        else
          need[q[i].b].push_back(make_pair(len[i][0] - mid, i * 2));
        if (mid <= h[q[i].c] - h[q[i].l2] + 1)
          need[q[i].c].push_back(make_pair(mid - 1, i * 2 + 1));
        else
          need[q[i].d].push_back(make_pair(len[i][1] - mid, i * 2 + 1));
      }
    for (int i : topo) {
      last[h[i]] = i;
      for (auto j : need[i]) {
        res[j.second] = last[h[i] - j.first];
      }
    }
    for (int i = 0; i < m; i++)
      if (bound[i].second - bound[i].first > 1) {
        int mid = (bound[i].first + bound[i].second) / 2;
        int one = get(q[i].a, q[i].l1, res[2 * i], mid);
        int two = get(q[i].c, q[i].l2, res[2 * i + 1], mid);
        if (one == two)
          bound[i].first = mid;
        else
          bound[i].second = mid;
      }
  }
}
inline int readint() {
  char c;
  while ((c = getchar()) < '0') continue;
  int ress = c - '0';
  while ((c = getchar()) >= '0') ress = ress * 10 + c - '0';
  return ress;
}
int main() {
  n = readint();
  for (int i = 1; i <= n; i++) s[i] = getchar();
  for (int i = 1; i < n; i++) {
    int u = readint(), v = readint();
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  build();
  m = readint();
  for (int i = 0; i < m; i++) {
    q[i].a = readint(), q[i].b = readint(), q[i].c = readint(),
    q[i].d = readint();
  }
  solve();
  for (int i = 0; i < m; i++) printf("%d\n", bound[i].first);
  return 0;
}
