#include <bits/stdc++.h>
using namespace std;
const int maxn = 200100, maxm = 500100;
const long long infinit = 0x007f7f7f7f7f7f7fll;
class TreeDP {
 public:
  struct edge {
    int u, v;
    edge *next;
  };
  int n, root, ecnt;
  edge *edges[maxn], epool[maxm];
  long long val[maxn], sum[maxn];
  long long dp[maxn][3];
  int depth[maxn], size[maxn];
  void add_edge(int u, int v) {
    edge *p = &epool[++ecnt], *q = &epool[++ecnt];
    p->u = u;
    p->v = v;
    p->next = edges[u];
    edges[u] = p;
    q->u = v;
    q->v = u;
    q->next = edges[v];
    edges[v] = q;
    return;
  }
  void dfs1(int p) {
    size[p] = 1;
    sum[p] = val[p];
    for (edge *ep = edges[p]; ep; ep = ep->next)
      if (!depth[ep->v]) {
        depth[ep->v] = depth[p] + 1;
        dfs1(ep->v);
        size[p] += size[ep->v];
        sum[p] += sum[ep->v];
      }
    return;
  }
  void dfs2(int p) {
    dp[p][1] = sum[p];
    dp[p][2] = -infinit;
    long long longest = -infinit, s_longest = -infinit;
    for (edge *ep = edges[p]; ep; ep = ep->next)
      if (depth[ep->v] == depth[p] + 1) {
        dfs2(ep->v);
        dp[p][1] = max(dp[p][1], dp[ep->v][1]);
        dp[p][2] = max(dp[p][2], dp[ep->v][2]);
        if (dp[ep->v][1] >= longest)
          s_longest = longest, longest = dp[ep->v][1];
        else if (dp[ep->v][1] >= s_longest)
          s_longest = dp[ep->v][1];
      }
    if (longest > -infinit && s_longest > -infinit)
      dp[p][2] = max(dp[p][2], longest + s_longest);
    return;
  }
  long long eval(void) {
    depth[root] = 1;
    dfs1(root);
    dfs2(root);
    return dp[root][2];
  }
} graph;
int n;
int main(int argc, char **argv) {
  scanf("%d", &n);
  graph.n = n;
  graph.root = 1;
  for (int i = 1; i <= n; i++) scanf("%lld", &graph.val[i]);
  for (int i = 1, a, b; i <= n - 1; i++) {
    scanf("%d%d", &a, &b);
    graph.add_edge(a, b);
  }
  long long res = graph.eval();
  if (res == -infinit)
    printf("Impossible\n");
  else
    printf("%lld\n", res);
  return 0;
}
