#include<bits/stdc++.h>
using namespace std;
struct st
{
    long long x,y,z;
    st(long long p, long long q,  long long r)
    {
        x = p,y = q, z = r;
    }
    bool operator <(const st&p) const
    {
        return z<p.z;
    }
};
struct qq
{
    long long x,y;
} Q[200005];
bool comp1(qq x, qq y)
{
    return x.y<y.y;
}

vector<st>vec;
long long par[200005];
long long fre[200005];
long long print[200005];

long long findd(long long x)
{
    if(par[x] == x)
        return x;
    return par[x] = findd(par[x]);
}

void Union(long long a, long long b)
{
    par[findd(b)] = findd(a);
}

int main()
{
    long long n,q;
    cin>>n>>q;
    for(long long i = 0; i <= n; i++)
        par[i] = i,fre[i]++;

    n--;
    while(n--)
    {
        long long x,y,z;
        scanf("%d %d %d", &x, &y, &z);
        vec.push_back(st(x,y,z));

    }
    sort(vec.begin(),vec.end());
    vec.push_back(st(-1,-1,9999999));
    for(long long i = 0; i< q; i++)
    {
        long long x;
        scanf("%d", &x);
        Q[i].x = i;
        Q[i].y = x;
    }
    sort(Q, Q+q,comp1);
    long long now = 0;
    long long ans = 0;
    for(long long i = 0; i< q; i++)
    {
        long long cost = Q[i].y;
        //cout<<"check cost = "<<cost<<endl;
        while(vec[now].z<=cost)
        {
            long long a = findd(vec[now].x);
            long long b = findd(vec[now].y);

            if(a!=b)
            {
                long long f = fre[a];
                long long s = fre[b];
                fre[a]-=f;
                fre[b]-=s;

                ans-=((f * (f-1))/2);
                ans-=((s * (s-1))/2);
                par[b] = a;
                fre[a]+=(f+s);
                f+=s;
                ans+=((f * (f-1))/2);

                // cout<<"edge_cost "<<vec[now].z<<endl;
                //cout<<"ans = "<<ans<<endl;
            }

            now++;
        }
        print[Q[i].x] = ans;
    }
    for(long long i = 0; i< q; i++)
        cout<<print[i]<<" ";
    return 0;
}


#include"bits/stdc++.h"
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
typedef long long int ll;
const ll N=2e5+2,inf=1e9+7;
void _run();
void no(){cout<<"0\n",exit(0);}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	_run();
	return 0;
}
vector<pair<int,int> >vec[N];
int n,m,q,pr[N],siz[N];ll rs[N];
int _find(int x)
{
    if(pr[x]==x)return x;
    return pr[x]=_find(pr[x]);
}
void _union(int p,int q)
{
    if(siz[q]>siz[p])swap(p,q);
    pr[q]=p;siz[p]+=siz[q];
}
void _run()
{
    cin>>n>>q;m=n-1;
    while(m--)
    {
        int u,v,c;cin>>u>>v>>c;
        vec[c].pb(mp(u,v));
    }
    ll cur=0;
    for(int i=1;i<=n;i++)pr[i]=i,siz[i]=1;
    for(int i=1;i<N;i++)
    {
        for(auto x:vec[i])
        {
            int u=x.fs,v=x.sc;
            int p=_find(u),q=_find(v);
            if(p==q)continue;
            cur+=(1LL*siz[p]*siz[q]);
            _union(p,q);
        }
        rs[i]=cur;
    }
    for(int i=1;i<=q;i++)
    {
        int x;cin>>x;
        cout<<rs[x]<<" ";
    }
    cout<<"\n";
}


#include"bits/stdc++.h"
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
typedef long long int ll;
const ll N=1e6+2,inf=1e9+7;
void _run();
void no(){cout<<"0\n",exit(0);}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	_run();
	return 0;
}
vector<pair<int,pair<int,int> > >vec;
int n,m,q,pr[N],siz[N];
int _find(int x)
{
    if(pr[x]==x)return x;
    return pr[x]=_find(pr[x]);
}
void _union(int u,int v)
{
    int p=_find(u),q=_find(v);
    if(p==q)return;
    if(siz[q]>siz[p])swap(p,q);
    pr[q]=p;siz[p]+=siz[q];
}
ll _cal(ll n)
{
    return (n*(n-1))/2LL;
}
void _run()
{
    cin>>n>>q;m=n-1;
    while(m--)
    {
        int u,v,c;cin>>u>>v>>c;
        vec.pb(mp(c,mp(u,v)));
    }
    sort(vec.begin(),vec.end());
    pair<int,int>Q[q+1];
    for(int i=1;i<=q;i++)cin>>Q[i].fs,Q[i].sc=i;
    sort(Q+1,Q+q+1);
    for(int i=1;i<=n;i++)pr[i]=i,siz[i]=1;
    ll cur=0,rs[q+1];int id=1;
    memset(rs,0,sizeof rs);
    for(auto x:vec)
    {
        int c=x.fs,u=x.sc.fs,v=x.sc.sc;
        int p=_find(u),q=_find(v);
        if(p!=q)
        {
            cur-=(_cal(siz[p])+_cal(siz[q]));
            if(siz[q]>siz[p])swap(p,q);
            pr[q]=p;siz[p]+=siz[q];siz[q]=0;
            cur+=_cal(siz[p]);
        }
        if(Q[id].fs>=c)rs[Q[id].sc]=cur;
        else
        {
            int nw=id+1;id++;
            while(nw<=q&&Q[nw].fs<c)nw++;
            //cout<<id<<" "<<nw<<" "<<c<<"*\n";
            while(id<nw)rs[Q[id++].sc]=cur;
            rs[Q[nw].sc]=cur;
        }
        if(id>q)break;
    }
    while(id<=q)rs[Q[id++].sc]=cur;
    for(int i=1;i<=q;i++)cout<<rs[i]<<" ";
    cout<<"\n";
}


#include"bits/stdc++.h"
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
typedef long long int ll;
const ll N=1e6+2,inf=1e9+7;
void _run();
void no(){cout<<"0\n",exit(0);}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	_run();
	return 0;
}
vector<pair<int,pair<int,int> > >vec;
int n,m,q,pr[N],siz[N];
int _find(int x)
{
    if(pr[x]==x)return x;
    return pr[x]=_find(pr[x]);
}
void _union(int u,int v)
{
    int p=_find(u),q=_find(v);
    if(p==q)return;
    if(siz[q]>siz[p])swap(p,q);
    pr[q]=p;siz[p]+=siz[q];
}
ll _cal(ll n)
{
    return (n*(n-1))/2LL;
}
void _run()
{
    cin>>n>>q;m=n-1;
    while(m--)
    {
        int u,v,c;cin>>u>>v>>c;
        vec.pb(mp(c,mp(u,v)));
    }
    sort(vec.begin(),vec.end());
    pair<int,int>Q[q+1];
    for(int i=1;i<=q;i++)cin>>Q[i].fs,Q[i].sc=i;
    sort(Q+1,Q+q+1);
    for(int i=1;i<=n;i++)pr[i]=i,siz[i]=1;
    ll cur=0,rs[q+1],prv=0;int id=1;
    memset(rs,0,sizeof rs);
    for(auto x:vec)
    {
        int c=x.fs,u=x.sc.fs,v=x.sc.sc;
        int p=_find(u),q=_find(v);
        if(p!=q)
        {
            cur-=(_cal(siz[p])+_cal(siz[q]));
            if(siz[q]>siz[p])swap(p,q);
            pr[q]=p;siz[p]+=siz[q];siz[q]=0;
            cur+=_cal(siz[p]);
        }
        if(Q[id].fs>=c)rs[Q[id].sc]=cur;
        else
        {
            int nw=id;
            while(nw<=q&&Q[nw].fs<c)nw++;
            //cout<<id<<" "<<nw<<" "<<c<<"*\n";
            while(id<nw)rs[Q[id++].sc]=prv;
            rs[Q[nw].sc]=cur;
        }
        if(id>q)break;
        prv=cur;
    }
    while(id<=q)rs[Q[id++].sc]=cur;
    for(int i=1;i<=q;i++)cout<<rs[i]<<" ";
    cout<<"\n";
}


