#include <bits/stdc++.h>
using namespace std;
int read() {
  char c = getchar();
  int x = 0;
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
  return x;
}
const int N = 4e5 + 10;
struct Edge {
  int nxt, point, w;
} edge[N << 1];
int head[N], tot, n, a[N];
long long f[N], g[N];
int wson[N], siz[N], dep[N], top[N], fa[N], dfn[N], dfntot;
long long disa[N], disw[N];
void add_edge(int u, int v, int w) {
  edge[++tot].nxt = head[u];
  edge[tot].point = v;
  edge[tot].w = w;
  head[u] = tot;
}
void dfs(int u) {
  f[u] = a[u];
  siz[u] = 1;
  dep[u] = dep[fa[u]] + 1;
  disa[u] += a[u];
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].point;
    if (v == fa[u]) continue;
    fa[v] = u;
    disa[v] = disa[u];
    disw[v] = disw[u] + edge[i].w;
    dfs(v);
    siz[u] += siz[v];
    if (siz[wson[u]] < siz[v]) wson[u] = v;
    f[u] += max(0ll, f[v] - 2 * edge[i].w);
  }
}
void treedp(int u, int fa) {
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].point;
    if (v == fa) continue;
    f[u] -= max(0ll, f[v] - 2 * edge[i].w);
    g[v] = max(0ll, f[u] - 2 * edge[i].w);
    f[v] += g[v];
    treedp(v, u);
    f[v] -= g[v];
    f[u] += max(0ll, f[v] - 2 * edge[i].w);
  }
}
long long F[N];
void dfs2(int u, int topver) {
  dfn[u] = ++dfntot;
  top[u] = topver;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].point;
    if (!dfn[v]) f[v] = max(f[v] - 2 * edge[i].w, 0ll);
  }
  if (wson[u])
    dfs2(wson[u], topver);
  else
    return;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].point;
    if (!dfn[v]) {
      F[dfn[u]] += f[v];
      dfs2(v, v);
    }
  }
}
int lca(int u, int v) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    u = fa[top[u]];
  }
  if (dep[u] > dep[v]) swap(u, v);
  return u;
}
bool in(int u, int v) {
  return dfn[v] >= dfn[u] && dfn[v] <= dfn[u] + siz[u] - 1;
}
void solve(int u, int v) {
  int x = lca(u, v);
  long long ans = (disa[u] + disa[v] - 2 * disa[x] + a[x]) -
                  (disw[u] + disw[v] - 2 * disw[x]);
  if (u == v)
    ans += f[wson[u]];
  else {
    if (dep[u] < dep[v]) swap(u, v);
    ans += f[wson[u]];
    if (x != v) ans += f[wson[v]];
  }
  bool tag = 0;
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    ans += F[dfn[u]] - F[dfn[top[u]] - 1];
    int t = top[u];
    ans -= f[t];
    if (fa[t] == x) {
      if (!in(wson[fa[t]], v) && !tag) ans += f[wson[fa[t]]], tag = 1;
    } else
      ans += f[wson[fa[t]]];
    u = fa[top[u]];
  }
  if (dfn[u] < dfn[v]) swap(u, v);
  ans += F[dfn[u]] - F[dfn[v] - 1];
  ans += g[x];
  printf("%lld\n", ans);
}
int main() {
  n = read();
  int q = read();
  for (int i = 1; i <= n; ++i) a[i] = read();
  for (int i = 1; i < n; ++i) {
    int u = read(), v = read(), w = read();
    add_edge(u, v, w);
    add_edge(v, u, w);
  }
  dfs(1);
  treedp(1, 0);
  dfs2(1, 1);
  for (int i = 1; i <= n; ++i) F[i] += F[i - 1];
  while (q--) {
    int u = read(), v = read();
    solve(u, v);
  }
  return 0;
}
