import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;

public class B_102 implements Runnable{

    public void solve(){
        String s  = scan.next();
        BigInteger b = new BigInteger(s);
        // int n = scan.nextInt();
        BigInteger bb = new BigInteger("10");
        long count = 0;
        while(!b.divide(bb).equals(BigInteger.ZERO)){
            // b = b.divide(bb);
            BigInteger k = b;
            long sum = 0;
            while(!k.equals(BigInteger.ZERO)){
                sum += k.mod(BigInteger.valueOf(10L)).longValue();
                k = k.divide(bb);

            }
            b = BigInteger.valueOf(sum);
            count++;
            // System.out.println(b.toString());
        }
        out.print(count);
    }

    InputReader scan;
    PrintWriter out;

    @Override
    public void run(){
        scan = new InputReader(System.in);
        out = new PrintWriter(System.out);
        solve();
        out.flush();
        out.close();
    }

    public static void main(String[] args) {
        new Thread(null,new B_102(),"Main",1<<26).start();
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars==-1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                }
                catch (IOException e) {
                    throw new InputMismatchException();
                }

                if(numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
        public int nextInt() {
            int c = read();

            while(isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if(c<'0'||c>'9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
                return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public long[] nla(int n){ //nextLongArray()
            long ar[] = new long[n];
            for(int i=0;i<n;i++){
                ar[i] = this.nextLong();
            }
            return ar;
        }

        public int[] nia(int n){
            int ar[] = new int[n];
            for(int i=0;i<n;i++){
                ar[i] = this.nextInt();
            }
            return ar;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

}


import java.util.Scanner;
public class abdo  {
public static void main(String[] args){
Scanner abd = new Scanner(System.in);
        String a=abd.next();
        int n=a.length(),s=0,sum=0,k=0,w=0;
        char[]x=new char[n];
        int[]z=new int[n];
        for(int i=0;i<n;i++){
            x[i]=a.charAt(i);
            z[i]=(int)x[i];
            s=z[i]-48;
            sum+=s;
        }
        if(sum==0){
            System.out.println(w);
            return;
        }
        if(sum/10<=0&&n>1){
            System.out.println(w+1);
            return;
        }
        if(sum/10<=0){
            System.out.println(w);
            return;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                 w=i;
              k+=sum%10;
              sum=sum/10;
            }
            if(k/10>0){
                int tmp=k;
                k=sum;
                sum=tmp;
            }
            else
              break;
        }

        System.out.println(w+1);
}}


import java.util.Scanner;
public class abdo  {
public static void main(String[] args){
Scanner abd = new Scanner(System.in);
        String a=abd.next();
        int n=a.length(),s=0,sum=0,k=0,w=0;
        char[]x=new char[n];
        int[]z=new int[n];
        for(int i=0;i<n;i++){
            x[i]=a.charAt(i);
            z[i]=(int)x[i];
            s=z[i]-48;
            sum+=s;
        }
        if(sum==0){
            System.out.println(w);
            return;
        }
        if(sum/10<=0){
            System.out.println(w+1);
            return;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                 w=i;
              k+=sum%10;
              sum=sum/10;
            }
            if(k/10>0){
                int tmp=k;
                k=sum;
                sum=tmp;
            }
            else
              break;
        }

        System.out.println(w+1);
}}


import static java.lang.Integer.max;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import javafx.geometry.Point2D;
import javax.swing.JOptionPane;

/**
 *
 * @author Abdelrahman Mamdouh
 */
public class Abdo {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Scanner abd = new Scanner(System.in);
        String a=abd.next();
        int n=a.length(),s=0,sum=0,k=10,w=0;
        char c;
        if(n<2){
            System.out.println(0);
            return;
        }
        while(k>=10){
            k=0;
            for(int i=0;i<a.length();i++){
                c=a.charAt(i);
                s=(int)c-48;
                k+=s;
            }
            a=String.valueOf(k);
            w++;
        }

        System.out.println(w);
    }
}


import static java.lang.Integer.max;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import javafx.geometry.Point2D;
import javax.swing.JOptionPane;

/**
 *
 * @author Abdelrahman Mamdouh
 */
public class Abdo {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Scanner abd = new Scanner(System.in);
        String a=abd.next();
        int n=a.length(),s=0,sum=0,k=10,w=0;
        char c;
        if(n<2)System.out.println(0);
        while(k>=10){
            k=0;
            for(int i=0;i<a.length();i++){
                c=a.charAt(i);
                s=(int)c-48;
                k+=s;
            }
            a=String.valueOf(k);
            w++;
        }

        System.out.println(w);
    }
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
int a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-1;
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end());
	q[x]=max(t[x],q[x]);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	if(ans==-1) cout<<"Impossible"<<endl;
	else cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
int a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-2147483600;
bool cmp(LL x,LL y)
{
	return x>y;
}
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	q[x]=-21483600;
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end(),cmp);
	q[x]=max(t[x],q[x]);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	if(ans==-2147483600) cout<<"Impossible"<<endl;
	else cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
int a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-1;
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end());
	q[x]=max(t[x],q[x]);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
LL a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-222147483600ll;
bool cmp(LL x,LL y)
{
	return x>y;
}
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	q[x]=-2221483600ll;
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end(),cmp);
	q[x]=max(t[x],q[x]);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	if(ans==-222147483600ll) cout<<"Impossible"<<endl;
	else cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
int a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-2147483600;
bool cmp(LL x,LL y)
{
	return x>y;
}
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	q[x]=-21483600;
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end());
	q[x]=max(t[x],q[x],cmp);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	if(ans==-2147483600) cout<<"Impossible"<<endl;
	else cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
int a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-2147483600;
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	q[x]=-21483600;
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end());
	q[x]=max(t[x],q[x]);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	if(ans==-2147483600) cout<<"Impossible"<<endl;
	else cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
typedef long long LL;
using namespace std;
int n;
int a[200010]={};
vector<int> e[200010];
LL t[200010]={};
LL q[200010]={};
int s,b;
LL ans=-22147483600ll;
bool cmp(LL x,LL y)
{
	return x>y;
}
void dfs(int x,int y)
{
	vector<LL> w;
	t[x]+=a[x];
	q[x]=-221483600ll;
	for(int i=0;i<e[x].size();i++)
	{
		if(e[x][i]==y) continue;
		dfs(e[x][i],x);
		t[x]+=t[e[x][i]];
		q[x]=max(q[x],q[e[x][i]]);
		w.pb(q[e[x][i]]);
	}
	sort(w.begin(),w.end(),cmp);
	q[x]=max(t[x],q[x]);
	if(w.size()>=2)
	{
		ans=max(w[0]+w[1],ans);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&s,&b);
		e[s].pb(b);
		e[b].pb(s);
	}
	dfs(1,0);
	if(ans==-22147483600ll) cout<<"Impossible"<<endl;
	else cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