#include"bits/stdc++.h"
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
typedef long long int ll;
const ll N=1e6+2,inf=1e9+7;
void _run();
void no(){cout<<"0\n",exit(0);}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	_run();
	return 0;
}
vector<pair<int,pair<int,int> > >vec;
int n,m,q,pr[N],siz[N];
int _find(int x)
{
    if(pr[x]==x)return x;
    return pr[x]=_find(pr[x]);
}
void _union(int u,int v)
{
    int p=_find(u),q=_find(v);
    if(p==q)return;
    if(siz[q]>siz[p])swap(p,q);
    pr[q]=p;siz[p]+=siz[q];
}
ll _cal(ll n)
{
    return (n*(n-1))/2LL;
}
void _run()
{
    cin>>n>>q;m=n-1;
    while(m--)
    {
        int u,v,c;cin>>u>>v>>c;
        vec.pb(mp(c,mp(u,v)));
    }
    sort(vec.begin(),vec.end());
    pair<int,int>Q[q+1];
    for(int i=1;i<=q;i++)cin>>Q[i].fs,Q[i].sc=i;
    sort(Q+1,Q+q+1);
    for(int i=1;i<=n;i++)pr[i]=i,siz[i]=1;
    ll cur=0,rs[q+1],prv=0;int id=1;
    memset(rs,0,sizeof rs);
    for(auto x:vec)
    {
        int c=x.fs,u=x.sc.fs,v=x.sc.sc;
        int p=_find(u),q=_find(v);
        if(p!=q)
        {
            cur-=(_cal(siz[p])+_cal(siz[q]));
            if(siz[q]>siz[p])swap(p,q);
            pr[q]=p;siz[p]+=siz[q];
            cur+=_cal(siz[p]);
        }
        if(Q[id].fs>=c)rs[Q[id].sc]=cur;
        else
        {
            int nw=id;
            while(nw<=q&&Q[nw].fs<c)nw++;
            //cout<<id<<" "<<nw<<" "<<c<<"*\n";
            while(id<nw)rs[Q[id++].sc]=prv;
            rs[Q[nw].sc]=cur;
        }
        if(id>q)break;
        prv=cur;
    }
    while(id<=q)rs[Q[id++].sc]=cur;
    for(int i=1;i<=q;i++)cout<<rs[i]<<" ";
    cout<<"\n";
}


#include"bits/stdc++.h"
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
typedef long long int ll;
const ll N=1e6+2,inf=1e9+7;
void _run();
void no(){cout<<"0\n",exit(0);}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	_run();
	return 0;
}
vector<pair<int,pair<int,int> > >vec;
int n,m,q,pr[N],siz[N];
int _find(int x)
{
    if(pr[x]==x)return x;
    return pr[x]=_find(pr[x]);
}
void _union(int u,int v)
{
    int p=_find(u),q=_find(v);
    if(p==q)return;
    if(siz[q]>siz[p])swap(p,q);
    pr[q]=p;siz[p]+=siz[q];
}
ll _cal(ll n)
{
    return (n*(n-1))/2LL;
}
void _run()
{
    cin>>n>>q;m=n-1;
    while(m--)
    {
        int u,v,c;cin>>u>>v>>c;
        vec.pb(mp(c,mp(u,v)));
    }
    sort(vec.begin(),vec.end());
    pair<int,int>Q[q+1];
    for(int i=1;i<=q;i++)cin>>Q[i].fs,Q[i].sc=i;
    sort(Q+1,Q+q+1);
    for(int i=1;i<=n;i++)pr[i]=i,siz[i]=1;
    ll cur=0,rs[q+1];int id=1;
    for(auto x:vec)
    {
        int c=x.fs,u=x.sc.fs,v=x.sc.sc;
        int p=_find(u),q=_find(v);
        if(p!=q)
        {
            cur-=(_cal(siz[p])+_cal(siz[q]));
            if(siz[q]>siz[p])swap(p,q);
            pr[q]=p;siz[p]+=siz[q];siz[q]=0;
            cur+=_cal(siz[p]);
        }
        if(Q[id].fs>=c)rs[Q[id].sc]=cur;
        else
        {
            int nw=id+1;id++;
            while(nw<=q&&Q[nw].fs<c)nw++;
            //cout<<id<<" "<<nw<<" "<<c<<"*\n";
            while(id<nw)rs[Q[id++].sc]=cur;
            rs[Q[nw].sc]=cur;
        }
        if(id>q)break;
    }
    while(id<=q)rs[Q[id++].sc]=cur;
    for(int i=1;i<=q;i++)cout<<rs[i]<<" ";
    cout<<"\n";
}


