					// ADASALES SPOJ    https://w...content-available-to-author-only...j.com/problems/ADASALES/
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<iostream>
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long 
#define vec vector<ll> 
#define mk make_pair 
#define pb push_back
#define ppb pop_back
#define setbit(n) __builtin_popcountll(n)
#define rep(i,a,b) for(int i=a; i<=b;i++) 
#define rep1(i,n)  for(int i=0;i<n;i++)
#define rrep(i,a,b) for(int i=a; i>=b;i--) 
#define rrep1(i,n)  for(int i=n;i>=0;i--)
#define cin(arr,n) for(int i=0; i<n;i++){cin>>arr[i];}
#define cin1(vec,n) rep1(i,n){ll x;cin>>x;vec.pb(x);}
#define so(vec) sort(vec.begin(),vec.end())
#define rev(v) reverse(v.begin(),v.end())
#define cout(v) rep1(i,v.size()){cout<<v[i]<<" ";}
#define prdouble(x) cout<<fixed<<setprecision(10)<<x;
#define out(v) cout<<v<<" "; 
#define all(v) v.begin(),v.end()
#define yes cout<<"YES";
#define no cout<<"NO";
#define no1 cout<<"-1";
#define lb cout<<"\n";
template <typename T>
T myMax(T x, T y)
{
return (x > y) ? x : y;
}
const ll N = 1e5+7;
const ll M = 2e9+7;
const ll Mn = -(1e9+7);
using namespace std;
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define ordered_multiset tree<ll,null_type,less_equal<ll>,rb_tree_tag,tree_order_statistics_node_update>

//For policy based data structures:-
//order_of_key (K): Number of items strictly smaller than K
//find_by_order(k): Kth element in a Set (counting from zero)
//deleting element in ordered multiset:-
//ordered_multiset::iterator it = v.find_by_order(v.order_of_key(a[i]));
//v.erase(it);
//deleting element in ordered set:-
//ordered_set::iterator it = v.find_by_order(v.order_of_key(a[i]));
//v.erase(it);

vector<ll> v;
vector<ll> g[N];
// ll visi[N];
ll in[N];
ll out[N];

void dfs1(ll node, ll par){ // filling in 
    for(auto it:g[node]){
        if(it!=par){
            dfs1(it,node);
            // cout<<node<<" : "<<it<<" "<<in[it];lb;
            in[node] = max({in[node],in[it]+max(0LL,v[it]-v[node])});
        }
    }
}

void dfs2(ll node,ll par){ // filling out
    ll mx1=-1;
    ll mx2=-1;
    for(auto it:g[node]){
        if(it!=par){
            if(in[it]+max(0LL,v[it]-v[node])>mx1){
                mx2=mx1;
                mx1=in[it]+max(0LL,v[it]-v[node]);
            }
            else if(in[it]+max(0LL,v[it]-v[node])>mx2){
                mx2=in[it]+max(0LL,v[it]-v[node]);
            }
        }
    }
    for(auto it:g[node]){
        if(it!=par){
            ll use=mx1;
            if(mx1==in[it]+max(0LL,v[it]-v[node])){
                use=mx2;
            }
            out[it]=max({out[it],use+max(0LL,v[node]-v[it]),out[node]+max(0LL,v[node]-v[it])});
            dfs2(it,node);
        }
    }

}

void solve(){
    ll n,q;
    cin>>n>>q;
    cin1(v,n);
    for(int i=0;i<n-1;i++){
        ll a,b;
        cin>>a>>b;
        g[a].pb(b);
        g[b].pb(a);
    }
    ll par=-1;
    dfs1(0LL,par);
    // for(int i=0;i<n;i++){
    //     cout<<i<<" "<<in[i]<<" ";
    // }
    dfs2(0LL,par);
    for(int i=0;i<q;i++){
        ll x;
        cin>>x;
        cout<<max(in[x],out[x]);lb;
    }
}
int main(){
fast;
ll t;
t=1;
// cin>>t;
rep1(i,t){
solve();
// cout<<"\n";
}
    return 0;
}