#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int fw[N];
template <class data_structure, bool excl_l = false>
struct heavy_light_decomposition {
  int n;
  vector<vector<int>> G;
  vector<int> parent, depth, head, pos, endpos;
  data_structure ds;
  heavy_light_decomposition(int n)
      : n(n), G(n), parent(n, -1), depth(n), head(n), pos(n), ds(n) {}
  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }
  void rootify_rec(int r = 0) {
    vector<int> sz(n, 1);
    function<void(int)> dfs = [&](int u) {
      for (auto &v : G[u])
        if (v != parent[u]) {
          depth[v] = depth[u] + 1;
          parent[v] = u;
          dfs(v);
          sz[u] += sz[v];
          if (sz[v] > sz[G[u][0]] || G[u][0] == parent[u]) swap(v, G[u][0]);
        }
    };
    dfs(r);
    int p = 0;
    endpos.resize(n);
    function<void(int)> dfs_hld = [&](int u) {
      pos[u] = p++;
      for (auto v : G[u])
        if (v != parent[u]) {
          head[v] = (v == G[u][0]) ? head[u] : v;
          dfs_hld(v);
        }
      endpos[u] = p;
    };
    head[r] = r;
    dfs_hld(r);
  }
  void rootify(int r = 0) {
    vector<int> heavy(n, -1), q(1, r), size(n, 1);
    for (int i = 0, u; i < n; ++i) {
      u = q[i];
      for (auto v : G[u])
        if (parent[u] != v)
          q.push_back(v), parent[v] = u, depth[v] = depth[u] + 1;
    }
    for (int i = n - 1, u; i >= 0; --i) {
      u = q[i];
      for (auto v : G[u])
        if (parent[u] != v) {
          size[u] += size[v];
          if (heavy[u] == -1 || size[v] > size[heavy[u]]) heavy[u] = v;
        }
    }
    for (int u = 0, p = 0; u < n; ++u)
      if (u == r || heavy[parent[u]] != u)
        for (int v = u; v != -1; v = heavy[v]) head[v] = u, pos[v] = p++;
  }
  int lca(int u, int v) {
    while (head[u] != head[v]) {
      if (depth[head[u]] < depth[head[v]]) swap(u, v);
      u = parent[head[u]];
    }
    return (depth[u] < depth[v] ? u : v);
  }
  using node_container = typename data_structure::node_container;
  vector<node_container> query_up(int u, int v, bool excl_v) {
    vector<node_container> ans;
    while (head[u] != head[v]) {
      ans.push_back(ds.query(pos[head[u]], pos[u] + 1));
      u = parent[head[u]];
    }
    if (pos[v] + excl_v <= pos[u])
      ans.push_back(ds.query(pos[v] + excl_v, pos[u] + 1));
    return ans;
  }
  long long query(int u, int v) {
    int l = lca(u, v);
    auto v1 = query_up(u, l, excl_l);
    auto v2 = query_up(v, l, true);
    node_container cur1, cur2;
    for (auto i : v1) cur1 = i + cur1;
    for (auto i : v2) cur2 = i + cur2;
    swap(cur1.p, cur1.s);
    return (cur1 + cur2).ans;
  }
  void update(int u, int v) {
    int x = (depth[u] > depth[v]) ? u : v;
    ds.update(pos[x], pos[x] + 1, {});
  }
};
enum seg_type { seg_not_lazy, seg_lazy, seg_beats };
template <class node, seg_type type>
struct segment_tree {
  using node_container = typename node::node_container;
  using lazy_container = typename node::lazy_container;