#include"bits/stdc++.h"
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
typedef long long int ll;
const ll N=1e6+2,inf=1e9+7;
void _run();
void no(){cout<<"0\n",exit(0);}
int main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);
	_run();
	return 0;
}
vector<pair<int,pair<int,int> > >vec;
int n,m,q,pr[N],siz[N];
int _find(int x)
{
    if(pr[x]==x)return x;
    return pr[x]=_find(pr[x]);
}
void _union(int u,int v)
{
    int p=_find(u),q=_find(v);
    if(p==q)return;
    if(siz[q]>siz[p])swap(p,q);
    pr[q]=p;siz[p]+=siz[q];
}
ll _cal(ll n)
{
    return (n*(n-1))/2LL;
}
void _run()
{
    cin>>n>>q;m=n-1;
    while(m--)
    {
        int u,v,c;cin>>u>>v>>c;
        vec.pb(mp(c,mp(u,v)));
    }
    sort(vec.begin(),vec.end());
    pair<int,int>Q[q+1];
    for(int i=1;i<=q;i++)cin>>Q[i].fs,Q[i].sc=i;
    sort(Q+1,Q+q+1);
    for(int i=1;i<=n;i++)pr[i]=i,siz[i]=1;
    ll cur=0,rs[q+1],prv=0;int id=1;
    memset(rs,0,sizeof rs);
    for(auto x:vec)
    {
        int c=x.fs,u=x.sc.fs,v=x.sc.sc;
        int p=_find(u),q=_find(v);
        if(p!=q)
        {
            cur-=(_cal(siz[p])+_cal(siz[q]));
            pr[q]=p;siz[p]+=siz[q];
            cur+=_cal(siz[p]);
        }
        if(Q[id].fs>=c)rs[Q[id].sc]=cur;
        else
        {
            int nw=id;
            while(nw<=q&&Q[nw].fs<c)nw++;
            //cout<<id<<" "<<nw<<" "<<c<<"*\n";
            while(id<nw)rs[Q[id++].sc]=prv;
            rs[Q[nw].sc]=cur;
        }
        if(id>q)break;
        prv=cur;
    }
    while(id<=q)rs[Q[id++].sc]=cur;
    for(int i=1;i<=q;i++)cout<<rs[i]<<" ";
    cout<<"\n";
}


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
struct Edge {
  int u,v,w;
  bool operator<(const Edge &other) const {
    return w<other.w;
  }
};
struct DSU {
  int n;
  vector<int> p,sz;
  DSU() {}
  DSU(int _n) : n(_n) {
    p.resize(n);
    sz.resize(n,1);
    iota(p.begin(),p.end(), 0);
  }
  inline int find(int u) {
    return (u== p[u] ? u : (p[u]=find(p[u])));
  }
  inline int merge(int u, int v) {
    u=find(u),v=find(v);
    if(sz[u]<sz[v]) swap(u,v);
    if(u!=v) {
      p[v]=u;
      sz[u]+=sz[v];
      return u;
    }
  }
};
int main(int argc, char const *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(0);
    int n,q; cin>>n>>q;
    DSU dsu(n);
    vector<Edge>edges;
    for(int i=0;i<n-1;i++) {
      int u,v,w;
      cin>>u>>v>>w;
      --u,--v;
      edges.push_back({u,v,w});
    }
    sort(edges.begin(),edges.end());
    vector<pair<int,int>>query(q);
    for(int i=0;i<q;i++) {
      cin>>query[i].first;
      query[i].second=i;
    }
    sort(query.begin(),query.end());
    int cur=0;
    set<int>rep;
    auto choose_two=[&](int x) {
      return (1LL*x*(x-1))/2;
    };
    long long ans=0;
    vector<long long>res(q);
    for(auto x:query) {
      int cost=x.first,id=x.second;
      while(cur<n-1 and edges[cur].w<=cost) {
        int u=edges[cur].u,v=edges[cur].v;
        int pu=dsu.find(u);
        int pv=dsu.find(v);
        assert(pu!=pv);
        ans-=choose_two(dsu.sz[pu]);
        ans-=choose_two(dsu.sz[pv]);
        int r=dsu.merge(pu,pv);
        ans+=choose_two(dsu.sz[r]);
        cur++;
      }
      res[id]=ans;
    }
    for(auto x:res) cout<<x<<" ";
}


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
struct Edge {
  int u,v,w;
  bool operator<(const Edge &other) const {
    return w<other.w;
  }
};
struct DSU {
  int n;
  vector<int> p,sz;
  DSU() {}
  DSU(int _n) : n(_n) {
    p.resize(n);
    sz.resize(n,1);
    iota(p.begin(),p.end(), 0);
  }
  inline int find(int u) {
    return (u== p[u] ? u : (p[u]=find(p[u])));
  }
  inline int merge(int u, int v) {
    u=find(u),v=find(v);
    if(sz[u]<sz[v]) swap(u,v);
    if(u!=v) {
      p[v]=u;
      sz[u]+=sz[v];
      return u;
    }
  }
};
int main(int argc, char const *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(0);
    int n,q; cin>>n>>q;
    DSU dsu(n);
    vector<Edge>edges;
    for(int i=0;i<n-1;i++) {
      int u,v,w;
      cin>>u>>v>>w;
      --u,--v;
      edges.push_back({u,v,w});
    }
    sort(edges.begin(),edges.end());
    vector<pair<int,int>>query(q);
    for(int i=0;i<q;i++) {
      cin>>query[i].first;
      query[i].second=i;
    }
    sort(query.begin(),query.end());
    int cur=0;
    set<int>rep;
    auto choose_two=[&](int x) {
      return (1LL*x*(x-1))/2;
    };
    long long ans=0;
    vector<long long>res(q);
    for(auto x:query) {
      int cost=x.first,id=x.second;
      while(cur<n-1 and edges[cur].w<=cost) {
        int u=edges[cur].u,v=edges[cur].v;
        assert(dsu.p[u]!=dsu.p[v]);
        ans-=choose_two(dsu.sz[dsu.p[u]]);
        ans-=choose_two(dsu.sz[dsu.p[v]]);
        int r=dsu.merge(u,v);
        ans+=choose_two(dsu.sz[r]);
        cur++;
      }
      res[id]=ans;
    }
    for(auto x:res) cout<<x<<" ";
}


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
struct Edge {
  int u,v,w;
  bool operator<(const Edge &other) const {
    return w<other.w;
  }
};
struct DSU {
  int n;
  vector<int> p,sz;
  DSU() {}
  DSU(int _n) : n(_n) {
    p.resize(n);
    sz.resize(n,1);
    iota(p.begin(),p.end(), 0);
  }
  inline int find(int u) {
    return (u== p[u] ? u : (p[u]=find(p[u])));
  }
  inline bool merge(int u, int v) {
    u=find(u),v=find(v);
    if(sz[u]<sz[v]) swap(u,v);
    if(u!=v) {
      p[v]=u;
      sz[u]+=sz[v];
      return true;
    }
    return false;
  }
};
int main(int argc, char const *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(0);
    int n,q; cin>>n>>q;
    DSU dsu(n);
    vector<Edge>edges;
    for(int i=0;i<n-1;i++) {
      int u,v,w;
      cin>>u>>v>>w;
      --u,--v;
      edges.push_back({u,v,w});
    }
    sort(edges.begin(),edges.end());
    vector<pair<int,int>>query(q);
    for(int i=0;i<q;i++) {
      cin>>query[i].first;
      query[i].second=i;
    }
    sort(query.begin(),query.end());
    int cur=0;
    set<int>rep;
    auto choose_two=[&](int x) {
      return (1LL*x*(x-1))/2;
    };
    long long ans=0;
    vector<long long>res(q);
    for(auto x:query) {
      int cost=x.first,id=x.second;
      while(cur<n-1 and edges[cur].w<=cost) {
        int u=edges[cur].u,v=edges[cur].v;
        assert(dsu.p[u]!=dsu.p[v]);
        ans-=choose_two(dsu.sz[dsu.p[u]]);
        ans-=choose_two(dsu.sz[dsu.p[v]]);
        dsu.merge(u,v);
        ans+=choose_two(dsu.sz[dsu.p[u]]);
        cur++;
      }
      res[id]=ans;
    }
    for(auto x:res) cout<<x<<" ";
}


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
struct Edge {
  int u,v,w;
  bool operator<(const Edge &other) const {
    return w<other.w;
  }
};
struct DSU {
  int n;
  vector<int> p,sz;
  DSU() {}
  DSU(int _n) : n(_n) {
    p.resize(n);
    sz.resize(n,1);
    iota(p.begin(),p.end(), 0);
  }
  inline int find(int u) {
    return (u== p[u] ? u : (p[u]=find(p[u])));
  }
  inline bool merge(int u, int v) {
    u=find(u),v=find(v);
    if(sz[u]<sz[v]) swap(u,v);
    if(u!=v) {
      p[v]=u;
      sz[u]+=sz[v];
      return true;
    }
    return false;
  }
};
int main(int argc, char const *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(0);
    int n,q; cin>>n>>q;
    DSU dsu(n);
    vector<Edge>edges;
    for(int i=0;i<n-1;i++) {
      int u,v,w;
      cin>>u>>v>>w;
      --u,--v;
      edges.push_back({u,v,w});
    }
    sort(edges.begin(),edges.end());
    vector<pair<int,int>>query(q);
    for(int i=0;i<q;i++) {
      cin>>query[i].first;
      query[i].second=i;
    }
    sort(query.begin(),query.end());
    int cur=0;
    set<int>rep;
    auto choose_two=[&](int x) {
      return (1LL*x*(x-1))/2;
    };
    vector<long long>ans(q);
    for(auto x:query) {
      int cost=x.first,id=x.second;
      while(cur<n-1 and edges[cur].w<=cost) {
        int u=edges[cur].u,v=edges[cur].v;
        dsu.merge(u,v);
        if(rep.find(u)!=rep.end()) rep.erase(u);
        if(rep.find(v)!=rep.end()) rep.erase(v);
        rep.insert(dsu.p[u]);
        ++cur;
      }
      for(int comp:rep) {
        ans[id]+=choose_two(dsu.sz[comp]);
      }
    }
    for(auto x:ans) cout<<x<<" ";
}


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
struct Edge {
  int u,v,w;
  bool operator<(const Edge &other) const {
    return w<other.w;
  }
};
struct DSU {
  int n;
  vector<int> p,sz;
  DSU() {}
  DSU(int _n) : n(_n) {
    p.resize(n);
    sz.resize(n,1);
    iota(p.begin(),p.end(), 0);
  }
  inline int find(int u) {
    return (u== p[u] ? u : (p[u]=find(p[u])));
  }
  inline bool merge(int u, int v) {
    u=find(u),v=find(v);
    if(sz[u]<sz[v]) swap(u,v);
    if(u!=v) {
      p[v]=u;
      sz[u]+=sz[v];
      return true;
    }
    return false;
  }
};
int main(int argc, char const *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(0);
    int n,q; cin>>n>>q;
    DSU dsu(n);
    vector<Edge>edges;
    for(int i=0;i<n-1;i++) {
      int u,v,w;
      cin>>u>>v>>w;
      --u,--v;
      edges.push_back({u,v,w});
    }
    sort(edges.begin(),edges.end());
    vector<pair<int,int>>query(q);
    for(int i=0;i<q;i++) {
      cin>>query[i].first;
      query[i].second=i;
    }
    sort(query.begin(),query.end());
    int cur=0;
    set<int>rep;
    auto choose_two=[&](int x) {
      return (1LL*x*(x-1))/2;
    };
    long long ans=0;
    vector<long long>res(q);
    for(auto x:query) {
      int cost=x.first,id=x.second;
      while(cur<n-1 and edges[cur].w<=cost) {
        int u=edges[cur].u,v=edges[cur].v;
        assert(dsu.p[u]!=dsu.p[v]);
        ans-=choose_two(dsu.sz[dsu.p[u]]);
        ans-=choose_two(dsu.sz[dsu.p[v]]);
        dsu.merge(u,v);
        ans+=choose_two(dsu.sz[dsu.p[dsu.p[u]]]);
        cur++;
      }
      res[id]=ans;
    }
    for(auto x:res) cout<<x<<" ";
}


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			if (l <= n-2 || edges[l].w > cq) {
				ans[q[i].second] = (i ? ans[q[i-1].second] : 0ll);
				continue;
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= l; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

		//	cout << "u: " << u << " v: " << v << '\n';

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
				//cout << "sz: " << sz[u] << '\n';
					cur += sz[u] * (sz[u] - 1) / 2;
				//cout << "cur: " << cur << '\n';
				}
			}

			ans[q[i].second] = cur;
			if (b < n-1) b = l + 1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= min(l,n-2); ++j) {
				if (edges[j].w > cq) {
					break;
				}

				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			ans[q[i].second] = cur;
			if (l < n-2) b = l+1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			if (edges[l].w > cq) {
				ans[q[i].second] = (i ? ans[q[i-1].second] : 0ll);
				continue;
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= l; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

		//	cout << "u: " << u << " v: " << v << '\n';

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
				//cout << "sz: " << sz[u] << '\n';
					cur += sz[u] * (sz[u] - 1) / 2;
				//cout << "cur: " << cur << '\n';
				}
			}

			ans[q[i].second] = cur;
			if (b < n-1) b = l + 1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		for (int i = 0; i < n-1; ++i) {
			int u,v,w;
			cin >> u >> v >> w;
			edges[i] = edge(u,v,w);
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		for (int i = 0; i < m; ++i) {
			int v;
			cin >> v;
			q[i] = make_pair(v, i);
		}

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			if (edges[l].w > cq) {
				ans[q[i].second] = (i ? ans[q[i-1].second] : 0ll);
				continue;
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= l; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

		//	cout << "u: " << u << " v: " << v << '\n';

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
				//cout << "sz: " << sz[u] << '\n';
					cur += sz[u] * (sz[u] - 1) / 2;
				//cout << "cur: " << cur << '\n';
				}
			}

			ans[q[i].second] = cur;
			b = l + 1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}
	cout << "##:" << edges.size() << '\n';
	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			if (l <= n-2 && edges[l].w > cq) {
				ans[i] = cur;
				continue;
			}

			for (int j = b; j <= min(l,n-2); ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			ans[q[i].second] = cur;
			if (l < n-2) b = l+1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		for (int i = 0; i < n-1; ++i) {
			int u,v,w;
			cin >> u >> v >> w;
			edges[i] = edge(u,v,w);
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		for (int i = 0; i < m; ++i) {
			int v;
			cin >> v;
			q[i] = make_pair(v, i);
		}

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			if (edges[l].w > cq) {
				ans[q[i].second] = (i ? ans[q[i-1].second] : 0ll);
				continue;
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= l; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

		//	cout << "u: " << u << " v: " << v << '\n';

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
				//cout << "sz: " << sz[u] << '\n';
					cur += sz[u] * (sz[u] - 1) / 2;
				//cout << "cur: " << cur << '\n';
				}
			}

			ans[q[i].second] = cur;
			b = l + 1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			if (edges[l].w > cq) {
				ans[q[i].second] = cur;
				continue;
			}

			for (int j = b; j <= min(l,n-2); ++j) {
				if (edges[j].w > cq) {
					break;
				}

				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			ans[q[i].second] = cur;
			if (l < n-2) b = l+1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		for (int i = 0; i < n-1; ++i) {
			int u,v,w;
			cin >> u >> v >> w;
			edges[i] = edge(u,v,w);
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		for (int i = 0; i < m; ++i) {
			int v;
			cin >> v;
			q[i] = make_pair(v, i);
		}

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			if (edges[l].w > cq || l == n-1) {
				ans[q[i].second] = (i ? ans[q[i-1].second] : 0ll);
				continue;
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= l; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

		//	cout << "u: " << u << " v: " << v << '\n';

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
				//cout << "sz: " << sz[u] << '\n';
					cur += sz[u] * (sz[u] - 1) / 2;
				//cout << "cur: " << cur << '\n';
				}
			}

			ans[q[i].second] = cur;
			b = l + 1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			if (l <= n-2 && edges[l].w > cq) {
				ans[i] = cur;
				continue;
			}

			for (int j = b; j <= min(l,n-2); ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			ans[q[i].second] = cur;
			if (l < n-2) b = l+1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		for (int i = 0; i < n-1; ++i) {
			int u,v,w;
			cin >> u >> v >> w;
			edges[i] = edge(u,v,w);
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		for (int i = 0; i < m; ++i) {
			int v;
			cin >> v;
			q[i] = make_pair(v, i);
		}

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			if (edges[l].w > cq) {
				ans[q[i].second] = (i ? ans[q[i-1].second] : 0ll);
				continue;
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= l; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

		//	cout << "u: " << u << " v: " << v << '\n';

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
				//cout << "sz: " << sz[u] << '\n';
					cur += sz[u] * (sz[u] - 1) / 2;
				//cout << "cur: " << cur << '\n';
				}
			}

			ans[q[i].second] = cur;
			if (b < n-1) b = l + 1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j < n-1 && edges[j].w <= cq; ++j) {
				b = j;
				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);

				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);

					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}
			++b;

			ans[q[i].second] = cur;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			ll cur = (i ? ans[q[i-1].second] : 0ll);

			int j;
			for (j = b; j < n-1 && edges[j].w <= cq; ++j) {
				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);

				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);

					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			b = j;

			ans[q[i].second] = cur;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			for (int j = b; j <= min(l,n-2); ++j) {
				if (edges[i].w > cq) {
					break;
				}

				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			ans[q[i].second] = cur;
			if (l < n-2) b = l+1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>
using namespace std;

//#define ONLINE_JUDGE
#define pb(a) push_back(a)
#define ALL(a) a.begin(), a.end()

using ll = long long;

///////////// Solution /////////////////////////////////

const int MAX = 1e5;
const ll oo = 1e15;

struct edge {
	int u,v,w;
	edge(int u, int v, int w) : u(u), v(v), w(w) {}
};

int n,m;
vector<pair<int,int>> q;
vector<edge> edges;
vector<ll> ans;
vector<ll> sz;
vector<int> p;

int find(int v) {
	if (p[v] == v) {
		return v;
	}

	return (p[v] = find(p[v]));
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);

	if (u == v) {
		return;
	}

	if (sz[u] > sz[v]) {
		swap(u,v);
	}

	p[u] = v;
	sz[v] += sz[u];
}

