#include <bits/stdc++.h>
using namespace std;
struct edge {
  int v = 0;
  long long cost = 0;
  edge(int v_ = 0, int cost_ = 0) {
    v = v_;
    cost = cost_;
  }
};
vector<edge> adj[(int)(3e5 + 10)];
int n, q, p[20][(int)(3e5 + 10)], lev[(int)(3e5 + 10)];
long long ver[(int)(3e5 + 10)], dp_down[(int)(3e5 + 10)],
    dp_up[(int)(3e5 + 10)];
long long dp[20][(int)(3e5 + 10)], cost[(int)(3e5 + 10)];
inline int lca(int v, int u) {
  for (int i = 20 - 1; ~i; i--)
    if (lev[p[i][u]] >= lev[v]) u = p[i][u];
  if (v == u) return v;
  for (int i = 20 - 1; ~i; i--)
    if (p[i][v] != p[i][u]) {
      v = p[i][v];
      u = p[i][u];
    }
  return p[0][v];
}
inline long long get(int &v, int l) {
  long long res = dp_down[v];
  for (int i = 0; i < 20; i++)
    if (l & (1 << i)) {
      res += dp[i][v];
      v = p[i][v];
    }
  return res;
}
void dfs_down(int v, int par = 0) {
  dp_down[v] = ver[v];
  p[0][v] = par;
  lev[v] = lev[par] + 1;
  for (auto e : adj[v])
    if (par ^ e.v) {
      cost[e.v] = e.cost;
      dfs_down(e.v, v);
      if ((dp_down[e.v] - 2 * e.cost) > 0)
        dp_down[v] += dp_down[e.v] - 2 * e.cost;
    }
}
void dfs_up(int v, int par = 0, long long up = 0) {
  dp_up[v] = up + ver[v];
  long long local =
      max(0ll, dp_down[v] - ver[v]) + max(0ll, dp_up[v] - ver[v]) + ver[v];
  for (auto e : adj[v])
    if (par ^ e.v)
      dfs_up(
          e.v, v,
          max(0ll, local - max(0ll, dp_down[e.v] - 2 * e.cost) - 2 * e.cost));
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> q;
  for (int i = 1; i <= n; i++) cin >> ver[i];
  for (int i = 1; i < n; i++) {
    int u, v, c;
    cin >> u >> v >> c;
    adj[v].push_back(edge(u, c));
    adj[u].push_back(edge(v, c));
  }
  dfs_down(1);
  dfs_up(1);
  for (int i = 2; i <= n; i++) {
    dp[0][i] = dp_down[p[0][i]] - cost[i] - max(0ll, dp_down[i] - 2 * cost[i]);
  }
  for (int i = 1; i < 20; i++) {
    for (int v = 1, papa = p[i - 1][1]; v <= n; v++, papa = p[i - 1][v]) {
      p[i][v] = p[i - 1][papa];
      if (lev[v] <= (1 << i)) continue;
      dp[i][v] = dp[i - 1][v] + dp[i - 1][papa];
    }
  }
  while (q--) {
    int v, u;
    cin >> v >> u;
    if (lev[v] > lev[u]) swap(v, u);
    int LCA = lca(v, u);
    if (LCA == v) {
      cout << get(u, lev[u] - lev[v]) + max(0ll, dp_up[v] - ver[v]) << '\n';
      continue;
    }
    long long res =
        get(v, lev[v] - lev[LCA] - 1) + get(u, lev[u] - lev[LCA] - 1);
    res += dp_up[LCA] + dp_down[LCA] - ver[LCA] - cost[v] - cost[u];
    res -= max(0ll, (dp_down[v] - 2 * cost[v])) +
           max(0ll, (dp_down[u] - 2 * cost[u]));
    cout << res << '\n';
  }
  return 0;
}

### Prompt

Generate a CPP solution to the following problem:

You are given a weighted tree (undirected connected graph with no cycles, loops or multiple edges) with n vertices. The edge \\{u_j, v_j\} has weight w_j. Also each vertex i has its own value a_i assigned to it.

Let's call a path starting in vertex u and ending in vertex v, where each edge can appear no more than twice (regardless of direction), a 2-path. Vertices can appear in the 2-path multiple times (even start and end vertices).

For some 2-path p profit Pr(p) = ∑_{v ∈ distinct vertices in  p}{a_v} - ∑_{e ∈ distinct edges in  p}{k_e ⋅ w_e}, where k_e is the number of times edge e appears in p. That is, vertices are counted once, but edges are counted the number of times they appear in p.

You are about to answer m queries. Each query is a pair of vertices (qu, qv). For each query find 2-path p from qu to qv with maximal profit Pr(p).

Input

The first line contains two integers n and q (2 ≤ n ≤ 3 ⋅ 10^5, 1 ≤ q ≤ 4 ⋅ 10^5) — the number of vertices in the tree and the number of queries.

The second line contains n space-separated integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ 10^9) — the values of the vertices.

Next n - 1 lines contain descriptions of edges: each line contains three space separated integers u_i, v_i and w_i (1 ≤ u_i, v_i ≤ n, u_i ≠ v_i, 1 ≤ w_i ≤ 10^9) — there is edge \\{u_i, v_i\} with weight w_i in the tree.

Next q lines contain queries (one per line). Each query contains two integers qu_i and qv_i (1 ≤ qu_i, qv_i ≤ n) — endpoints of the 2-path you need to find.

