#include <bits/stdc++.h>
const int INF = 2000000005;
const long long BIG_INF = 2000000000000000005;
const int mod = 1000000007;
const int P = 31;
const long double PI = 3.141592653589793238462643;
const double eps = 1e-9;
using namespace std;
vector<pair<int, int> > dir = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
bool valid(int x, int y, int n, int m) {
  return x >= 0 && y >= 0 && x < n && y < m;
}
mt19937 rng(1999999973);
struct node {
  bool allone;
  int suf, pref, sum;
  node(bool val = false) {
    suf = pref = val;
    allone = val;
    sum = 0;
  }
};
struct query {
  int u, v, l, ans;
  query() {}
};
const int N = 100000 + 5, logN = 17;
int sz[N], h[N], path[N], highest[N], lowest[N], f[N], p[N], dp[N][logN],
    order_edge[N], order_query[N], n, q, o = 0;
bool good[N];
query req[N];
vector<node> t[N];
vector<pair<int, int> > g[N];
inline node combine(node a, node b) {
  node res;
  if (a.sum == -INF) return b;
  if (b.sum == -INF) return a;
  res.sum = a.sum + b.sum;
  res.pref = a.pref;
  if (a.allone) res.pref += b.pref;
  res.suf = b.suf;
  if (b.allone) res.suf += a.suf;
  if (!b.allone && !a.allone) res.sum += f[b.pref + a.suf];
  res.allone = (a.allone & b.allone);
  return res;
}
void dfs(int v, int pnode, int pval) {
  p[v] = pval;
  dp[v][0] = pnode;
  sz[v] = 1;
  path[v] = -1;
  good[v] = true;
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first, w = g[v][i].second;
    if (to == pnode) continue;
    h[to] = h[v] + 1;
    dfs(to, v, w);
    sz[v] += sz[to];
  }
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first, w = g[v][i].second;
    if (to == pnode) continue;
    if (sz[to] >= (sz[v] + 1) / 2) good[v] = false;
  }
}
inline void getPath(int v, int cur) {
  path[v] = cur;
  lowest[cur] = v;
  for (int i = 0; i < 4; i++) {
    t[cur].push_back(node());
  }
  if (((sz[dp[v][0]] + 1) / 2 > sz[v]) || dp[v][0] == 0) return;
  getPath(dp[v][0], cur);
}
inline void build_dp() {
  for (int j = 1; j < logN; j++) {
    for (int i = 0; i < n; i++) {
      dp[i][j] = dp[dp[i][j - 1]][j - 1];
    }
  }
}
inline int upper(int v, int dist) {
  for (int j = 0; j < logN; j++) {
    if ((dist >> j) % 2 == 1) v = dp[v][j];
  }
  return v;
}
inline int lca(int u, int v) {
  if (h[u] < h[v]) swap(u, v);
  u = upper(u, h[u] - h[v]);
  if (u == v) return u;
  for (int j = logN - 1; j >= 0; j--) {
    if (dp[v][j] != dp[u][j]) v = dp[v][j], u = dp[u][j];
  }
  return dp[v][0];
}
void update(int v, int tl, int tr, int pos, int o) {
  if (!(pos >= tl && pos <= tr)) return;
  if (tl == tr) {
    t[o][v] = node(true);
    return;
  }
  int tm = (tl + tr) / 2;
  update(v * 2, tl, tm, pos, o);
  update(v * 2 + 1, tm + 1, tr, pos, o);
  t[o][v] = combine(t[o][v * 2], t[o][v * 2 + 1]);
}
node getNode(int v, int tl, int tr, int l, int r, int o) {
  if (tl >= l && tr <= r) return t[o][v];
  if (tl > r || tr < l) {
    node res;
    res.sum = -INF;
    return res;
  }
  int tm = (tl + tr) / 2;
  return combine(getNode(v * 2, tl, tm, l, r, o),
                 getNode(v * 2 + 1, tm + 1, tr, l, r, o));
}
bool comp1(int x, int y) { return p[x] > p[y]; }
bool comp2(int x, int y) { return req[x].l > req[y].l; }
inline node getPathNode(int v, int lc) {
  node res;
  res.sum = -INF;
  int curv = v;
  while (h[curv] > h[lc]) {
    res = combine(
        getNode(1, 0, t[path[curv]].size() / 4 - 1,
                max(h[lowest[path[curv]]], h[lc] + 1) - h[lowest[path[curv]]],
                h[curv] - h[lowest[path[curv]]], path[curv]),
        res);
    curv = dp[lowest[path[curv]]][0];
  }
  return res;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> q;
  for (int i = 1; i <= n - 1; i++) cin >> f[i];
  for (int i = 0; i < n - 1; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    u--, v--;
    g[u].push_back(make_pair(v, w));
    g[v].push_back(make_pair(u, w));
  }
  for (int i = 0; i < q; i++) {
    cin >> req[i].u >> req[i].v >> req[i].l;
    req[i].v--, req[i].u--;
  }
  dfs(0, 0, -INF);
  for (int i = 1; i < n; i++) {
    if (good[i]) {
      getPath(i, o);
      highest[o] = i;
      o++;
    }
  }
  build_dp();
  for (int i = 0; i < n; i++) order_edge[i] = i;
  for (int i = 0; i < q; i++) order_query[i] = i;
  sort(order_edge, order_edge + n, comp1);
  sort(order_query, order_query + q, comp2);
  int pointer = 0;
  for (int i = 0; i < q; i++) {
    while (pointer < n - 1 && p[order_edge[pointer]] >= req[order_query[i]].l) {
      update(1, 0, t[path[order_edge[pointer]]].size() / 4 - 1,
             h[order_edge[pointer]] - h[lowest[path[order_edge[pointer]]]],
             path[order_edge[pointer]]);
      pointer++;
    }
    int cur = order_query[i], u = req[cur].u, v = req[cur].v, lc = lca(u, v),
        res = 0;
    if (u == v) {
      req[cur].ans = 0;
      continue;
    }
    node ansU, ansV, answer;
    if (u != lc && v != lc) {
      ansU = getPathNode(u, lc), ansV = getPathNode(v, lc);
      swap(ansU.pref, ansU.suf);
      answer = combine(ansU, ansV);
    } else {
      if (u == lc)
        answer = getPathNode(v, lc);
      else
        answer = getPathNode(u, lc);
    }
    if (answer.allone)
      req[cur].ans = f[answer.pref];
    else
      req[cur].ans = answer.sum + f[answer.pref] + f[answer.suf];
  }
  for (int i = 0; i < q; i++) {
    cout << req[i].ans << '\n';
  }
  return 0;
}