void solve() {
	cin >> n >> m;

	q.assign(m, {0,0});
	edges.assign(n-1, edge(0,0,0));
	p.assign(n+1, 0);
	sz.assign(n+1, 0);
	ans.assign(m, 0ll);

	for (int i = 0; i < n-1; ++i) {
		int u,v,w;
		cin >> u >> v >> w;
		edges[i] = edge(u,v,w);
	}

	for (int i = 0; i < m; ++i) {
		int v;
		cin >> v;
		q[i] = make_pair(v, i);
	}

	if (n > 1) {
		for (int i = 1; i <= n; ++i) {
			p[i] = i;
			sz[i] = 1ll;
		}

		sort(ALL(edges), [](const edge &a, const edge &b) {
			return a.w < b.w;
		});

		sort(ALL(q));

		int b = 0;
		for (int i = 0; i < m; ++i) {
			int cq = q[i].first;
			int l = b, r = n-1;

			while (r - l > 1) {
				int mid = (l+r)/2;

				if (edges[mid].w <= cq) {
					l = mid;
				} else {
					r = mid;
				}
			}

			ll cur = (i ? ans[q[i-1].second] : 0ll);

			if (edges[l].w > cq) {
				ans[q[i].second] = cur;
				continue;
			}

			for (int j = b; j <= min(l,n-2); ++j) {
				if (edges[j].w > cq) {
					break;
				}

				int u = edges[j].u;
				int v = edges[j].v;

				u = find(u);
				v = find(v);
				if (u != v) {
					cur -= sz[u] * (sz[u] - 1) / 2;
					cur -= sz[v] * (sz[v] - 1) / 2;

					unite(u,v);
					u = find(u);
					cur += sz[u] * (sz[u] - 1) / 2;
				}
			}

			ans[q[i].second] = cur;
			if (l+1 <= n-2) b = l+1;
		}

		sort(ALL(q), [](const pair<int,int> &a, const pair<int,int> &b) {
			return a.second < b.second;
		});
	}

	for (int i = 0;  i < m; ++i) {
		cout << ans[q[i].second] << ' ';
	}
	cout << '\n';
}

		/////////// End Solution ///////////////////////////////////////

		//////// Initialization ////////////////////////////////////

