#include <bits/stdc++.h>
using namespace std;
struct node {
  int idx;
  node *ch[26];
} nodepool[300100], *ntp;
node *newnode(int x) {
  for (int i = (0); i < (26); ++i) ntp->ch[i] = 0;
  ntp->idx = x;
  return ntp++;
}
vector<int> g[300100];
int c[300100];
int si[300100];
char s[300100];
int ans = -21e8, ansi;
node *root[300100];
void gogo(node *L, node *R) {
  for (int i = (0); i < (26); ++i) {
    if (R->ch[i]) {
      if (!L->ch[i]) {
        L->ch[i] = R->ch[i];
        si[L->idx] += si[R->ch[i]->idx];
      } else {
        si[L->idx] -= si[L->ch[i]->idx];
        gogo(L->ch[i], R->ch[i]);
        si[L->idx] += si[L->ch[i]->idx];
      }
    }
  }
}
void go(int x, int p) {
  int son = 0, soni = -1;
  for (int i = (0); i < (((int)(g[x]).size())); ++i) {
    int u = g[x][i];
    if (u == p) continue;
    go(u, x);
    if (si[u] > son) {
      son = si[u];
      soni = u;
    }
  }
  root[x] = newnode(x);
  son++;
  if (soni != -1) {
    root[x]->ch[s[soni] - 'a'] = root[soni];
  }
  for (int i = (0); i < (((int)(g[x]).size())); ++i) {
    int u = g[x][i];
    if (u == p || u == soni) continue;
    node *L = root[x], *R = root[u];
    if (!L->ch[s[u] - 'a']) {
      L->ch[s[u] - 'a'] = R;
      son += si[u];
    } else {
      son -= si[L->ch[s[u] - 'a']->idx];
      gogo(L->ch[s[u] - 'a'], R);
      son += si[L->ch[s[u] - 'a']->idx];
    }
  }
  if (son + c[x] > ans) {
    ans = son + c[x];
    ansi = 1;
  } else if (son + c[x] == ans) {
    ansi++;
  }
  si[x] = son;
}
int main() {
  ntp = nodepool;
  int(n);
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%d", &(c[i]));
  scanf("%s", (s));
  int A, B;
  for (int i = (1); i < (n); ++i) {
    scanf("%d%d", &(A), &(B));
    A--;
    B--;
    g[A].push_back(B);
    g[B].push_back(A);
  }
  go(0, -1);
  cout << ans << endl << ansi << endl;
  return 0;
}