const int maxn=500500;
ll val[maxn],f[maxn],ans=-inf;
int n,cnt,head[maxn];
struct node{int to,next;}e[maxn];
void add(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
void dfs(int rt,int fa)
{
     for(int i=head[rt];i;i=e[i].next)
     {
	 if(fa==e[i].to)continue;
         dfs(e[i].to,rt);
	 val[rt]+=val[e[i].to];
	 ans=max(ans,f[rt]+f[e[i].to]);
	 f[rt]=max(f[rt],f[e[i].to]);
     }f[rt]=max(f[rt],val[rt]);
}
int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%I64d",&val[i]),f[i]=-inf;
    for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    if(n==1){printf("Impossible\n");return 0;}
    dfs(1,-1);printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans=-inf,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			sum[rt]=max(sum[rt],sum[e[i].to]);
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=max(last[rt]+mx[rt][2],max(last[rt],mx[rt][2]));
	       else last[e[i].to]=max(last[rt]+mx[rt][1],max(last[rt],mx[rt][1]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("Impossible\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
const int maxn=500500;
ll val[maxn],f[maxn],ans=-inf;
int n,cnt,head[maxn];
struct node
{
	int to,next;
}e[maxn];
void add(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
void dfs(int rt,int fa)
{
     for(int i=head[rt];i;i=e[i].next)
     {
	 if(fa==e[i].to)continue;
         dfs(e[i].to,rt);
	 val[rt]+=val[e[i].to];
	 ans=max(ans,f[rt]+f[e[i].to]);
	 f[rt]=max(f[rt],f[e[i].to]);
     }f[rt]=max(f[rt],val[rt]);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%I64d",&val[i]);
    for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    if(n==1){printf("Impossible\n");return 0;}
    dfs(1,-1);printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 0x7fffffff
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
		        //printf("edge  %d %d\n",rt,e[i].to);
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}//printf("rt==%d sum==%I64d\n",rt,sum[rt]);
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=max(last[rt]+mx[rt][2],max(last[rt],mx[rt][2]));
	       else last[e[i].to]=max(last[rt]+mx[rt][1],max(last[rt],mx[rt][1]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   if(n==1){printf("-1\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);//printf("%I64d  %I64d\n",sum[i],last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
const int maxn=500500;
ll val[maxn],f[maxn],ans=-inf;
int n,cnt,head[maxn];
struct node{int to,next;}e[maxn];
void add(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
void dfs(int rt,int fa)
{
     for(int i=head[rt];i;i=e[i].next)
     {
	 if(fa==e[i].to)continue;
         dfs(e[i].to,rt);
	 val[rt]+=val[e[i].to];
	 if(f[rt]!=-inf)
	 ans=max(ans,f[rt]+f[e[i].to]);
	 f[rt]=max(f[rt],f[e[i].to]);
     }f[rt]=max(f[rt],val[rt]);
}
int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%I64d",&val[i]),f[i]=-inf;
    for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    if(n==1){printf("Impossible\n");return 0;}
    dfs(1,-1);if(ans>-inf)printf("%I64d\n",ans);else printf("Impossible\n");
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			sum[rt]=max(sum[rt],sum[e[i].to]);
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=max(last[rt]+mx[rt][2],max(last[rt],mx[rt][2]));
	       else last[e[i].to]=max(last[rt]+mx[rt][1],max(last[rt],mx[rt][1]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("-1\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			sum[rt]=max(sum[rt],sum[e[i].to]);
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=max(last[rt]+mx[rt][2],max(last[rt],mx[rt][2]));
	       else last[e[i].to]=max(last[rt]+mx[rt][1],max(last[rt],mx[rt][1]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("Impossible\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=max(last[rt]+mx[rt][2],max(last[rt],mx[rt][2]));
	       else last[e[i].to]=max(last[rt]+mx[rt][1],max(last[rt],mx[rt][1]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("-1\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
const int maxn=500500;
ll val[maxn],f[maxn],ans=-inf;
int n,cnt,head[maxn];
struct node
{
	int to,next;
}e[maxn];
void add(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
void dfs(int rt,int fa)
{
     for(int i=head[rt];i;i=e[i].next)
     {
	 if(fa==e[i].to)continue;
         dfs(e[i].to,rt);
	 val[rt]+=val[e[i].to];
	 ans=max(ans,f[rt]+f[e[i].to]);
	 f[rt]=max(f[rt],f[e[i].to]);
     }f[rt]=max(f[rt],val[rt]);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%I64d",&val[i]);
    for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    if(n==1){printf("Impossilbe\n");return 0;}
    dfs(1,-1);printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 0x7fffffff
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=max(last[rt]+mx[rt][2],max(last[rt],mx[rt][2]));
	       else last[e[i].to]=max(last[rt]+mx[rt][1],max(last[rt],mx[rt][1]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("-1\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans=-inf,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			sum[rt]=max(sum[rt],sum[e[i].to]);
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               if(e[i].to==hmx[rt][1])last[e[i].to]=last[rt]+sum[rt]-sum[e[i].to];
	       else last[e[i].to]=last[rt]+sum[rt]-sum[e[i].to];
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("-1\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define inf 1e16
using namespace std;
ll a[500500],mx[500500][3],xw[500500][3],last[500050],ans=-inf,sum[500050];
int n,cnt,tot,head[500050],hxw[500500][3],hmx[500500][3];
struct node{int next,to;}e[500500];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int rt,int fa)
{
	for(int i=head[rt];i;i=e[i].next)
	if(e[i].to!=fa)
	{
			dfs(e[i].to,rt);
			sum[rt]+=sum[e[i].to];
			ll res=sum[e[i].to];
			sum[rt]=max(sum[rt],sum[e[i].to]);
			for(int j=2;j>=1;j--)
			{
				if(res>=mx[rt][j])
				{
					mx[rt][j+1]=mx[rt][j],hmx[rt][j+1]=hmx[rt][j];
					mx[rt][j]=res,hmx[rt][j]=e[i].to;
				}
			}
	}
}
void dfs2(int rt,int fa)
{
       for(int i=head[rt];i;i=e[i].next)
       if(e[i].to!=fa)
       {
               last[e[i].to]=max(last[rt]+sum[rt]-sum[e[i].to],max(last[rt],sum[rt]-sum[e[i].to]));
	       dfs2(e[i].to,rt);
       }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),sum[i]=a[i];
   for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u);
   for(int i=1;i<=n;i++)mx[i][1]=mx[i][2]=-inf;
   if(n==1){printf("-1\n");return 0;}
   dfs(1,-1);
   dfs2(1,-1);
   for(int i=2;i<=n;i++)ans=max(ans,sum[i]+last[i]);
   printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
ll INF = -(1LL<<50LL);
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    res+=dfs(G[x][i]);;
    memo2[x]=max(memo2[x],memo2[G[x][i]]);
  }
  memo2[x]=max(memo2[x],res);
  return memo[x]=res;
}
ll dfs2(ll x){
  ll res=INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    res=max(res,dfs2(G[x][i]));
    q.push(memo2[G[x][i]]);
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n,r=0;
  cin>>n;
  bool used[n];
  for(ll i=0;i<n;i++) cin>>a[i],used[i]=0,memo[i]=INF,memo2[i]=a[i];
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
    used[v-1]=1;
  }
  for(ll i=0;i<n;i++) if(!used[i]) r=i;
  dfs(r);
  ll ans=dfs2(r);
  //for(ll i=0;i<n;i++) cout << i << ":" << memo[i] <<"/"<< memo2[i]<<endl;
  if(ans==INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
#define INF 1<<25LL
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    ll r = dfs(G[x][i]);
    res+=r;
    memo2[x]=max(memo2[x],r);
  }
  return memo[x]=res;
}
ll dfs2(ll x){
  ll res=-INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    res=max(res,dfs2(G[x][i]));
    q.push(max(memo[G[x][i]],memo2[G[x][i]]));
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n,r=0;
  cin>>n;
  bool used[n];
  for(ll i=0;i<n;i++) cin>>a[i],used[i]=0,memo[i]=memo2[i]=-INF;
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
    used[v-1]=1;
  }
  for(ll i=0;i<n;i++) if(!used[i]) r=i;
  dfs(r);
  ll ans=dfs2(r);
  if(ans==-INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
ll INF = -(1LL<<50LL);
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x,ll p){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    if(G[x][i]==p) continue;
    res+=dfs(G[x][i],x);
    memo2[x]=max(memo2[x],memo2[G[x][i]]);
  }
  memo2[x]=max(memo2[x],res);
  return memo[x]=res;
}
ll dfs2(ll x, ll p){
  ll res=INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    if(G[x][i]==p) continue;
    res=max(res,dfs2(G[x][i],x));
    q.push(memo2[G[x][i]]);
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n;
  cin>>n;
  for(ll i=0;i<n;i++) cin>>a[i],memo[i]=INF,memo2[i]=INF;
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
    G[v-1].push_back(u-1);
  }
  dfs(0,-1);
  ll ans=dfs2(0,-1);
  //for(ll i=0;i<n;i++) cout << i << ":" << memo[i] <<"/"<< memo2[i]<<endl;
  if(ans==INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
ll INF = LLONG_MIN;
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    ll r = dfs(G[x][i]);
    res+=r;
    memo2[x]=max(memo2[x],r);
  }
  memo2[x]=max(memo2[x],res);
  return memo[x]=res;
}
ll dfs2(ll x){
  ll res=INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    res=max(res,dfs2(G[x][i]));
    q.push(memo2[G[x][i]]);
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n,r=0;
  cin>>n;
  bool used[n];
  for(ll i=0;i<n;i++) cin>>a[i],used[i]=0,memo[i]=memo2[i]=INF;
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
    used[v-1]=1;
  }
  for(ll i=0;i<n;i++) if(!used[i]) r=i;
  dfs(r);
  ll ans=dfs2(r);
  if(ans==INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
#define INF 1LL<<50LL
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    ll r = dfs(G[x][i]);
    res+=r;
    memo2[x]=max(memo2[x],r);
  }
  return memo[x]=res;
}
ll dfs2(ll x){
  ll res=-INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    res=max(res,dfs2(G[x][i]));
    q.push(max(memo[G[x][i]],memo2[G[x][i]]));
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n,r=0;
  cin>>n;
  bool used[n];
  for(ll i=0;i<n;i++) cin>>a[i],used[i]=0,memo[i]=memo2[i]=-INF;
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
    used[v-1]=1;
  }
  for(ll i=0;i<n;i++) if(!used[i]) r=i;
  dfs(r);
  ll ans=dfs2(r);
  if(ans==-INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
ll INF = -(1LL<<50LL);
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    ll r = dfs(G[x][i]);
    res+=r;
    memo2[x]=max(memo2[x],memo2[G[x][i]]);
  }
  memo2[x]=max(memo2[x],res);
  return memo[x]=res;
}
ll dfs2(ll x){
  ll res=INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    res=max(res,dfs2(G[x][i]));
    q.push(memo2[G[x][i]]);
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n,r=0;
  cin>>n;
  bool used[n];
  for(ll i=0;i<n;i++) cin>>a[i],used[i]=0,memo[i]=memo2[i]=INF;
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
    used[v-1]=1;
  }
  for(ll i=0;i<n;i++) if(!used[i]) r=i;
  dfs(r);
  ll ans=dfs2(r);
  //for(ll i=0;i<n;i++) cout << i << ":" << memo[i] <<"/"<< memo2[i]<<endl;
  if(ans==INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_V 200050
ll INF = -(1LL<<50LL);
vector<ll> G[MAX_V];
ll a[MAX_V],memo[MAX_V],memo2[MAX_V];
ll dfs(ll x){
  ll res=a[x];
  for(ll i=0;i<(ll)G[x].size();i++){
    res+=dfs(G[x][i]);
    memo2[x]=max(memo2[x],memo2[G[x][i]]);
  }
  memo2[x]=max(memo2[x],res);
  return memo[x]=res;
}
ll dfs2(ll x){
  ll res=INF;
  priority_queue<ll> q;
  for(ll i=0;i<(ll)G[x].size();i++) {
    res=max(res,dfs2(G[x][i]));
    q.push(memo2[G[x][i]]);
  }
  if(q.size()>1){
    ll m1,m2;
    m1=q.top();q.pop();
    m2=q.top();q.pop();
    res=max(res,m1+m2);
  }
  return res;
}
int main(){
  ll n;
  cin>>n;
  for(ll i=0;i<n;i++) cin>>a[i],memo[i]=INF,memo2[i]=INF;
  for(ll i=0;i<n-1;i++){
    ll u,v;
    cin>>u>>v;
    G[u-1].push_back(v-1);
  }
  dfs(0);
  ll ans=dfs2(0);
  //for(ll i=0;i<n;i++) cout << i << ":" << memo[i] <<"/"<< memo2[i]<<endl;
  if(ans==INF) cout << "Impossible" << endl;
  else cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010],sum[200010],size[200010],prem[200010];
int ma[200010];
list<int> e[200010];
int rt,ans;
int max(int a,int b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=INT_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	//if(size[u]==1)ma[u]=pl[u];
	ma[u]=max(ma[u],sum[u]);
}
int sol(int u){
	priority_queue<int> Q;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		Q.push(ma[v]);
	}
	int ret=Q.top();Q.pop();
	if(!Q.empty()&&Q.top()>=0)return ret+=Q.top();
	return ret;
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	if(n==1)
		printf("-1\n");
	else{
		rt=-1;
		pr(0,0);
		int t=sol(0);
		ans=max(ans,t);
		for(int i=0;i<n;i++)
			if(size[i]==1&&pl[i]==ans){
				rt=i;
				pr(0,0);
				t=sol(0);
				ans+=t;
			}
		printf("%d\n",ans);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010];
long long sum[200010],ma[200010];
int size[200010],prem[200010];
list<int> e[200010];
int rt;
long long max(long long a,long long b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=LLONG_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	ma[u]=max(ma[u],sum[u]);
}
long long sol(int u){
		if(size[u]==1)return LLONG_MIN;
	priority_queue<long long> Q;
	bool found=false;
	long long ret=LLONG_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		ret=max(ret,sol(v));
		Q.push(ma[v]);
	}
	long long tmp=Q.top();
	Q.pop();
	if(Q.empty())return ret;
	tmp+=Q.top();
	return max(tmp,ret);
}
bool line(int u){
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[u]==size[v]+1)
			return line(v);
		else
			return false;
	}
	return true;
}
long long ans;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		//ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pr(0,0);
	if(line(0))
		printf("Impossible\n");
	else{
		ans=sol(0);
		//printf("%I64d\n",ans);
		cout<<ans<<endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010];
long long sum[200010],ma[200010];
int size[200010],prem[200010];
list<int> e[200010];
int rt;
long long max(long long a,long long b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=LLONG_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	//if(size[u]==1)ma[u]=pl[u];
	ma[u]=max(ma[u],sum[u]);
}
long long sol(int u){
	if(size[u]==1)return pl[u];
	priority_queue<long long> Q;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[v]==size[u]-1)
			return(sol(v));
		Q.push(ma[v]);
	}
	long long ret=Q.top();Q.pop();
	//if(!Q.empty()&&Q.top()>=0)return ret+=Q.top();
	//if(Q.empty())ret=-1;//sol(*e[u].begin());else
		ret+=Q.top();

	return ret;
}
bool line(int u){
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[u]==size[v]+1)
			return line(v);
		else
			return false;
	}
	return true;
}
long long ans;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		//ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pr(0,0);
	if(line(0))
		printf("Impossible\n");
	else{
		ans=sol(0);
		//printf("%I64d\n",ans);
		cout<<ans<<endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010];
long long sum[200010],ma[200010];
int size[200010],prem[200010];
list<int> e[200010];
int rt;
long long max(long long a,long long b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=LLONG_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	ma[u]=max(ma[u],sum[u]);
}
long long sol(int u){
	priority_queue<long long> Q;
	bool found=false;
	long long ret=LLONG_MIN;
	while(!found){
		if(size[u]==1)return LLONG_MIN;
		found=true;
		for(auto p=e[u].begin();p!=e[u].end();p++){
			int v=*p;
			if(v==prem[u])continue;
			if(size[v]==size[u]-1){
				u=v;
				found=false;
				break;
			}
			ret=max(ret,sol(v));
			Q.push(ma[v]);
		}
	}
	ret=max(ret,Q.top());
	Q.pop();
	ret+=Q.top();
	return ret;
}
bool line(int u){
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[u]==size[v]+1)
			return line(v);
		else
			return false;
	}
	return true;
}
long long ans;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		//ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pr(0,0);
	if(line(0))
		printf("Impossible\n");
	else{
		ans=sol(0);
		//printf("%I64d\n",ans);
		cout<<ans<<endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010],sum[200010],size[200010],prem[200010];
int ma[200010];
list<int> e[200010];
int rt,ans;
int max(int a,int b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=INT_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	//if(size[u]==1)ma[u]=pl[u];
	ma[u]=max(ma[u],sum[u]);
}
int sol(int u){
	priority_queue<int> Q;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		Q.push(ma[v]);
	}
	int ret=Q.top();Q.pop();
	if(!Q.empty()&&Q.top()>=0)return ret+=Q.top();
	return ret;
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	if(n==1)
		printf("Impossible\n");
	else{
		rt=-1;
		pr(0,0);
		int t=sol(0);
		ans=max(ans,t);
		for(int i=0;i<n;i++)
			if(size[i]==1&&pl[i]==ans){
				rt=i;
				pr(0,0);
				t=sol(0);
				ans+=t;
			}
		printf("%d\n",ans);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010],sum[200010],size[200010],prem[200010];
int ma[200010];
list<int> e[200010];
int rt,ans;
int max(int a,int b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=INT_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	//if(size[u]==1)ma[u]=pl[u];
	ma[u]=max(ma[u],sum[u]);
}
int sol(int u){
	if(size[u]==1)return pl[u];
	priority_queue<int> Q;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[v]==size[u]-1)
			return(sol(v));
		Q.push(ma[v]);
	}
	int ret=Q.top();Q.pop();
	//if(!Q.empty()&&Q.top()>=0)return ret+=Q.top();
	//if(Q.empty())ret=-1;//sol(*e[u].begin());else
		ret+=Q.top();

	return ret;
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	if(n==1)
		printf("Impossible\n");
	else{
		rt=-1;
		pr(0,0);
		int t=sol(0);
		ans=INT_MIN;
		ans=max(ans,t);
		if(false)
		for(int i=0;i<n;i++)
			if(size[i]==1&&pl[i]==ans){
				rt=i;
				pr(0,0);
				t=sol(0);
				ans+=t;
			}
		printf("%d\n",ans);
	}

	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,pl[200010];
long long sum[200010],ma[200010];
int size[200010],prem[200010];
list<int> e[200010];
int rt;
long long max(long long a,long long b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=LLONG_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	//if(size[u]==1)ma[u]=pl[u];
	ma[u]=max(ma[u],sum[u]);
}
long long sol(int u){
	if(size[u]==1)return pl[u];
	priority_queue<long long> Q;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[v]==size[u]-1)
			return(sol(v));
		Q.push(ma[v]);
	}
	long long ret=Q.top();Q.pop();
	//if(!Q.empty()&&Q.top()>=0)return ret+=Q.top();
	//if(Q.empty())ret=-1;//sol(*e[u].begin());else
		ret+=Q.top();

	return ret;
}
bool line(int u){
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[u]==size[v]+1)
			return line(v);
		else
			return false;
	}
	return true;
}
long long ans;
signed main(){
	//scanf("%d",&n);
	cin>>n;
	for(int i=0;i<n;i++){
		//scanf("%d",&pl[i]);
		cin>>pl[i];
		//ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		//scanf("%d%d",&u,&v);
		cin>>u>>v;
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pr(0,0);
	if(line(0))
		printf("Impossible\n");
	else{
		ans=sol(0);
		//printf("%I64d\n",ans);
		cout<<ans<<endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,pl[200010],sum[200010],size[200010],prem[200010];
int ma[200010];
list<int> e[200010];
int rt,ans;
int max(int a,int b){return a>b?a:b;}
void pr(int u,int pre){
	prem[u]=pre;
	sum[u]=pl[u];
	size[u]=1;
	ma[u]=INT_MIN;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==pre||v==rt)continue;
		pr(v,u);
		sum[u]+=sum[v];
		size[u]+=size[v];
		ma[u]=max(ma[u],ma[v]);
	}
	//if(size[u]==1)ma[u]=pl[u];
	ma[u]=max(ma[u],sum[u]);
}
int sol(int u){
	if(size[u]==1)return pl[u];
	priority_queue<int> Q;
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[v]==size[u]-1)
			return(sol(v));
		Q.push(ma[v]);
	}
	int ret=Q.top();Q.pop();
	//if(!Q.empty()&&Q.top()>=0)return ret+=Q.top();
	//if(Q.empty())ret=-1;//sol(*e[u].begin());else
		ret+=Q.top();

	return ret;
}
bool line(int u){
	for(auto p=e[u].begin();p!=e[u].end();p++){
		int v=*p;
		if(v==prem[u])continue;
		if(size[u]==size[v]+1)
			return line(v);
		else
			return false;
	}
	return true;
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&pl[i]);
		ans+=pl[i];
	}
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--,v--;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pr(0,0);
	if(line(0))
		printf("Impossible\n");
	else{
		ans=sol(0);
		printf("%d\n",ans);
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;
const ll k_min_val = -1e16;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (sum[next] != k_min_val) continue;
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (dp[curr][0] != k_min_val) return;
    if (child[curr].size() == 0) {
        dp[curr][0] = sum[curr];
        dp[curr][1] = k_min_val;
        return;
    }

    dp[curr][0] = sum[curr];
    dp[curr][1] = k_min_val;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (dp[next][0] != k_min_val) continue;
        rec(next);
        dp[curr][0] = max(dp[next][0], dp[curr][0]);
        /*
        if (curr == 0)
            printf("!!!%d : [%lld]!!!\n", next+1, dp[next][1]);
        */
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < sum[next]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        sum[i] = k_min_val;
        dp[i][0] = k_min_val, dp[i][1] = k_min_val;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
        child[b].push_back(a);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == k_min_val) puts("Impossible");
    else printf("%lld\n", dp[0][1]);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;
const ll k_min_val = -1e16;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (sum[next] != k_min_val) continue;
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (dp[curr][0] != k_min_val) return;

    dp[curr][0] = sum[curr];
    dp[curr][1] = k_min_val;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (dp[next][0] != k_min_val) continue;
        rec(next);
        dp[curr][0] = max(dp[next][0], dp[curr][0]);
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < sum[next]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        sum[i] = k_min_val;
        dp[i][0] = k_min_val, dp[i][1] = k_min_val;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
        child[b].push_back(a);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == k_min_val)
        return puts("Impossible"), 0;
    ll ans = k_min_val;
    for (int i = 0; i < n; ++i) ans = max(ans, dp[i][1]);
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;
const ll k_min_val = -1e16;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (sum[next] != k_min_val) continue;
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (dp[curr][0] != k_min_val) return;

    dp[curr][0] = sum[curr];
    dp[curr][1] = k_min_val;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (dp[next][0] != k_min_val) continue;
        rec(next);
        dp[curr][0] = max(dp[next][0], dp[curr][0]);
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < sum[next]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        sum[i] = k_min_val;
        dp[i][0] = k_min_val, dp[i][1] = k_min_val;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
        child[b].push_back(a);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == k_min_val) puts("Impossible");
    ll ans = k_min_val;
    for (int i = 0; i < n; ++i) ans = max(ans, dp[i][1]);
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;
const ll k_min_val = -1e16;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (sum[next] != k_min_val) continue;
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (dp[curr][0] != k_min_val) return;
    if (child[curr].size() == 0) {
        dp[curr][0] = sum[curr];
        dp[curr][1] = k_min_val;
        return;
    }

    dp[curr][0] = sum[curr];
    dp[curr][1] = k_min_val;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (dp[next][0] != k_min_val) continue;
        rec(next);
        dp[curr][0] = max(sum[next], dp[curr][0]);
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < sum[next]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        sum[i] = k_min_val;
        dp[i][0] = k_min_val, dp[i][1] = k_min_val;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
        child[b].push_back(a);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == k_min_val) puts("Impossible");
    else printf("%lld\n", dp[0][1]);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;