int main() {

	#ifndef ONLINE_JUDGE
	FILE *FIN = freopen("/home/danil/prog/input.txt", "r", stdin);
	clock_t time_start = clock();
		#endif

	ios::sync_with_stdio(false);
	cin.tie(NULL);

	solve();

		#ifndef ONLINE_JUDGE
	fclose(FIN);
	cerr << "\x1b[031m\n-----------------\nTime=" << (ll)((double)(clock()-time_start) / CLOCKS_PER_SEC * 1000) << "ms\n\x1b[0m";
		#endif

	return 0;
}

		//////// End Initialization ///////////////////////////////////////


#include <bits/stdc++.h>

using namespace std;

using ll = long long;

#define MAXN 200010

ll ft[MAXN],sz[MAXN],ans[MAXN];

int find(int x){
	if(ft[x] == x) return x;
	return ft[x] = find(ft[x]);
}

struct e{
	ll u,v,w;

	bool operator < (const struct e ed) const{
		return w < ed.w;
	}

}edge[MAXN] = {};

int main(){

	ll n,m;

	cin >> n >> m;

	for(int i=1;i<MAXN;++i){
		sz[i]=1;
		ft[i] = i;
	}

	for(int i=0;i<n-1;++i){
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}

	sort(edge,edge+n-1);

	for(int i=0;i<MAXN;++i){
		ll t1 = find(edge[i].u),t2 = find(edge[i].v);
		ans[edge[i].w]+= sz[t1]*sz[t2];
		if(sz[t1] > sz[t2]) swap(t1,t2);
		sz[t2]+=sz[t1];
		ft[t1] = t2;
	}

	for(int i=1;i<MAXN;++i){
		ans[i]+=ans[i-1];
	}

	for(int i=0;i<m;++i){
		ll x;
		cin >> x;
		cout << ans[x] << " ";
	}

	cout << "\n";

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define MAXN 200010

int ft[MAXN],sz[MAXN],ans[MAXN];

int find(int x){
	if(ft[x] == x) return x;
	return ft[x] = find(ft[x]);
}

struct e{
	int u,v,w;

	bool operator < (const struct e ed) const{
		return w < ed.w;
	}

}edge[MAXN];

int main(){

	int n,m;

	cin >> n >> m;

	for(int i=1;i<MAXN;++i){
		sz[i]=1;
		ft[i] = i;
	}

	for(int i=0;i<n-1;++i){
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}

	sort(edge,edge+MAXN);

	for(int i=0;i<MAXN;++i){
		int t1 = find(edge[i].u),t2 = find(edge[i].v);
		ans[edge[i].w]+= sz[t1]*sz[t2];
		if(sz[t1] > sz[t2]) swap(t1,t2);
		sz[t2]+=sz[t1];
		ft[t1] = t2;
	}

	for(int i=1;i<MAXN;++i){
		ans[i]+=ans[i-1];
	}

	for(int i=0;i<m;++i){
		int x;
		cin >> x;
		cout << ans[x] << " ";
	}

	cout << "\n";

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define MAXN 200010

int ft[MAXN],sz[MAXN],ans[MAXN];

int find(int x){
	if(ft[x] == x) return x;
	return ft[x] = find(ft[x]);
}

struct e{
	int u,v,w;

	bool operator < (const struct e ed) const{
		return w < ed.w;
	}

}edge[MAXN];

int main(){

	int n,m;

	cin >> n >> m;

	for(int i=1;i<=n;++i){
		sz[i]=1;
		ft[i] = i;
	}

	for(int i=0;i<n-1;++i){
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}

	sort(edge,edge+MAXN);

	for(int i=0;i<MAXN;++i){
		int t1 = find(edge[i].u),t2 = find(edge[i].v);
		ans[edge[i].w]+= sz[t1]*sz[t2];
		if(sz[t1] > sz[t2]) swap(t1,t2);
		sz[t2]+=sz[t1];
		ft[t1] = t2;
	}

	for(int i=1;i<MAXN;++i){
		ans[i]+=ans[i-1];
	}

	for(int i=0;i<m;++i){
		int x;
		cin >> x;
		cout << ans[x] << " ";
	}

	cout << "\n";

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define MAXN 200010

int ft[MAXN],sz[MAXN],ans[MAXN];

int find(int x){
	if(ft[x] == x) return x;
	return ft[x] = find(ft[x]);
}

void merge(int a,int b){
	a = find(a);
	b = find(b);

	if(a == b) return;

	if(sz[a] > sz[b]) swap(a,b);

	sz[b]+=sz[a];
	ft[a] = b;
}

struct e{
	int u,v,w;

	bool operator < (const struct e ed) const{
		return w < ed.w;
	}

}edge[MAXN];

int main(){

	int n,m;

	cin >> n >> m;

	for(int i=1;i<=n;++i){
		sz[i]=1;
		ft[i] = i;
	}

	for(int i=0;i<n-1;++i){
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}

	sort(edge,edge+MAXN);

	for(int i=0;i<MAXN;++i){
		ans[edge[i].w]+= sz[find(edge[i].u)]*sz[find(edge[i].v)];
		merge(edge[i].u,edge[i].v);
	}

	for(int i=1;i<MAXN;++i){
		ans[i]+=ans[i-1];
	}

	for(int i=0;i<m;++i){
		int x;
		cin >> x;
		cout << ans[x] << " ";
	}

	cout << "\n";

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define MAXN 200010

int ft[MAXN],sz[MAXN],ans[MAXN];

int find(int x){
	if(ft[x] == x) return x;
	return ft[x] = find(ft[x]);
}

struct e{
	int u,v,w;

	bool operator < (const struct e ed) const{
		return w < ed.w;
	}

}edge[MAXN] = {};

int main(){

	int n,m;

	cin >> n >> m;

	for(int i=1;i<MAXN;++i){
		sz[i]=1;
		ft[i] = i;
	}

	for(int i=0;i<n-1;++i){
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}

	sort(edge,edge+n-1);

	for(int i=1;i<MAXN;++i){
		int t1 = find(edge[i].u),t2 = find(edge[i].v);
		ans[edge[i].w]+= sz[t1]*sz[t2];
		if(sz[t1] > sz[t2]) swap(t1,t2);
		sz[t2]+=sz[t1];
		ft[t1] = t2;
	}

	for(int i=1;i<MAXN;++i){
		ans[i]+=ans[i-1];
	}

	for(int i=0;i<m;++i){
		int x;
		cin >> x;
		cout << ans[x] << " ";
	}

	cout << "\n";

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define MAXN 200010

int ft[MAXN],sz[MAXN],ans[MAXN];

int find(int x){
	if(ft[x] == x) return x;
	return ft[x] = find(ft[x]);
}

struct e{
	int u,v,w;

	bool operator < (const struct e ed) const{
		return w < ed.w;
	}

}edge[MAXN];

int main(){

	int n,m;

	cin >> n >> m;

	for(int i=1;i<MAXN;++i){
		sz[i]=1;
		ft[i] = i;
	}

	for(int i=0;i<n-1;++i){
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}

	sort(edge,edge+n-1);

	for(int i=0;i<MAXN;++i){
		int t1 = find(edge[i].u),t2 = find(edge[i].v);
		ans[edge[i].w]+= sz[t1]*sz[t2];
		if(sz[t1] > sz[t2]) swap(t1,t2);
		sz[t2]+=sz[t1];
		ft[t1] = t2;
	}

	for(int i=1;i<MAXN;++i){
		ans[i]+=ans[i-1];
	}

	for(int i=0;i<m;++i){
		int x;
		cin >> x;
		cout << ans[x] << " ";
	}

	cout << "\n";

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=1;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]-1))/2;
    an-=(ran[py]*(ran[py]-1))/2;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py];
    }

    an+=(ran[px]*(ran[px]-1))/2;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%d ",ans[i]);

    printf("\n");

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=1;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]-1))/2ll;
    an-=(ran[py]*(ran[py]-1))/2ll;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py];
    }

    an+=(ran[px]*(ran[px]-1))/2ll;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%d ",ans[i]);

    printf("\n");

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=0;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]+1))/2;
    an-=(ran[py]*(ran[py]+1))/2;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py]+1;
        ran[py]=0;
    }

    an+=(ran[px]*(ran[px]+1))/2;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%d ",ans[i]);

    printf("\n");

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=0;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]+1))/2ll;
    an-=(ran[py]*(ran[py]+1))/2ll;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py]+1;
        ran[py]=0;
    }

    an+=(ran[px]*(ran[px]+1))/2ll;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%d ",ans[i]);

    printf("\n");

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=0;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]+1ll))/2ll;
    an-=(ran[py]*(ran[py]+1ll))/2ll;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py]+1;
        ran[py]=0;
    }

    an+=(ran[px]*(ran[px]+1ll))/2ll;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%lld ",ans[i]);

    printf("\n");

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=1;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]-1))/2;
    an-=(ran[py]*(ran[py]-1))/2;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py];
    }

    an+=(ran[px]*(ran[px]-1))/2;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%lld ",ans[i]);

    printf("\n");

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct ed{
    int u,v,cost;
    inline bool operator<(const ed& x )const{
        return cost<x.cost;
    }
};

