#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
struct edge {
  int to, nxt;
} e[N << 1];
int cnt = 0, head[N], n;
void addedge(int x, int y) {
  ++cnt;
  e[cnt].to = y;
  e[cnt].nxt = head[x];
  head[x] = cnt;
}
char s[N];
int a[N], rt[N], diff[N], maxn = 0, tot = 0;
struct trie {
  int ch[N][26], v[N], sz;
  int id(char ch) { return ch - 'a'; }
  void pushup(int x) {
    v[x] = 1;
    for (int i = 0; i < 26; ++i)
      if (ch[x][i]) v[x] += v[ch[x][i]];
  }
  int new_node(char c) {
    ++sz;
    memset(ch[sz], 0, sizeof(ch[sz]));
    v[sz] = 2;
    ++sz;
    memset(ch[sz], 0, sizeof(ch[sz]));
    ch[sz - 1][id(c)] = sz;
    v[sz] = 1;
    return sz - 1;
  }
  int comb(int x, int y) {
    if (!x || !y) return x + y;
    for (int i = 0; i < 26; ++i) ch[x][i] = comb(ch[x][i], ch[y][i]);
    pushup(x);
    return x;
  }
} t;
void dfs(int x, int fa) {
  rt[x] = t.new_node(s[x]);
  int lst = 0;
  for (int i = head[x]; ~i; i = e[i].nxt) {
    int v = e[i].to;
    if (v == fa) continue;
    dfs(v, x);
    if (!lst)
      lst = v;
    else
      rt[lst] = t.comb(rt[lst], rt[v]);
  }
  if (lst) {
    int u = t.ch[rt[x]][t.id(s[x])];
    for (int i = 0; i < 26; ++i) t.ch[u][i] = t.ch[rt[lst]][i];
    t.pushup(u);
    t.pushup(rt[x]);
  }
  diff[x] = t.v[rt[x]] - 1;
}
int main() {
  memset(head, -1, sizeof(head));
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  scanf("%s", s + 1);
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    addedge(x, y);
    addedge(y, x);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; ++i) {
    if ((a[i] + diff[i]) > maxn) {
      maxn = a[i] + diff[i];
      tot = 1;
    } else if (a[i] + diff[i] == maxn) {
      ++tot;
    }
  }
  printf("%d\n%d\n", maxn, tot);
  return 0;
}