const ll k_min_val = -1e16;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (sum[next] != k_min_val) continue;
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (dp[curr][0] != k_min_val) return;

    dp[curr][0] = sum[curr];
    dp[curr][1] = k_min_val;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (dp[next][0] != k_min_val) continue;
        rec(next);
        dp[curr][0] = max(dp[next][0], dp[curr][0]);
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < dp[next][0]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        sum[i] = k_min_val;
        dp[i][0] = k_min_val, dp[i][1] = k_min_val;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
        child[b].push_back(a);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == k_min_val)
        return puts("Impossible"), 0;
    ll ans = k_min_val;
    for (int i = 0; i < n; ++i) ans = max(ans, dp[i][1]);
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (child[curr].size() == 0) {
        dp[curr][0] = sum[curr];
        dp[curr][1] = -1e16;
        return;
    }

    dp[curr][0] = sum[curr];
    dp[curr][1] = -1e16;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        rec(next);
        dp[curr][0] = max(sum[next], dp[curr][0]);
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < sum[next]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        dp[i][0] = -1e16, dp[i][1] = -1e16;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == -1e16) puts("Impossible");
    else printf("%lld\n", dp[0][1]);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int k_max_n = 1e5 * 2 + 222;
const ll k_min_val = -1e16;

int n;
int a[k_max_n];
vector<int> child[k_max_n];
ll sum[k_max_n];
ll dp[k_max_n][2];