long long arr[200007],ran[200007];

long long ans[200007],an;

int n,q,m;

pair<int,int> query[200007];

vector<ed>v;

long long find_set(long long x)
{
    if(x!=arr[x])
        arr[x]=find_set(arr[x]);
    return arr[x];
}
void create_set(long long x)
{
    arr[x]=x;
    ran[x]=0;
    return;
}
void merge_set(long long x,long long y)
{
    long long px=find_set(x);
    long long py=find_set(y);

    an-=(ran[px]*(ran[px]+1))/2;
    an-=(ran[py]*(ran[py]+1))/2;

    if(px!=py) {
        arr[py]=px;
        ran[px]+=ran[py]+1;
        ran[py]=0;
    }

    an+=(ran[px]*(ran[px]+1))/2ll;

}

int main()
{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
        create_set(i);

    for(int i=0;i<n-1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        v.push_back({x,y,z});
    }

    sort(v.begin(),v.end());

    for(int i=0;i<m;i++)
    {
        scanf("%d",&query[i].first);
        query[i].second=i;
    }

    sort(query,query+m);

    int j=0;

    for(int i=0;i<m;i++)
    {
        while(j<n-1&&v[j].cost<=query[i].first)
        {
            merge_set(v[j].u,v[j].v);
            j++;
        }
        ans[query[i].second]=an;
    }

    for(int i=0;i<m;i++)
        printf("%d ",ans[i]);

    printf("\n");

    return 0;
}


using namespace std;
#include <bits/stdc++.h>
#include <string>

vector<vector<int> > edges;
long long ans = 0;

long long get(int k){
    return k * 1ll * (k - 1) / 2;
}

int find(int src, vector<int>& parent){
    if(parent[src] != src){
        parent[src] = find(parent[src], parent);
    }
    return parent[src];
}

void merge(int a, int b, vector<int>& parent, vector<int>& size){
    int pa = find(a, parent);
    int pb = find(b, parent);

    if(pa == pb){
        return;
    }

    if(size[pa] < size[pb]){
        swap(size[pa], size[pb]);
    }

    ans -= get(size[pa]);
    ans -= get(size[pb]);

    size[pa] += size[pb];

    ans += get(size[pa]);

    parent[pb] = pa;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    for(int i = 2; i <= n; i++){
        int x, y, w;
        cin >> x >> y >> w;
        edges.push_back({x, y, w});
    }
    vector<pair<int, int>> q;
    for(int i = 0; i < m; i++){
        int cur;
        cin >> cur;
        q.push_back(make_pair(i, cur));
    }

    sort(edges.begin(), edges.end(), [](const vector<int>& lhs, const vector<int>& rhs){
        return lhs[2] < rhs[2];
    });

    sort(q.begin(), q.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs){
        return lhs.second < rhs.second;
    });

    vector<int> parent(n + 1);
    vector<int> size(n + 1);
    for(int i = 0; i <= n; i++){
        parent[i] = i;
        size[i] = 1;
    }
    int pos = 0;
    vector<long long> res(m);
    for(int i = 0; i < q.size(); i++){
        int cur = q[i].second;
        while(pos < edges.size() && edges[pos][2] <= cur){
            int a = edges[pos][0];
            int b = edges[pos][1];
            merge(a, b, parent, size);
            pos++;
        }
        res[q[i].first] = ans;
    }

    for(int i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    cout << "\n";

    return 0;
}


using namespace std;
#include <bits/stdc++.h>
#include <string>

vector<vector<int> > edges;

int find(int src, vector<int>& parent){
    if(parent[src] != src){
        parent[src] = find(parent[src], parent);
    }
    return parent[src];
}

bool merge(int a, int b, vector<int>& parent, vector<int>& size){
    int pa = find(a, parent);
    int pb = find(b, parent);
    if(pa == pb){
        return false;
    }
    parent[pb] = pa;
    size[pa] += size[pb];
    return true;
}

int get(int k){
    return k * 1ll * (k - 1) / 2;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    for(int i = 2; i <= n; i++){
        int x, y, w;
        cin >> x >> y >> w;
        edges.push_back({x, y, w});
    }
    vector<pair<int, int>> q;
    for(int i = 0; i < m; i++){
        int cur;
        cin >> cur;
        q.push_back(make_pair(i, cur));
    }

    sort(edges.begin(), edges.end(), [](const vector<int>& lhs, const vector<int>& rhs){
        return lhs[2] < rhs[2];
    });

    sort(q.begin(), q.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs){
        return lhs.second < rhs.second;
    });

    vector<int> parent(n + 1);
    vector<int> size(n + 1);
    for(int i = 0; i <= n; i++){
        parent[i] = i;
        size[i] = 1;
    }
    int pos = 0;
    long long ans = 0;
    vector<long long> res(m);
    for(int i = 0; i < q.size(); i++){
        int cur = q[i].second;
        long long remove = 0;
        while(pos < edges.size() && edges[pos][2] <= cur){
            int a = edges[pos][0];
            int b = edges[pos][1];
            int asize = size[find(a, parent)];
            int bsize = size[find(b, parent)];
            remove = get(asize) + get(bsize);
            merge(a, b, parent, size);
            int usize = size[find(a, parent)];
            ans += get(usize);
            ans -= remove;
            pos++;
        }
        res[q[i].first] = ans;
    }

    for(int i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    cout << "\n";

    return 0;
}


using namespace std;
#include <bits/stdc++.h>
#include <string>

vector<vector<int> > edges;
long long ans = 0;

long long get(int k){
    return k * 1ll * (k - 1) / 2;
}

int find(int src, vector<int>& parent){
    if(parent[src] != src){
        parent[src] = find(parent[src], parent);
    }
    return parent[src];
}

void merge(int a, int b, vector<int>& parent, vector<int>& size){
    int pa = find(a, parent);
    int pb = find(b, parent);

    if(pa == pb){
        return;
    }

    ans -= get(size[pa]);
    ans -= get(size[pb]);

    size[pa] += size[pb];

    ans += get(size[pa]);

    parent[pb] = pa;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    for(int i = 2; i <= n; i++){
        int x, y, w;
        cin >> x >> y >> w;
        edges.push_back({x, y, w});
    }
    vector<pair<int, int>> q;
    for(int i = 0; i < m; i++){
        int cur;
        cin >> cur;
        q.push_back(make_pair(i, cur));
    }

    sort(edges.begin(), edges.end(), [](const vector<int>& lhs, const vector<int>& rhs){
        return lhs[2] < rhs[2];
    });

    sort(q.begin(), q.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs){
        return lhs.second < rhs.second;
    });

    vector<int> parent(n + 1);
    vector<int> size(n + 1);
    for(int i = 0; i <= n; i++){
        parent[i] = i;
        size[i] = 1;
    }
    int pos = 0;
    vector<long long> res(m);
    for(int i = 0; i < q.size(); i++){
        int cur = q[i].second;
        while(pos < edges.size() && edges[pos][2] <= cur){
            int a = edges[pos][0];
            int b = edges[pos][1];
            merge(a, b, parent, size);
            pos++;
        }
        res[q[i].first] = ans;
    }

    for(int i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    cout << "\n";

    return 0;
}


using namespace std;
#include <bits/stdc++.h>
#include <string>

vector<vector<int> > edges;
long long ans = 0;

long long get(int k){
    return k * 1ll * (k - 1) / 2;
}

int find(int src, vector<int>& parent){
    if(parent[src] != src){
        parent[src] = find(parent[src], parent);
    }
    return parent[src];
}

