#include <bits/stdc++.h>
using namespace std;
const int maxn = 300010, INF = 0x3f3f3f3f;
template <typename Tp>
inline int getmin(Tp &x, Tp y) {
  return y < x ? x = y, 1 : 0;
}
template <typename Tp>
inline int getmax(Tp &x, Tp y) {
  return y > x ? x = y, 1 : 0;
}
template <typename Tp>
inline void read(Tp &x) {
  x = 0;
  int f = 0;
  char ch = getchar();
  while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
  if (ch == '-') f = 1, ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  if (f) x = -x;
}
struct data {
  int v, nxt;
} edge[maxn << 1];
int n, p, k, tot, head[maxn], w[maxn], mark[maxn];
long long mx = -INF, f[maxn];
void insert(int u, int v) {
  edge[++p] = (data){v, head[u]};
  head[u] = p;
  edge[++p] = (data){u, head[v]};
  head[v] = p;
}
void input() {
  int u, v;
  read(n);
  for (int i = 1; i <= n; i++) read(w[i]);
  for (int i = 1; i < n; i++) {
    read(u);
    read(v);
    insert(u, v);
  }
}
void dp(int x, int pre) {
  f[x] = w[x];
  for (int i = head[x]; i; i = edge[i].nxt)
    if (edge[i].v ^ pre) {
      dp(edge[i].v, x);
      if (f[edge[i].v] > 0) f[x] += f[edge[i].v], mark[edge[i].v] = 1;
    }
  getmax(mx, f[x]);
}
void getans(int x, int pre) {
  f[x] = w[x];
  for (int i = head[x]; i; i = edge[i].nxt)
    if (edge[i].v ^ pre) {
      getans(edge[i].v, x);
      if (f[edge[i].v] > 0) f[x] += f[edge[i].v], mark[edge[i].v] = 1;
    }
  if (f[x] == mx) ++k, f[x] = 0;
}
int main() {
  input();
  dp(1, 1);
  getans(1, 1);
  printf("%lld %d\n", mx * k, k);
  return 0;
}