void get_sum(int curr)
{
    sum[curr] = (ll)a[curr];
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (sum[next] != k_min_val) continue;
        get_sum(next);
        sum[curr] += sum[next];
    }
    return;
}

void rec(int curr)
{
    if (dp[curr][0] != k_min_val) return;

    dp[curr][0] = sum[curr];
    dp[curr][1] = k_min_val;
    int idx1 = -1, idx2 = -1;
    ll mx1, mx2;
    for (int i = 0; i < child[curr].size(); ++i) {
        int next = child[curr][i];
        if (dp[next][0] != k_min_val) continue;
        rec(next);
        dp[curr][0] = max(dp[next][0], dp[curr][0]);
        dp[curr][1] = max(dp[next][1], dp[curr][1]);
        if (idx1 == -1) {
            idx1 = i, mx1 = dp[next][0];
        }
        else if (idx2 == -1 || mx2 < dp[next][0]) {
            idx2 = i, mx2 = dp[next][0];
        }
        if (mx2 > mx1) {
            swap(mx1, mx2), swap(idx1, idx2);
        }
    }
    if (idx1 != -1 && idx2 != -1) dp[curr][1] = max(dp[curr][1], mx1 + mx2);
    return;
}

int main()
{
    for (int i = 0; i < k_max_n; ++i) {
        sum[i] = k_min_val;
        dp[i][0] = k_min_val, dp[i][1] = k_min_val;
    }
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for (int i = 0; i < n-1; ++i) {
        int a, b; scanf("%d %d", &a, &b); --a, --b;
        child[a].push_back(b);
        child[b].push_back(a);
    }

    get_sum(0);
    rec(0);
    if (dp[0][1] == k_min_val)
        return puts("Impossible"), 0;
    printf("%lld\n", dp[0][1]);
    return 0;
}