void merge(int a, int b, vector<int>& parent, vector<int>& size){
    int pa = find(a, parent);
    int pb = find(b, parent);
    if(size[pa] < size[pb]){
        swap(size[pa], size[pb]);
    }

    ans -= get(size[pa]);
    ans -= get(size[pb]);

    size[pa] += size[pb];

    ans += get(size[pa]);

    parent[pb] = pa;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    for(int i = 2; i <= n; i++){
        int x, y, w;
        cin >> x >> y >> w;
        edges.push_back({x, y, w});
    }
    vector<pair<int, int>> q;
    for(int i = 0; i < m; i++){
        int cur;
        cin >> cur;
        q.push_back(make_pair(i, cur));
    }

    sort(edges.begin(), edges.end(), [](const vector<int>& lhs, const vector<int>& rhs){
        return lhs[2] < rhs[2];
    });

    sort(q.begin(), q.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs){
        return lhs.second < rhs.second;
    });

    vector<int> parent(n + 1);
    vector<int> size(n + 1);
    for(int i = 0; i <= n; i++){
        parent[i] = i;
        size[i] = 1;
    }
    int pos = 0;
    vector<long long> res(m);
    for(int i = 0; i < q.size(); i++){
        int cur = q[i].second;
        while(pos < edges.size() && edges[pos][2] <= cur){
            int a = edges[pos][0];
            int b = edges[pos][1];
            merge(a, b, parent, size);
            pos++;
        }
        res[q[i].first] = ans;
    }

    for(int i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    cout << "\n";

    return 0;
}


using namespace std;
#include <bits/stdc++.h>
#include <string>

vector<vector<int> > edges;
long long ans = 0;

int find(int src, vector<int>& parent){
    if(parent[src] != src){
        parent[src] = find(parent[src], parent);
    }
    return parent[src];
}

void merge(int a, int b, vector<int>& parent, vector<int>& size){
    int pa = find(a, parent);
    int pb = find(b, parent);

    if(size[pa] < size[pb]){
        swap(size[pa], size[pb]);
    }

    ans -= get(size[pa]);
    ans -= get(size[pb]);

    size[pa] += size[pb];

    ans += get(size[pa]);

    parent[pb] = pa;
}

long long get(int k){
    return k * 1ll * (k - 1) / 2;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    for(int i = 2; i <= n; i++){
        int x, y, w;
        cin >> x >> y >> w;
        edges.push_back({x, y, w});
    }
    vector<pair<int, int>> q;
    for(int i = 0; i < m; i++){
        int cur;
        cin >> cur;
        q.push_back(make_pair(i, cur));
    }

    sort(edges.begin(), edges.end(), [](const vector<int>& lhs, const vector<int>& rhs){
        return lhs[2] < rhs[2];
    });

    sort(q.begin(), q.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs){
        return lhs.second < rhs.second;
    });

    vector<int> parent(n + 1);
    vector<int> size(n + 1);
    for(int i = 0; i <= n; i++){
        parent[i] = i;
        size[i] = 1;
    }
    int pos = 0;
    vector<long long> res(m);
    for(int i = 0; i < q.size(); i++){
        int cur = q[i].second;
        while(pos < edges.size() && edges[pos][2] <= cur){
            int a = edges[pos][0];
            int b = edges[pos][1];
            merge(a, b, parent, size);
            pos++;
        }
        res[q[i].first] = ans;
    }

    for(int i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    cout << "\n";

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<int> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        int all = pre[i] + i*a + suf[mid-i];
        if (all <= t){
            if ((n == 1000 && a == 323 && b == 1000) && mid == 986)
                cout << "A" << endl;
            return 1;
        }
        all = suf[i] + (i+1)*a + pre[mid-i];
        if (all <= t){
            if ((n == 1000 && a == 323 && b == 1000) && mid == 986)
                cout << "B" << endl;
            return 1;
        }
    }
    if ((pre[mid] <= t || a+suf[mid] <= t) && (n == 1000 && a == 323 && b == 1000) && mid == 986)
    cout << "BUL" << endl;

    return pre[mid] <= t || a+suf[mid] <= t;
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;

        f(986);
    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<int> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        int all = pre[i] + i*a + suf[mid-i];
        if (all <= t){

            return 1;
        }
        all = suf[i] + (i+1)*a + pre[mid-i];
        if (all <= t){

            return 1;
        }
    }

    return (pre[mid] <= t) || ((a+suf[mid]) <= t);
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;
        if (n > 986)
        f(986);
    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<ll> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        ll all = pre[i] + 1LL*i*a + suf[mid-i];
        if (all <= t){

            return 1;
        }
        all = suf[i] + (i+1)*a + pre[mid-i];
        if (all <= t){

            return 1;
        }
    }

    return (pre[mid] <= t) || ((a+suf[mid]) <= t);
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;

    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<int> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        int all = pre[i] + (2*(i-1)+1)*a + suf[mid-i];
        if (all <= t){
            //cout << "i = " << i << " , pre = " << pre[i] << " , suf = " << suf[i] << endl;
            return 1;
        }
        all = suf[i] + 2*i*a + pre[mid-i];
        if (all <= t){
            //cout << "i = " << i << " , pre = " << pre[i] << " , suf = " << suf[i] << endl;
            return 1;
        }
    }
    //cout << "BUL " << endl;
    return pre[mid] <= t || a+suf[mid] <= t;
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;

    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<ll> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        ll all = pre[i] + 1LL*i*a + suf[mid-i];
        if (all <= t){

            return 1;
        }
        all = suf[i] + (i+1)*a + pre[mid-i];
        if (all <= t){

            return 1;
        }
    }

    return (pre[mid] <= t) || ((pre[1] + a + suf[mid-1]) <= t);
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;

    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<int> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        int all = pre[i] + i*a + suf[mid-i];
        if (all <= t){
            if ((n == 1000 && a == 323 && b == 1000) && mid == 986)
                cout << "A" << endl;
            return 1;
        }
        all = suf[i] + (i+1)*a + pre[mid-i];
        if (all <= t){
            if ((n == 1000 && a == 323 && b == 1000) && mid == 986)
                cout << "B" << endl;
            return 1;
        }
    }
    if ((pre[mid] <= t || a+suf[mid] <= t) && (n == 1000 && a == 323 && b == 1000) && mid == 986)
    cout << "BUL" << endl;

    return pre[mid] <= t || a+suf[mid] <= t;
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;
        if (n > 986)
        f(986);
    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

int n, a, b, t;
char s[600000];
vector<int> pre, suf;

bool f(int mid)
{
    for (int i = 1; i < mid; ++i) {
        int all = pre[i] + i*a + suf[mid-i];
        if (all <= t){
            //cout << "i = " << i << " , pre = " << pre[i] << " , suf = " << suf[i] << endl;
            return 1;
        }
        all = suf[i] + (i+1)*a + pre[mid-i];
        if (all <= t){
            //cout << "i = " << i << " , pre = " << pre[i] << " , suf = " << suf[i] << endl;
            return 1;
        }
    }
    //cout << "BUL " << endl;
    return pre[mid] <= t || a+suf[mid] <= t;
}

int main()
{
    scanf("%d %d %d %d",&n,&a,&b,&t);
    pre.push_back(0);
    suf.push_back(0);
    for (int i = 0; i < n; ++i) {
        scanf(" %c",s+i);
        pre.push_back(pre.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == 0) pre.back() -= a;
    }

    for (int i=n-1;i>=0;i--){
        suf.push_back(suf.back()+a+(s[i]=='h' ? 1 : b+1));
        if (i == n-1) suf.back() -= a;
    }

    int low = 0, high = n;
    int ans = 0;
    f(4);
    while (low <= high)
    {
        int mid = (low+high) / 2;
        if (f(mid))
            ans = mid, low = mid+1;
        else
            high = mid-1;

    }

    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int maxn = 5e5 + 500;
int n , a , b , T , st[maxn];
char str[maxn];
long long dpL[maxn] , dpR[maxn];

/*
w -> 0 , h -> 1;
初始时是 h -> 1
*/

inline void updata( long long & x , long long v) {
	x = min( x , v );
}

void init(){
    long long add = 0;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[i]==0) add += b ;
		add ++;
		dpR[i] = add;
		add += a;
	}
	for(int i = 1 ; i <= n ; ++ i) dpL[i]=1LL<<60;
	int idx = n;
	dpL[1]=a+1;
	if(st[n]==0) dpL[1]+=b;
	for(int i = 1 ; i < n ; ++ i){
		if(st[idx-1]==0) updata(dpL[i+1],dpL[i]+a+b+1);
		else updata(dpL[i+1],dpL[i]+a+1);
	    idx--;
	}
}