 private:
  template <const bool T = (type != seg_not_lazy),
            typename enable_if<T, bool>::type = 0>
  inline void push(int x, int b, int e, int m) {
    if (st[x].lazy()) {
      st[x + 1].apply(b, m, st[x].lazy);
      st[x + ((m - b) << 1)].apply(m, e, st[x].lazy);
      st[x].lazy = lazy_container();
    }
  }
  template <const bool T = (type != seg_not_lazy),
            typename enable_if<!T, bool>::type = 0>
  inline void push(int x, int b, int e, int m) {}
  template <typename RAIter>
  void build(int x, int b, int e, const RAIter &a) {
    if (b + 1 == e) {
      st[x].nod.build(a[b]);
      return;
    }
    int m = (b + e) >> 1;
    int y = x + ((m - b) << 1);
    build(x + 1, b, m, a);
    build(y, m, e, a);
    st[x].nod = st[x + 1].nod + st[y].nod;
  }
  template <const bool T = (type == seg_beats),
            typename enable_if<!T, bool>::type = 0>
  void update_(int x, int b, int e) {
    if (lo <= b && e <= hi) {
      st[x].apply(b, e, lazy);
      return;
    }
    int m = (b + e) >> 1;
    int y = x + ((m - b) << 1);
    push(x, b, e, m);
    if (lo < m) update_(x + 1, b, m);
    if (m < hi) update_(y, m, e);
    st[x].nod = st[x + 1].nod + st[y].nod;
  }
  template <const bool T = (type == seg_beats),
            typename enable_if<T, bool>::type = 0>
  void update_(int x, int b, int e) {
    if (st[x].break_condition(lazy)) return;
    if (lo <= b && e <= hi && st[x].tag_condition(lazy)) {
      st[x].apply(b, e, lazy);
      return;
    }
    int m = (b + e) >> 1;
    int y = x + ((m - b) << 1);
    push(x, b, e, m);
    if (lo < m) update_(x + 1, b, m);
    if (m < hi) update_(y, m, e);
    st[x].nod = st[x + 1].nod + st[y].nod;
  }
  node_container query(int x, int b, int e) {
    if (lo <= b && e <= hi) return st[x].nod;
    int m = (b + e) >> 1;
    int y = x + ((m - b) << 1);
    push(x, b, e, m);
    if (m >= hi) return query(x + 1, b, m);
    if (m <= lo) return query(y, m, e);
    return query(x + 1, b, m) + query(y, m, e);
  }
  template <class P>
  int find_first(int x, int b, int e, const P &f) {
    if (b + 1 == e) return f(st[x]) ? b : -1;
    int m = (b + e) >> 1;
    int y = x + ((m - b) << 1);
    push(x, b, e, m);
    if (lo < m && f(st[x + 1])) {
      auto t = find_first(x + 1, b, m, f);
      if (t != -1) return t;
    }
    if (m < hi && f(st[y])) return find_first(y, m, e, f);
    return -1;
  }
  template <class P>
  int find_last(int x, int b, int e, const P &f) {
    if (b + 1 == e) return f(st[x]) ? b : -1;
    int m = (b + e) >> 1;
    int y = x + ((m - b) << 1);
    push(x, b, e, m);
    if (m < hi && f(st[y])) {
      auto t = find_last(y, m, e, f);
      if (t != -1) return t;
    }
    if (lo < m && f(st[x + 1])) return find_last(x + 1, b, m, f);
    return -1;
  }
  lazy_container lazy;
  int n, lo, hi;
  vector<node> st;

 public:
  template <typename RAIter>
  void build(const RAIter &a) {
    build(0, 0, n, a);
  }
  void update(int l, int r, const lazy_container &x) {
    lo = l, hi = r, lazy = x, update_(0, 0, n);
  }
  node_container query(int l, int r) { return lo = l, hi = r, query(0, 0, n); }
  template <class P>
  int find_first(int l, int r, const P &f) {
    return lo = l, hi = r, find_first(0, 0, n, f);
  }
  template <class P>
  int find_last(int l, int r, const P &f) {
    return lo = l, hi = r, find_last(0, 0, n, f);
  }
  segment_tree(int n) : n(n), st(2 * n - 1) {}
};
struct node {
  struct node_container {
    bool all;
    long long ans, p, s;
    template <typename T>
    inline void build(const T &a) {
      assert(0);
    }
    friend node_container operator+(const node_container &l,
                                    const node_container &r) {
      node_container x;
      x.all = l.all & r.all;
      x.p = l.p + l.all * r.p;
      x.s = r.s + r.all * l.s;
      x.ans = l.ans + r.ans + (!l.all) * (!r.all) * fw[l.s + r.p];
      return x;
    }
    node_container() : all(false), ans(0), p(0), s(0) {}
  } nod;
  struct lazy_container {
    inline bool operator()() { assert(0); }
    lazy_container() {}
  } lazy;
  inline void apply(int l, int r, lazy_container &p) {
    nod.all = true;
    nod.ans = 0;
    nod.p = nod.s = 1;
  }
};
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0);
  int n, q;
  cin >> n >> q;
  for (int i = 1; i < n; ++i) cin >> fw[i];
  heavy_light_decomposition<segment_tree<node, seg_type::seg_not_lazy>, true>
      hld(n);
  vector<tuple<int, int, int>> e;
  for (int i = 1, u, v, w; i < n; ++i) {
    cin >> u >> v >> w;
    --u, --v;
    e.push_back({w, u, v});
    hld.add_edge(u, v);
  }
  hld.rootify(0);
  vector<tuple<int, int, int, int>> que(q);
  for (auto &i : que) {
    int u, v, w;
    cin >> u >> v >> w;
    --u, --v;
    i = {w, u, v, &i - &que[0]};
  }
  sort(e.rbegin(), e.rend());
  sort(que.rbegin(), que.rend());
  vector<long long> ans(q);
  for (int i = 0, j = 0; i < q; ++i) {
    while (j < n - 1 && get<0>(e[j]) >= get<0>(que[i])) {
      int _t, u, v;
      tie(_t, u, v) = e[j];
      hld.update(u, v);
      ++j;
    }
    int _t, u, v, id;
    tie(_t, u, v, id) = que[i];
    ans[id] = hld.query(u, v);
  }
  for (auto &i : ans) cout << i << "\n";
  return 0;
}