#include <cstdio>
#include <iostream>

#define MAXN 300020
#define to(k) E[k].to
#define Fuck -23333333333LL

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt ;
long long N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;
        work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) dp[0] = max(dp[0], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;//dp[now]表示最大子树和（即只选取一颗子树，选取哪一棵）
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%I64d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (dp[0] > Fuck ? cout << dp[0] << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <cstdio>
#include <iostream>

#define MAXN 500020
#define to(k) E[k].to
#define Fuck -(1ll << 62)

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt ;
long long N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) dp[0] = max(dp[0], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;//dp[now]表示最大子树和（即只选取一颗子树，选取哪一棵）
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%I64d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (dp[0] > Fuck ? cout << dp[0] << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <cstdio>
#include <iostream>

#define MAXN 300020
#define to(k) E[k].to
#define Fuck -2333333

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt, ans ;
int N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;
        work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) ans = max(dp[now], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;//dp[now]表示最大子树和（即只选取一颗子树，选取哪一棵）
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (ans > Fuck ? cout << ans << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <cstdio>
#include <iostream>

#define MAXN 300020
#define to(k) E[k].to
#define Fuck -(1ll << 57)

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt ;
long long N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) dp[0] = max(dp[0], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;//dp[now]表示最大子树和（即只选取一颗子树，选取哪一棵）
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%I64d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (dp[0] > Fuck ? cout << dp[0] << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <cstdio>
#include <iostream>

#define MAXN 300020
#define to(k) E[k].to
#define Fuck -2333333

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt ;
int N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;
        work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) dp[0] = max(dp[0], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;//dp[now]表示最大子树和（即只选取一颗子树，选取哪一棵）
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (dp[0] > Fuck ? cout << dp[0] << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 200010
typedef long long LL;
const LL INF = 1LL<<60;
struct node
{
    int v, nxt;
}edge[N*2];
LL dp[N], sum[N], w[N], head[N], tot, ans;

void add(int u, int v) {
    edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
}

void dfs(int u, int fa) {
    sum[u] = w[u];
    for(int i = head[u]; ~i; i = edge[i].nxt) {
        int v = edge[i].v;
        if(v == fa) continue;
        dfs(v, u);
        sum[u] += sum[v];
        if(dp[u] > -INF) ans = max(ans, dp[u] + dp[v]);
        dp[u] = max(dp[u], dp[v]);
    }
    dp[u] = max(dp[u], sum[u]);
}

int main()
{
    int n;
    cin >> n;
    memset(head, -1, sizeof(head));
    for(int i = 1; i <= n; i++) cin >> w[i];
    for(int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        add(u, v); add(v, u);
    }
    ans = -INF;
    for(int i = 1; i <= n; i++) dp[i] = -INF;
    dfs(1, -1);
    if(ans <= -INF) puts("Impossible");
    else cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <iostream>

#define MAXN 300020
#define to(k) E[k].to
#define Fuck -2333333

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt ;
int N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;
        work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) dp[0] = max(dp[now], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;//dp[now]表示最大子树和（即只选取一颗子树，选取哪一棵）
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (dp[0] > Fuck ? cout << dp[0] << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <cstdio>
#include <iostream>

#define MAXN 300020
#define to(k) E[k].to
#define Fuck -2333333

using namespace std ;
struct Edge{
    int to, next ;
}E[MAXN] ; int head[MAXN], cnt ;
int N, base[MAXN], S[MAXN], dp[MAXN], A, B, i ;

inline void Add(int u, int v){
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
    E[++ cnt].to = u, E[cnt].next = head[v], head[v] = cnt ;
}
void work_on_dp(int now, int f){
    S[now] = base[now] ;
    for (int k = head[now] ; k ; k = E[k].next){
        if (f == E[k].to) continue ;
        work_on_dp(to(k), now) ;
        if (dp[now] > Fuck) dp[now] = max(dp[now], dp[now] + dp[to(k)]) ;
        S[now] += S[to(k)], dp[now] = max(dp[now], dp[to(k)]) ;
    }
    if (now!=1) dp[now] = max(dp[now], S[now]) ;
}
int main(){
    cin >> N ; fill(dp, dp + N + 2, Fuck) ;
    for (i = 1 ; i <= N ; ++ i) scanf("%d", &base[i]) ;
    for (i = 1 ; i < N ; ++ i) scanf("%d%d", &A, &B), Add(A, B) ;
    work_on_dp(1, 0) ;  (dp[1] > Fuck ? cout << dp[1] << endl : cout << "Impossible" << endl) ; return 0 ;
}


#include <bits/stdc++.h>
using namespace std;
long long values[100000],max_value;
bool flag1=0;
vector<vector<int>>v;
long long dfs(int node,int parent,long long a[]){
    if((node==0&&v[0].size()==0)||(node!=0&&v[node].size()==1)){
        values[node]=a[node];
        return a[node];
    }
    values[node]=a[node];
    int flag=0;
    long long lar1=0,lar2=0;
    for(int i=0;i<v[node].size();i++){
        long long temp;
        if(v[node][i]!=parent) {
        temp=dfs(v[node][i],node,a);
        if(flag==0){
            lar1=temp;
            flag=1;
        }
        else if(flag==1){
            if(lar1>temp) lar2=temp;
            else{
                lar2=lar1;
                lar1=temp;
            }
            flag=2;
            flag1=1;
        }
        else{
            if(temp>lar1){
                lar2=lar1;
                lar1=temp;
            }
            else if(temp>lar2){
                lar2=temp;
            }
        }
    }
    if(flag==2){
        if(flag1==0){
            max_value=lar1+lar2;
        }
        else{
            max_value=max(max_value,lar1+lar2);
        }
    }}
    for(int i=0;i<v[node].size();i++){
        if(v[node][i]!=parent) values[node]+=values[v[node][i]];
    }
    return max(values[node],lar1);
}
main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    long long a[n];
    v.resize(n);
    for(int i=0;i<n;i++) cin>>a[i];
    int t1,t2;
    for(int i=0;i<n-1;i++){
        cin>>t1>>t2;
        v[t1-1].push_back(t2-1);
        v[t2-1].push_back(t1-1);
    }
    dfs(0,-1,a);
    if(flag1==0) cout<<"Impossible";
    else cout<<max_value;
}


#include <bits/stdc++.h>
using namespace std;
long long values[100000],max_value;
bool flag1=0;
vector<vector<int>>v;
long long dfs(int node,int parent,long long a[]){
    if(v[node].size()==1){
        values[node]=a[node];
        return a[node];
    }
    values[node]=a[node];
    int flag=0;
    long long lar1,lar2;
    if(v[node].size()>2||node==0&&v[0].size()>1) flag1=1;
    for(int i=0;i<v[node].size();i++){
        long long temp;
        if(v[node][i]!=parent) temp=dfs(v[node][i],node,a);
        if(flag==0){
            lar1=temp;
            flag=1;
        }
        else if(flag==1){
            if(lar1>temp) lar2=temp;
            else{
                lar2=lar1;
                lar1=temp;
            }
            flag=2;
        }
        else{
            if(temp>lar1){
                lar2=lar1;
                lar1=temp;
            }
            else if(temp>lar2){
                lar2=temp;
            }
        }
    }
    if(flag==2){
        if(flag1==0){
            max_value=lar1+lar2;
        }
        else{
            max_value=max(max_value,lar1+lar2);
        }
    }
    for(int i=0;i<v[node].size();i++){
        if(v[node][i]!=parent) values[node]+=values[v[node][i]];
    }
    return max(values[node],lar1);
}
main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    long long a[n];
    v.resize(n);
    for(int i=0;i<n;i++) cin>>a[i];
    int t1,t2;
    for(int i=0;i<n-1;i++){
        cin>>t1>>t2;
        v[t1-1].push_back(t2-1);
        v[t2-1].push_back(t1-1);
    }
    dfs(0,-1,a);
    if(flag1==0) cout<<"Impossible";
    else cout<<max_value;

}


#include <bits/stdc++.h>
using namespace std;
long long values[200000],max_value;
bool flag1=0;
vector<vector<int>>v;
long long dfs(int node,int parent,long long a[]){
    if((node==0&&v[0].size()==0)||(node!=0&&v[node].size()==1)){
        values[node]=a[node];
        return a[node];
    }
    values[node]=a[node];
    int flag=0;
    long long lar1=0,lar2=0;
    for(int i=0;i<v[node].size();i++){
        long long temp;
        if(v[node][i]!=parent) {
        temp=dfs(v[node][i],node,a);
        if(flag==0){
            lar1=temp;
            flag=1;
        }
        else if(flag==1){
            if(lar1>temp) lar2=temp;
            else{
                lar2=lar1;
                lar1=temp;
            }
            flag=2;
        }
        else{
            if(temp>lar1){
                lar2=lar1;
                lar1=temp;
            }
            else if(temp>lar2){
                lar2=temp;
            }
        }
    }
    if(flag==2){
        if(flag1==0){
            max_value=lar1+lar2;
            flag1=1;
        }
        else{
            max_value=max(max_value,lar1+lar2);
        }
    }
    }
    for(int i=0;i<v[node].size();i++){
        if(v[node][i]!=parent) values[node]+=values[v[node][i]];
    }
    return max(values[node],lar1);
}
main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    long long a[n];
    v.resize(n);
    for(int i=0;i<n;i++) cin>>a[i];
    int t1,t2;
    for(int i=0;i<n-1;i++){
        cin>>t1>>t2;
        v[t1-1].push_back(t2-1);
        v[t2-1].push_back(t1-1);
    }
    dfs(0,-1,a);
    if(flag1==0) cout<<"Impossible";
    else cout<<max_value;
}


#include <bits/stdc++.h>
using namespace std;
long long values[100000],max_value;
bool flag1=0;
vector<vector<int>>v;
long long dfs(int node,int parent,long long a[]){
    if(v[node].size()==1){
        values[node]=a[node];
        return a[node];
    }
    values[node]=a[node];
    int flag=0;
    long long lar1=0,lar2=0;
    if(v[node].size()>2||node==0&&v[0].size()>1) flag1=1;
    for(int i=0;i<v[node].size();i++){
        long long temp;
        if(v[node][i]!=parent) {
        temp=dfs(v[node][i],node,a);
        if(flag==0){
            lar1=temp;
            flag=1;
        }
        else if(flag==1){
            if(lar1>temp) lar2=temp;
            else{
                lar2=lar1;
                lar1=temp;
            }
            flag=2;
        }
        else{
            if(temp>lar1){
                lar2=lar1;
                lar1=temp;
            }
            else if(temp>lar2){
                lar2=temp;
            }
        }
    }
    if(flag==2){
        if(flag1==0){
            max_value=lar1+lar2;
        }
        else{
            max_value=max(max_value,lar1+lar2);
        }
    }}
    for(int i=0;i<v[node].size();i++){
        if(v[node][i]!=parent) values[node]+=values[v[node][i]];
    }
    return max(values[node],lar1);
}
main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    long long a[n];
    v.resize(n);
    for(int i=0;i<n;i++) cin>>a[i];
    int t1,t2;
    for(int i=0;i<n-1;i++){
        cin>>t1>>t2;
        v[t1-1].push_back(t2-1);
        v[t2-1].push_back(t1-1);
    }
    dfs(0,-1,a);
    if(flag1==0) cout<<"Impossible";
    else cout<<max_value;

}


#include <bits/stdc++.h>
using namespace std;
long long values[100000],max_value;
bool flag1=0;
vector<vector<int>>v;
long long dfs(int node,int parent,long long a[]){
    if(v[node].size()==1){
        values[node]=a[node];
        return a[node];
    }
    values[node]=a[node];
    int flag=0;
    long long lar1=0,lar2=0;
    if(v[node].size()>2||node==0&&v[0].size()>1) flag1=1;
    for(int i=0;i<v[node].size();i++){
        long long temp;
        if(v[node][i]!=parent) temp=dfs(v[node][i],node,a);
        if(flag==0){
            lar1=temp;
            flag=1;
        }
        else if(flag==1){
            if(lar1>temp) lar2=temp;
            else{
                lar2=lar1;
                lar1=temp;
            }
            flag=2;
        }
        else{
            if(temp>lar1){
                lar2=lar1;
                lar1=temp;
            }
            else if(temp>lar2){
                lar2=temp;
            }
        }
    }
    if(flag==2){
        if(flag1==0){
            max_value=lar1+lar2;
        }
        else{
            max_value=max(max_value,lar1+lar2);
        }
    }
    for(int i=0;i<v[node].size();i++){
        if(v[node][i]!=parent) values[node]+=values[v[node][i]];
    }
    return max(values[node],lar1);
}
main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    long long a[n];
    v.resize(n);
    for(int i=0;i<n;i++) cin>>a[i];
    int t1,t2;
    for(int i=0;i<n-1;i++){
        cin>>t1>>t2;
        v[t1-1].push_back(t2-1);
        v[t2-1].push_back(t1-1);
    }
    dfs(0,-1,a);
    if(flag1==0) cout<<"Impossible";
    else cout<<max_value;

}


#include <bits/stdc++.h>
using namespace std;
long long values[100000],max_value;
bool flag1=0;
vector<vector<int>>v;
long long dfs(int node,int parent,long long a[]){
    if((node==0&&v[0].size()==0)||(node!=0&&v[node].size()==1)){
        values[node]=a[node];
        return a[node];
    }
    values[node]=a[node];
    int flag=0;
    long long lar1=0,lar2=0;
    for(int i=0;i<v[node].size();i++){
        long long temp;
        if(v[node][i]!=parent) {
        temp=dfs(v[node][i],node,a);
        if(flag==0){
            lar1=temp;
            flag=1;
        }
        else if(flag==1){
            if(lar1>temp) lar2=temp;
            else{
                lar2=lar1;
                lar1=temp;
            }
            flag=2;
        }
        else{
            if(temp>lar1){
                lar2=lar1;
                lar1=temp;
            }
            else if(temp>lar2){
                lar2=temp;
            }
        }
    }
    if(flag==2){
        if(flag1==0){
            max_value=lar1+lar2;
            flag1=1;
        }
        else{
            max_value=max(max_value,lar1+lar2);
        }
    }
    }
    for(int i=0;i<v[node].size();i++){
        if(v[node][i]!=parent) values[node]+=values[v[node][i]];
    }
    return max(values[node],lar1);
}
main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    long long a[n];
    v.resize(n);
    for(int i=0;i<n;i++) cin>>a[i];
    int t1,t2;
    for(int i=0;i<n-1;i++){
        cin>>t1>>t2;
        v[t1-1].push_back(t2-1);
        v[t2-1].push_back(t1-1);
    }
    dfs(0,-1,a);
    if(flag1==0) cout<<"Impossible";
    else cout<<max_value;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(sz[x]>1)ret= max(ret,sum[x]);
}
multiset<ll>::reverse_iterator it;
void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(n-sz[x]>1){ret= max(ret,sum[1]-sum[x]);}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int n,i,x,y;
	cin>>n;
	assert(n!=2);
	if(n==1){printf("Impossible\n");return 0;}
	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	dfs2(1,0,-1e18);
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
multiset<ll>::reverse_iterator it;
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	maxi[x]= -1e18;
	multiset<ll> s;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			s.insert(maxi[u]);
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(s.size()>0){
		ll k=0;
		for(i=0,it = s.rbegin();it!= s.rend();++it,++i)
			k+= *it;
		ret= max(ret,k);
	}
	if(sz[x]>1 && x!=1)ret= max(ret,sum[x]);
}
void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(n-sz[x]>1){ret= max(ret,sum[1]-sum[x]);}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int i,x,y;
	cin>>n;
	if(n<=2){printf("Impossible\n");return 0;}
	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	//dfs2(1,0,-1e18);
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
multiset<ll>::reverse_iterator it;
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	maxi[x]= -1e18;
	multiset<ll> s;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			s.insert(maxi[u]);
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(s.size()>1){
		ll k=0;
		for(i=0,it = s.rbegin();i<2&&it!= s.rend();++it,++i)
			k+= *it;
		ret= max(ret,k);
	}
}