int my_binary(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpL[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int main(int argc,char *argv[]){
	scanf("%d%d%d%d%s",&n,&a,&b,&T,str+1);
	for(int i = 1 ; i <= n ; ++ i) if(str[i]=='w') st[i] = 0 ; else st[i] = 1;
	init();
    int ans = 0;
    for(int r = 1 ; r <= n ; ++ r){
    	if(dpR[r]>T) break;
    	else{
    		int rp = T - dpR[r];
    		int pos = my_binary( rp - 1LL * a * ( r - 1 ) , n - r);
    		ans = max( ans , r + pos );
    	}
    }
    printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int maxn = 5e5 + 500;
int n , a , b , T , st[maxn];
char str[maxn];
long long dpL[maxn] , dpR[maxn];

/*
w -> 0 , h -> 1;
初始时是 h -> 1
*/

inline void updata( long long & x , long long v) {
	x = min( x , v );
}

void init(){
    long long add = 0;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[i]==0) add += b ;
		add ++;
		dpR[i] = add;
		add += a;
	}
	for(int i = 1 ; i <= n ; ++ i) dpL[i]=1LL<<60;
	int idx = n;
	dpL[1]=a+1;
	if(st[n]==0) dpL[1]+=b;
	for(int i = 1 ; i < n ; ++ i){
		if(st[idx-1]==0) updata(dpL[i+1],dpL[i]+a+b+1);
		else updata(dpL[i+1],dpL[i]+a+1);
	    idx--;
	}
}

void init2(){
	long long add = 0;
	int idx = 1;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[idx]==0) add += b ;
		add ++;
		dpL[i] = add;
		add += a;
		idx--;
		if(idx == 0) idx = n;
	}
	dpR[0]=0;
	for(int i = 1 ; i <= n ; ++ i) dpR[i]=1LL<<60;
	for(int i = 0 ; i < n ; ++ i){
		if(st[i+1]==0) updata(dpR[i+1],dpR[i]+a+b+1);
		else updata(dpR[i+1],dpR[i]+a+1);
	}
}

int my_binary(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpL[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int my_binary2(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpR[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int main(int argc,char *argv[]){
	scanf("%d%d%d%d%s",&n,&a,&b,&T,str+1);
	for(int i = 1 ; i <= n ; ++ i) if(str[i]=='w') st[i] = 0 ; else st[i] = 1;
	init();
    int ans = 0;
    for(int r = 1 ; r <= n ; ++ r){
    	if(dpR[r]>T) break;
    	else{
    		int rp = T - dpR[r];
    		int pos = my_binary( rp - 1LL * a * ( r - 1 ) , n - r);
    		ans = max( ans , r + pos );
    	}
    }
    init2();
    for(int l = 1 ; l <= n ; ++ l){
    	if(dpL[l]>T) break;
    	else{
    		int rp = T - dpL[l];
    		int pos = my_binary2( rp - 1LL * a * ( l - 1 ) , n - l);
    		ans = max( ans , l + pos );
    	}
    }
    printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int maxn = 5e5 + 500;
int n , a , b , T , st[maxn];
char str[maxn];
long long dpL[maxn] , dpR[maxn];

/*
w -> 0 , h -> 1;
初始时是 h -> 1
*/

inline void updata( long long & x , long long v) {
	x = min( x , v );
}

void init(){
    long long add = 0;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[i]==0) add += b ;
		add ++;
		dpR[i] = add;
		add += a;
	}
	for(int i = 1 ; i <= n ; ++ i) dpL[i]=1LL<<60;
	int idx = n;
	dpL[1]=a+1;
	if(st[n]==0) dpL[1]+=b;
	for(int i = 1 ; i < n ; ++ i){
		if(st[idx-1]==0) updata(dpL[i+1],dpL[i]+a+b+1);
		else updata(dpL[i+1],dpL[i]+a+1);
	    idx--;
	}
}

void init2(){
	long long add = 0;
	int idx = 1;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[idx]==0) add += b ;
		add ++;
		dpL[i] = add;
		add += a;
		idx--;
		if(idx == 0) idx = n;
	}
	dpR[0]=0;
	for(int i = 1 ; i <= n ; ++ i) dpR[i]=1LL<<60;
	dpR[1]=a+1;
	if(st[1]==0) dpR[1]+=b;
	for(int i = 1 ; i < n ; ++ i){
		if(st[i+1]==0) updata(dpR[i+1],dpR[i]+a+b+1);
		else updata(dpR[i+1],dpR[i]+a+1);
	}
}

int my_binary(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpL[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int my_binary2(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpR[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int main(int argc,char *argv[]){
	scanf("%d%d%d%d%s",&n,&a,&b,&T,str+1);
	for(int i = 1 ; i <= n ; ++ i) if(str[i]=='w') st[i] = 0 ; else st[i] = 1;
	init();
    int ans = 0;
    for(int r = 1 ; r <= n ; ++ r){
    	if(dpR[r]>T) break;
    	else{
    		int rp = T - dpR[r];
    		int pos = my_binary( rp - 1LL * a * ( r - 1 ) , n - r);
    		ans = max( ans , r + pos );
    	}
    }
    init2();
    for(int l = 1 ; l <= n ; ++ l){
    	if(dpL[l]>T) break;
    	else{
    		int rp = T - dpL[l];
    		int pos = my_binary2( rp - 1LL * a * ( l - 1 ) , n - l);
    		ans = max( ans , l + pos );
    	}
    }
    printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int maxn = 5e5 + 500;
int n , a , b , T , st[maxn];
char str[maxn];
long long dpL[maxn] , dpR[maxn];

/*
w -> 0 , h -> 1;
初始时是 h -> 1
*/

inline void updata( long long & x , long long v) {
	x = min( x , v );
}

void init(){
    long long add = 0;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[i]==0) add += b ;
		add ++;
		dpR[i] = add;
		add += a;
	}
	for(int i = 1 ; i <= n ; ++ i) dpL[i]=1LL<<60;
	int idx = n;
	dpL[1]=a+1;
	if(st[n]==0) dpL[1]+=b;
	for(int i = 1 ; i < n ; ++ i){
		if(st[idx-1]==0) updata(dpL[i+1],dpL[i]+a+b+1);
		else updata(dpL[i+1],dpL[i]+a+1);
	    idx--;
	}
}

void init2(){
	long long add = 0;
	int idx = 1;
	for(int i = 1 ; i <= n ; ++ i){
		if(st[idx]==0) add += b ;
		add ++;
		dpL[i] = add;
		add += a;
		idx--;
		if(idx == 0) idx = n;
	}
	dpR[0]=0;
	idx = 2;
	for(int i = 1 ; i <= n ; ++ i) dpR[i]=1LL<<60;
	for(int i = 0 ; i < n ; ++ i){
		if(st[idx]==0) updata(dpR[i+1],dpR[i]+a+b+1);
		else updata(dpR[i+1],dpR[i]+a+1);
		idx++;
	}
}

int my_binary(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpL[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int my_binary2(long long rp , int limit){
	if(rp < 0) return 0;
	int l = 0 , r = limit;
	while( l < r ){
		int mid = l + r + 1 >> 1;
		if(dpR[mid] > rp) r = mid - 1;
		else l = mid;
	}
	return l;
}

int main(int argc,char *argv[]){
	scanf("%d%d%d%d%s",&n,&a,&b,&T,str+1);
	for(int i = 1 ; i <= n ; ++ i) if(str[i]=='w') st[i] = 0 ; else st[i] = 1;
	init();
    int ans = 0;
    for(int r = 1 ; r <= n ; ++ r){
    	if(dpR[r]>T) break;
    	else{
    		int rp = T - dpR[r];
    		int pos = my_binary( rp - 1LL * a * ( r - 1 ) , n - r);
    		ans = max( ans , r + pos );
    	}
    }
    init2();
    for(int l = 1 ; l <= n ; ++ l){
    	if(dpL[l]>T) break;
    	else{
    		int rp = T - dpL[l];
    		int pos = my_binary2( rp - 1LL * a * ( l - 1 ) , n - l);
    		ans = max( ans , l + pos );
    	}
    }
    printf("%d\n",ans);
	return 0;
}