#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int mxn = 300006 * 2;
const int mxh = 20;
void radix(int *s, int *a, int *b, int n, int m) {
  static int c[mxn];
  fill(c, c + m + 1, 0);
  for (int i = n; i--;) ++c[s[a[i]]];
  partial_sum(c, c + m + 1, c);
  for (int i = n; i--;) b[--c[s[a[i]]]] = a[i];
}
void SA(int *s, int *sa, int *h, int n, int m) {
  static int a[mxn * 2], t[mxn];
  fill(a, a + n * 2, 0);
  copy(s, s + n, a);
  for (int len = 1; len / 2 < n; len *= 2) {
    auto b = a + len / 2;
    iota(sa, sa + n, 0);
    radix(b, sa, t, n, m);
    radix(a, t, sa, n, m);
    t[sa[0]] = (len < n);
    for (int i = 1; i < n; ++i)
      t[sa[i]] =
          t[sa[i - 1]] + (a[sa[i]] != a[sa[i - 1]] || b[sa[i]] != b[sa[i - 1]]);
    copy(t, t + n, a);
    m = n;
  }
  int k = 0;
  for (int i = 0; i < n; ++i) {
    if (k) --k;
    if (a[i])
      while (s[i + k] == s[sa[a[i] - 1] + k]) ++k;
    h[a[i]] = k;
  }
}
struct STtable {
  int s[mxn][mxh];
  void build(int *a, int n) {
    for (int i = 0; i < n; ++i) {
      s[i][0] = a[i];
      for (int j = 1; i - (1 << j) + 1 >= 0; ++j)
        s[i][j] = min(s[i][j - 1], s[i - (1 << j - 1)][j - 1]);
    }
  }
  int get(int l, int r) {
    int k = 31 - __builtin_clz(r + 1 - l);
    return min(s[r][k], s[l + (1 << k) - 1][k]);
  }
};
struct LCP {
  STtable Q;
  int n;
  int r[mxn];
  void build(int *sa, int *h, int n) {
    this->n = n;
    for (int i = 0; i < n; ++i) r[sa[i]] = i;
    Q.build(h, n);
  }
  int get(int x, int y) {
    if (x == y) return n - x;
    return Q.get(min(r[x], r[y]) + 1, max(r[x], r[y]));
  }
};
struct HPD {
  using arr = int[mxn];
  vector<int> e[mxn];
  arr s, h, top, dfn, pv;
  int cnt;
  int size(int x, int p) {
    s[x] = 1;
    for (auto i : e[x])
      if (i != p) s[x] += size(i, x);
    return s[x];
  }
  void dfs(int x, int p, int t) {
    pv[x] = p;
    h[x] = h[p] + 1;
    top[x] = t;
    dfn[x] = ++cnt;
    int y = 0;
    for (auto i : e[x])
      if (i != p)
        if (s[y] < s[i]) y = i;
    if (y) dfs(y, x, top[x]);
    for (auto i : e[x])
      if (i != p)
        if (i != y) dfs(i, x, i);
  }
  void build() {
    size(1, 0);
    cnt = 0;
    dfs(1, 0, 1);
  }
  deque<pii> path(int x, int y) {
    deque<pii> l, r;
    while (top[x] != top[y])
      if (h[top[x]] > h[top[y]]) {
        l.push_back({dfn[x], dfn[top[x]]});
        x = pv[top[x]];
      } else {
        r.push_front({dfn[top[y]], dfn[y]});
        y = pv[top[y]];
      }
    l.push_back({dfn[x], dfn[y]});
    while (!r.empty()) {
      l.push_back(r.front());
      r.pop_front();
    }
    return l;
  }
};
int n;
char a[mxn];
HPD T;
int s[mxn];
int sa[mxn];
int h[mxn];
LCP lcp;
int length(pii a) { return abs(a.first - a.second) + 1; }
int pos(pii a) {
  return a.first <= a.second ? a.first - 1 : (n * 2 + 1 - (a.first));
}
int strlcp(pii a, pii b) {
  int len = lcp.get(pos(a), pos(b));
  return min({len, length(a), length(b)});
}
bool eraseFront(pii &a, int len) {
  if (a.first <= a.second) {
    a.first += len;
    return a.first <= a.second;
  } else {
    a.first -= len;
    return a.first >= a.second;
  }
}
void EXEC() {
  scanf("%d", &n);
  scanf("%s", a + 1);
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    T.e[x].push_back(y);
    T.e[y].push_back(x);
  }
  T.build();
  for (int i = 1; i <= n; ++i) {
    s[T.dfn[i] - 1] = a[i];
    s[(n * 2 + 1 - (T.dfn[i]))] = a[i];
  }
  s[n] = '$';
  s[n * 2 + 1] = 0;
  SA(s, sa, h, n * 2 + 1, 128);
  lcp.build(sa, h, n * 2 + 1);
  int q;
  scanf("%d", &q);
  while (q--) {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    deque<pii> l = T.path(a, b);
    deque<pii> r = T.path(c, d);
    int ans = 0;
    while (!l.empty() && !r.empty()) {
      int len = strlcp(l.front(), r.front());
      ans += len;
      if (!len) break;
      if (!eraseFront(l.front(), len)) l.pop_front();
      if (!eraseFront(r.front(), len)) r.pop_front();
    }
    printf("%d\n", ans);
  }
}
int main() {
  EXEC();
  return 0;
}