Output

For each query print one integer per line — maximal profit Pr(p) of the some 2-path p with the corresponding endpoints.

Example

Input

7 6
6 5 5 3 2 1 2
1 2 2
2 3 2
2 4 1
4 5 1
6 4 2
7 3 25
1 1
4 4
5 6
6 4
3 4
3 7


Output

9
9
9
8
12
-14

Note

Explanation of queries: 

  1. (1, 1) — one of the optimal 2-paths is the following: 1 → 2 → 4 → 5 → 4 → 2 → 3 → 2 → 1. Pr(p) = (a_1 + a_2 + a_3 + a_4 + a_5) - (2 ⋅ w(1,2) + 2 ⋅ w(2,3) + 2 ⋅ w(2,4) + 2 ⋅ w(4,5)) = 21 - 2 ⋅ 12 = 9. 
  2. (4, 4): 4 → 2 → 1 → 2 → 3 → 2 → 4. Pr(p) = (a_1 + a_2 + a_3 + a_4) - 2 ⋅ (w(1,2) + w(2,3) + w(2,4)) = 19 - 2 ⋅ 10 = 9. 
  3. (5, 6): 5 → 4 → 2 → 3 → 2 → 1 → 2 → 4 → 6. 
  4. (6, 4): 6 → 4 → 2 → 1 → 2 → 3 → 2 → 4. 
  5. (3, 4): 3 → 2 → 1 → 2 → 4. 
  6. (3, 7): 3 → 2 → 1 → 2 → 4 → 5 → 4 → 2 → 3 → 7. 

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
struct edge {
  int v = 0;
  long long cost = 0;
  edge(int v_ = 0, int cost_ = 0) {
    v = v_;
    cost = cost_;
  }
};
vector<edge> adj[(int)(3e5 + 10)];
int n, q, p[20][(int)(3e5 + 10)], lev[(int)(3e5 + 10)];
long long ver[(int)(3e5 + 10)], dp_down[(int)(3e5 + 10)],
    dp_up[(int)(3e5 + 10)];
long long dp[20][(int)(3e5 + 10)], cost[(int)(3e5 + 10)];
inline int lca(int v, int u) {
  for (int i = 20 - 1; ~i; i--)
    if (lev[p[i][u]] >= lev[v]) u = p[i][u];
  if (v == u) return v;
  for (int i = 20 - 1; ~i; i--)
    if (p[i][v] != p[i][u]) {
      v = p[i][v];
      u = p[i][u];
    }
  return p[0][v];
}
inline long long get(int &v, int l) {
  long long res = dp_down[v];
  for (int i = 0; i < 20; i++)
    if (l & (1 << i)) {
      res += dp[i][v];
      v = p[i][v];
    }
  return res;
}
void dfs_down(int v, int par = 0) {
  dp_down[v] = ver[v];
  p[0][v] = par;
  lev[v] = lev[par] + 1;
  for (auto e : adj[v])
    if (par ^ e.v) {
      cost[e.v] = e.cost;
      dfs_down(e.v, v);
      if ((dp_down[e.v] - 2 * e.cost) > 0)
        dp_down[v] += dp_down[e.v] - 2 * e.cost;
    }
}
void dfs_up(int v, int par = 0, long long up = 0) {
  dp_up[v] = up + ver[v];
  long long local =
      max(0ll, dp_down[v] - ver[v]) + max(0ll, dp_up[v] - ver[v]) + ver[v];
  for (auto e : adj[v])
    if (par ^ e.v)
      dfs_up(
          e.v, v,
          max(0ll, local - max(0ll, dp_down[e.v] - 2 * e.cost) - 2 * e.cost));
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> q;
  for (int i = 1; i <= n; i++) cin >> ver[i];
  for (int i = 1; i < n; i++) {
    int u, v, c;
    cin >> u >> v >> c;
    adj[v].push_back(edge(u, c));
    adj[u].push_back(edge(v, c));
  }
  dfs_down(1);
  dfs_up(1);
  for (int i = 2; i <= n; i++) {
    dp[0][i] = dp_down[p[0][i]] - cost[i] - max(0ll, dp_down[i] - 2 * cost[i]);
  }
  for (int i = 1; i < 20; i++) {
    for (int v = 1, papa = p[i - 1][1]; v <= n; v++, papa = p[i - 1][v]) {
      p[i][v] = p[i - 1][papa];
      if (lev[v] <= (1 << i)) continue;
      dp[i][v] = dp[i - 1][v] + dp[i - 1][papa];
    }
  }
  while (q--) {
    int v, u;
    cin >> v >> u;
    if (lev[v] > lev[u]) swap(v, u);
    int LCA = lca(v, u);
    if (LCA == v) {
      cout << get(u, lev[u] - lev[v]) + max(0ll, dp_up[v] - ver[v]) << '\n';
      continue;
    }
    long long res =
        get(v, lev[v] - lev[LCA] - 1) + get(u, lev[u] - lev[LCA] - 1);
    res += dp_up[LCA] + dp_down[LCA] - ver[LCA] - cost[v] - cost[u];
    res -= max(0ll, (dp_down[v] - 2 * cost[v])) +
           max(0ll, (dp_down[u] - 2 * cost[u]));
    cout << res << '\n';
  }
  return 0;
}

```