void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(n-sz[x]>1){ret= max(ret,sum[1]-sum[x]);}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int i,x,y;
	cin>>n;	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	//dfs2(1,0,-1e18);
	if(ret==-1e18){printf("Impossible\n");return 0;}
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	maxi[x]= -1e18;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(sz[x]>1)ret= max(ret,sum[x]);
}
multiset<ll>::reverse_iterator it;
void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(n-sz[x]>1){ret= max(ret,sum[1]-sum[x]);}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int n,i,x,y;
	cin>>n;
	if(n==1){printf("Impossible\n");return 0;}
	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	dfs2(1,0,-1e18);
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(sz[x]>1)ret= max(ret,sum[x]);
}
multiset<ll>::reverse_iterator it;
void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(n-sz[x]>1){ret= max(ret,sum[1]-sum[x]);}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int n,i,x,y;
	cin>>n;
	if(n==1){printf("Impossible\n");return 0;}
	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	dfs2(1,0,-1e18);
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(sz[x]>1)ret= max(ret,sum[x]);
}
multiset<ll>::reverse_iterator it;
void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(n-sz[x]>1){ret= max(ret,sum[1]-sum[x]);}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int n,i,x,y;
	cin>>n;
	assert(n==2);
	if(n==1){printf("Impossible\n");return 0;}
	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	dfs2(1,0,-1e18);
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
multiset<ll>::reverse_iterator it;
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	maxi[x]= -1e18;
	multiset<ll> s;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			s.insert(maxi[u]);
			maxi[x]= max(maxi[x],maxi[u]);
			if(s.size()>2)s.erase(s.begin());
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(s.size()>1){
		ll k=0;
		for(i=0,it = s.rbegin();i<2&&it!= s.rend();++it,++i)
			k+= *it;
		ret= max(ret,k);
	}
}
int main(){
	int i,x,y;
	cin>>n;	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	if(ret==-1e18){printf("Impossible\n");return 0;}
	cout<<ret<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 5;
#define ll long long
ll sum[N],a[N],maxi[N],ret= -1e18;
int sz[N],n;
vector<int> adj[N];
void dfs(int x,int p){
	int u,i;
	sum[x]+=a[x];sz[x]=1;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			sz[x]+=sz[u];
			sum[x]+=sum[u];
			maxi[x]= max(maxi[x],maxi[u]);
		}
	}
	maxi[x] = max(maxi[x],sum[x]);
	if(sz[x]>1)ret= max(ret,sum[x]);
}
multiset<ll>::reverse_iterator it;
void dfs2(int x,int p,ll c){
	int u,i;ll k;multiset<ll> s;
	ll se=0,cs;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p)s.insert(maxi[u]);
	}
	if(n-sz[x]>0){
		s.insert(c);
	}
	if(s.size()>1){
		k=0;
		for(it= s.rbegin();it!= s.rend();++it)
			k+= *it;
		ret= max(ret,k);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			cs= sum[1]-sum[u];
			s.erase(maxi[u]);
			k=-1e18;
			if(s.size()>0)k= max(k,*s.rbegin());
			k= max(k,cs);
			dfs2(u,x,k);
			s.insert(maxi[u]);
		}
	}
}
int main(){
	int n,i,x,y;
	cin>>n;
	if(n==1){printf("Impossible\n");return 0;}
	for(i=1;i<=n;++i)cin>>a[i];
	for(i=0;i<n-1;++i)
		scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	dfs2(1,0,-1e18);
	cout<<ret<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=1e5+10,M=1e6+10,inf=1e9+10;
const ll INF=1e18+10,mod=2147493647;
struct is
{
    int v;
    int next;
}edge[N<<1];
int head[N<<1],edg;
ll sum[N],a[N],dp[N][5];
void init()
{
    memset(head,-1,sizeof(head));
    edg=0;
}
void add(int u,int v)
{
    edg++;
    edge[edg].v=v;
    edge[edg].next=head[u];
    head[u]=edg;
}
void dfs(int u,int fa)
{
    sum[u]=a[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        sum[u]+=sum[v];
    }
}
void dfs1(int u,int fa)
{
    //cout<<u<<" "<<fa<<endl;
    int flag=1;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    ll ans2=-INF,ans1=-INF;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs1(v,u);
        if(dp[v][1]!=sum[v])flag=0;
        ans2=max(ans2,dp[v][2]);
        ans1=max(ans1,dp[v][1]);
        q.push(dp[v][1]);
        while(q.size()>2)
        {
            q.pop();
        }
    }
    dp[u][1]=max(dp[u][1],ans1);
    ll s1=0,s2=0,p=1;
    while(!q.empty())
    {
        if(p==1)
            s1=q.top();
        else
            s2=q.top();
            q.pop();
        p++;
    }
    dp[u][2]=max(dp[u][2],ans2);
    dp[u][2]=max(dp[u][2],s1+s2);
    if(flag) dp[u][1]=max(dp[u][1],sum[u]);
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        dp[i][1]=dp[i][2]=-INF;
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    if(n<=2)
    {
        return puts("Impossible\n");
    }
    dfs(1,-1);
    dfs1(1,-1);
    ll ans=-INF;
    ans=max(ans,max(dp[1][1],dp[1][2]));
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=1e5+10,M=1e6+10,inf=1e9+10;
const ll INF=1e18+10,mod=2147493647;
struct is
{
    int v;
    int next;
}edge[N<<1];
int head[N<<1],edg;
ll sum[N],a[N],dp[N][5];
void init()
{
    memset(head,-1,sizeof(head));
    edg=0;
}
void add(int u,int v)
{
    edg++;
    edge[edg].v=v;
    edge[edg].next=head[u];
    head[u]=edg;
}
void dfs(int u,int fa)
{
    sum[u]=a[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        sum[u]+=sum[v];
    }
}
void dfs1(int u,int fa)
{
    //cout<<u<<" "<<fa<<endl;
    int flag=1;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    ll ans2=-INF,ans1=-INF;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs1(v,u);
        if(dp[v][1]!=sum[v])flag=0;
        ans2=max(ans2,dp[v][2]);
        ans1=max(ans1,dp[v][1]);
        q.push(dp[v][1]);
        while(q.size()>2)
        {
            q.pop();
        }
    }
    dp[u][1]=max(dp[u][1],ans1);
    ll s1=0,s2=0,p=1;
    while(!q.empty())
    {
        if(p==1)
            s1=q.top();
        else
            s2=q.top();
            q.pop();
        p++;
    }
    dp[u][2]=max(dp[u][2],ans2);
    dp[u][2]=max(dp[u][2],s1+s2);
    if(flag) dp[u][1]=max(dp[u][1],sum[u]);
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        dp[i][1]=dp[i][2]=-INF;
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    if(n==1)
    {
        return puts("Impossible\n");
    }
    dfs(1,-1);
    dfs1(1,-1);
    ll ans=-INF;
    ans=max(ans,max(dp[1][1],dp[1][2]));
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=1e5+10,M=1e6+10,inf=1e9+10;
const ll INF=1e18+10,mod=2147493647;
struct is
{
    int v;
    int next;
}edge[N<<1];
int head[N<<1],edg;
ll sum[N],a[N],dp[N][5];
void init()
{
    memset(head,-1,sizeof(head));
    edg=0;
}
void add(int u,int v)
{
    edg++;
    edge[edg].v=v;
    edge[edg].next=head[u];
    head[u]=edg;
}
void dfs(int u,int fa)
{
    sum[u]=a[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        sum[u]+=sum[v];
    }
}
void dfs1(int u,int fa)
{
    //cout<<u<<" "<<fa<<endl;
    int flag=1;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    ll ans2=-INF,ans1=-INF;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs1(v,u);
        if(dp[v][1]!=sum[v])flag=0;
        ans2=max(ans2,dp[v][2]);
        ans1=max(ans1,dp[v][1]);
        q.push(dp[v][1]);
        while(q.size()>2)
        {
            q.pop();
        }
    }
    dp[u][1]=max(dp[u][1],ans1);
    ll s1=0,s2=0,p=1;
    while(!q.empty())
    {
        if(p==1)
            s1=q.top();
        else
            s2=q.top();
            q.pop();
        p++;
    }
    dp[u][2]=max(dp[u][2],ans2);
    dp[u][2]=max(dp[u][2],s1+s2);
    if(flag) dp[u][1]=max(dp[u][1],sum[u]);
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        dp[i][1]=dp[i][2]=-INF;
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    if(n<=2)
    {
        return puts("Impossible\n");
    }
    dfs(1,-1);
    dfs1(1,-1);
    ll ans=-INF;
    ans=max(ans,max(dp[1][1],dp[1][2]));
    if(ans>=0)
    printf("%lld\n",ans);
    else
        puts("Impossible\n");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=2e5+10,M=1e6+10,inf=1e9+10;
const ll INF=1e18+10,mod=2147493647;
struct is
{
    int v;
    int next;
}edge[N<<1];
int head[N<<1],edg;
ll sum[N],a[N],dp[N][5];
void init()
{
    memset(head,-1,sizeof(head));
    edg=0;
}
void add(int u,int v)
{
    edg++;
    edge[edg].v=v;
    edge[edg].next=head[u];
    head[u]=edg;
}
void dfs(int u,int fa)
{
    sum[u]=a[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        sum[u]+=sum[v];
    }
}
void dfs1(int u,int fa)
{
    //cout<<u<<" "<<fa<<endl;
    int flag=1;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    ll ans2=-INF,ans1=-INF;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs1(v,u);
        if(dp[v][1]!=sum[v])flag=0;
        ans2=max(ans2,dp[v][2]);
        ans1=max(ans1,dp[v][1]);
        q.push(dp[v][1]);
        while(q.size()>2)
        {
            q.pop();
        }
    }
    dp[u][1]=max(dp[u][1],ans1);
    ll s1=-INF,s2=-INF,p=1,s3;
    while(!q.empty())
    {
        if(p==1)
            s1=q.top();
        else
            s2=q.top();
            q.pop();
        p++;
    }
    if(s2==-INF)
        s3=-INF;
    else
        s3=s2+s1;
    dp[u][2]=max(dp[u][2],ans2);
    dp[u][2]=max(dp[u][2],s3);
    if(flag) dp[u][1]=max(dp[u][1],sum[u]);
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        dp[i][1]=dp[i][2]=-INF;
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    if(n<=2)
    {
        return puts("Impossible\n");
    }
    dfs(1,-1);
    dfs1(1,-1);
    //for(int i=1;i<=n;i++)
        //cout<<dp[i][1]<<" "<<dp[i][2]<<endl;
    if(dp[1][2]>-INF)
    printf("%lld\n",dp[1][2]);
    else
        puts("Impossible\n");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=1e5+10,M=1e6+10,inf=1e9+10;
const ll INF=1e18+10,mod=2147493647;
struct is
{
    int v;
    int next;
}edge[N<<1];
int head[N<<1],edg;
ll sum[N],a[N],dp[N][5];
void init()
{
    memset(head,-1,sizeof(head));
    edg=0;
}
void add(int u,int v)
{
    edg++;
    edge[edg].v=v;
    edge[edg].next=head[u];
    head[u]=edg;
}
void dfs(int u,int fa)
{
    sum[u]=a[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        sum[u]+=sum[v];
    }
}
void dfs1(int u,int fa)
{
    //cout<<u<<" "<<fa<<endl;
    int flag=1;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    ll ans2=-INF,ans1=-INF;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs1(v,u);
        if(dp[v][1]!=sum[v])flag=0;
        ans2=max(ans2,dp[v][2]);
        ans1=max(ans1,dp[v][1]);
        q.push(dp[v][1]);
        while(q.size()>2)
        {
            q.pop();
        }
    }
    dp[u][1]=max(dp[u][1],ans1);
    ll s1=0,s2=0,p=1;
    while(!q.empty())
    {
        if(p==1)
            s1=q.top();
        else
            s2=q.top();
            q.pop();
        p++;
    }
    dp[u][2]=max(dp[u][2],ans2);
    dp[u][2]=max(dp[u][2],s1+s2);
    if(flag) dp[u][1]=max(dp[u][1],sum[u]);
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        dp[i][1]=dp[i][2]=-INF;
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    if(n<=2)
    {
        return puts("Impossible\n");
    }
    dfs(1,-1);
    dfs1(1,-1);
    ll ans=-INF;
    ans=max(ans,max(dp[1][1],dp[1][2]));
    if(dp[1][2]>-INF)
    printf("%lld\n",ans);
    else
        puts("Impossible\n");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=2e5+10,M=1e6+10,inf=1e9+10;
const ll INF=1e18+10,mod=2147493647;
struct is
{
    int v;
    int next;
}edge[N<<1];
int head[N<<1],edg;
ll sum[N],a[N],dp[N][5];
void init()
{
    memset(head,-1,sizeof(head));
    edg=0;
}
void add(int u,int v)
{
    edg++;
    edge[edg].v=v;
    edge[edg].next=head[u];
    head[u]=edg;
}
void dfs(int u,int fa)
{
    sum[u]=a[u];
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        sum[u]+=sum[v];
    }
}
void dfs1(int u,int fa)
{
    priority_queue<ll,vector<ll>,greater<ll> >q;
    ll ans2=-INF,ans1=-INF;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa)continue;
        dfs1(v,u);
        ans2=max(ans2,dp[v][2]);
        ans1=max(ans1,dp[v][1]);
        q.push(dp[v][1]);
        while(q.size()>2)
        {
            q.pop();
        }
    }
    dp[u][1]=max(dp[u][1],ans1);
    dp[u][2]=max(dp[u][2],ans2);
    dp[u][1]=max(dp[u][1],sum[u]);
    ll s1=-INF,s2=-INF,p=1,s3;
    while(!q.empty())
    {
        if(p==1)
            s1=q.top();
        else
            s2=q.top();
            q.pop();
        p++;
    }
    if(s2==-INF)
        s3=-INF;
    else
        s3=s2+s1;
    dp[u][2]=max(dp[u][2],s3);
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        dp[i][1]=dp[i][2]=-INF;
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs(1,-1);
    dfs1(1,-1);
    //for(int i=1;i<=n;i++)
        //cout<<dp[i][1]<<" "<<dp[i][2]<<endl;
    if(dp[1][2]>-INF)
    printf("%lld\n",dp[1][2]);
    else
        puts("Impossible\n");
    return 0;
}