#include <bits/stdc++.h>
using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f3f;
struct hld_t {
  vector<vector<int>> g;
  vector<int> sz, par;
  vector<int> h, in, rin, out, nxt;
  int t, n;
  hld_t(int _n) : n(_n) {
    h.resize(n);
    in.resize(n);
    rin.resize(n);
    out.resize(n);
    par.resize(n);
    sz.resize(n);
    g.resize(n);
    nxt.resize(n);
    t = 0;
  }
  void build(int v) {
    dfs_sz(v, v);
    hld(v, v);
  }
  void add(int first, int second) {
    g[first].push_back(second);
    g[second].push_back(first);
  }
  void dfs_sz(int v, int p) {
    sz[v] = 1, par[v] = p;
    for (int i = 0; i < g[v].size(); i++) {
      int &u = g[v][i];
      if (u == p) {
        swap(u, g[v].back());
        g[v].pop_back();
        i--;
      } else {
        h[u] = h[v] + 1;
        dfs_sz(u, v);
        sz[v] += sz[u];
        if (sz[u] > sz[g[v][0]]) {
          swap(u, g[v][0]);
        }
      }
    }
  }
  void hld(int v, int p) {
    in[v] = t++;
    rin[in[v]] = v;
    for (auto &u : g[v]) {
      nxt[u] = u == g[v][0] ? nxt[v] : u;
      hld(u, v);
    }
    out[v] = t;
  }
  int lca(int u, int v) {
    while (!inSubtree(nxt[u], v)) u = par[nxt[u]];
    while (!inSubtree(nxt[v], u)) v = par[nxt[v]];
    return in[u] < in[v] ? u : v;
  }
  bool inSubtree(int u, int v) { return in[u] <= in[v] && in[v] < out[u]; }
  vector<pair<int, int>> getPathtoAncestor(int a, int p) {
    vector<pair<int, int>> ans;
    while (nxt[a] != nxt[p]) {
      ans.emplace_back(in[nxt[a]], in[a]);
      a = par[nxt[a]];
    }
    ans.emplace_back(in[p], in[a]);
    return ans;
  }
  int dist(int a, int b) { return h[a] + h[b] - 2 * h[lca(a, b)]; }
};
template <typename T>
struct stringh {
  string s;
  vector<T> h;
  vector<T> h_base;
  T mod;
  stringh(){};
  stringh(string &s, T mod = 1) : s(s), mod(mod) {
    h.resize(s.size() + 1);
    h_base.resize(s.size() + 1);
    hash_init();
  }
  void hash_init(T prime = 0xdefaced) {
    h_base[0] = 1;
    h[0] = 0;
    for (int i = 1; i <= s.size(); i++) {
      h[i] = (h[i - 1] * prime + s[i - 1]) % mod;
      h_base[i] = (h_base[i - 1] * prime) % mod;
    }
  }
  T get(int l, int r) {
    return (h[r + 1] - (h[l] * h_base[r - l + 1]) % mod + mod) % mod;
  }
};
const int mod1 = 1073676287;
const int mod2 = 1e9 + 9;
const int mx = 312345;
struct path_h {
  stringh<long long> h1, h2;
  path_h() {}
  path_h(string &s) { h1 = stringh<long long>(s, mod1); }
} ph[2 * mx];
string s[mx];
pair<long long, long long> getKeys(vector<pair<int, int>> &paths1,
                                   vector<pair<int, int>> &paths2, int first,
                                   hld_t &t) {
  long long key1 = 0, key2 = 0;
  for (auto &a : paths1) {
    if (a.first > a.second) continue;
    auto &cur = ph[2 * t.nxt[t.rin[a.second]] ^ 1];
    int base = t.in[t.nxt[t.rin[a.second]]];
    int sz = a.second - a.first + 1;
    int tot = cur.h1.s.size();
    if (!first) break;
    if (sz > first) {
      key1 = (key1 * cur.h1.h_base[first] +
              cur.h1.get(tot - 1 - (a.second - base),
                         tot - 1 - (a.second - first + 1 - base))) %
             mod1;
      first = 0;
      break;
    }
    long long g =
        cur.h1.get(tot - 1 - (a.second - base), tot - 1 - (a.first - base));
    key1 = (key1 * cur.h1.h_base[sz] + g) % mod1;
    first -= sz;
  }
  for (auto &a : paths2) {
    if (a.first > a.second) continue;
    auto &cur = ph[2 * t.nxt[t.rin[a.second]]];
    int base = t.in[t.nxt[t.rin[a.second]]];
    int sz = a.second - a.first + 1;
    int tot = cur.h1.s.size();
    if (!first) break;
    if (sz > first) {
      key1 = (key1 * cur.h1.h_base[first] +
              cur.h1.get(a.first - base, (a.first - base) + first - 1)) %
             mod1;
      first = 0;
      break;
    }
    long long g = cur.h1.get(a.first - base, a.second - base);
    key1 = (key1 * cur.h1.h_base[sz] + g) % mod1;
    first -= sz;
  }
  return make_pair(key1, key2);
}
int main() {
  int n;
  scanf("%d", &n);
  string v;
  cin >> v;
  hld_t t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--, b--;
    t.add(a, b);
  }
  t.build(0);
  for (int i = 0; i < n; i++) {
    s[t.nxt[t.rin[i]]].push_back(v[t.rin[i]]);
  }
  for (int i = 0; i < n; i++) {
    ph[2 * i] = path_h(s[i]);
    reverse(s[i].begin(), s[i].end());
    ph[2 * i + 1] = path_h(s[i]);
  }
  int m;
  scanf("%d", &m);
  for (int i = 0; i < m; i++) {
    int a, b, c, d;
    scanf("%d%d", &a, &b), scanf("%d%d", &c, &d);
    a--, b--, c--, d--;
    int lo = 0, hi = min(t.dist(a, b), t.dist(c, d)) + 1;
    int lab = t.lca(a, b);
    auto paths1 = t.getPathtoAncestor(a, lab);
    auto paths2 = t.getPathtoAncestor(b, lab);
    paths2.back().first++;
    reverse(paths2.begin(), paths2.end());
    int lcd = t.lca(c, d);
    auto paths3 = t.getPathtoAncestor(c, lcd);
    auto paths4 = t.getPathtoAncestor(d, lcd);
    paths4.back().first++;
    reverse(paths4.begin(), paths4.end());
    while (hi - lo > 1) {
      int m = lo + hi >> 1;
      auto key1 = getKeys(paths1, paths2, m, t);
      auto key2 = getKeys(paths3, paths4, m, t);
      if (key1 == key2)
        lo = m;
      else
        hi = m;
    }
    auto key1 = getKeys(paths1, paths2, hi, t);
    auto key2 = getKeys(paths3, paths4, hi, t);
    printf("%d\n", key1 == key2 ? hi : lo);
  }
}
