//题意:给出有向图,有环(SCC),每个节点有一个 商品值 ,小明想从1点走向n点,同时想要进行一次贸易,即从路线上某个点买入商品, 又在某个节点卖出, 询问最大收益是多少(如果收益为负数那么输出0)
//思路:有环第一时间想到tarjan缩点,重建一幅无环有向图
// 因为我想取得最大收益,所以在到达一个点时,我应该用路径上的最小价进货,同时看在这点卖出是否能取得最大值,是一个dp问题(用前点更新后点)
// 注释内是用的dfs序跑dp,但是会T掉几个点,具体的情况实在无法想象出来
// 所以为了保险起见,跑dp这种需要前提条件来更新后面条件的有序结构,要使用拓扑序
// 另外缩点会有重边问题,本题无影响,但是其他题要视具体情况考虑
//
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int> mp[N], mp2[2 * N];
int n, m, wt[N];
int dfn[N], low[N], ins[N], bel[N], idx, cnt;//dfn序,low值,是否存在,哪个强联通分量(缩点用)
stack<int> stk;
int dp[N];
map<pair<int, int>, bool> ct;
struct point {
int in, out;
}fmp[2 * N];
void dfs(int u) {
dfn[u] = low[u] = ++idx;
ins[u] = true;
stk.push(u);
for (auto v : mp[u]) {
if (!dfn[v]) dfs(v);
if (ins[v]) low[u] = min(low[u], low[v]);
}
if (dfn[u] == low[u]) {
++cnt;
int maxn = -1e9, minn = 1e9;
while (true) {
int v = stk.top();
maxn = max(maxn, wt[v]);
minn = min(minn, wt[v]);
ins[v] = false;
bel[v] = cnt;
stk.pop();
if (u == v) break;
}
fmp[cnt].in = minn;
fmp[cnt].out = maxn;
}
}
/*void dfs2(int x) {
for (auto y : mp2[x]) {
if (fmp[y].in > fmp[x].in) fmp[y].in = fmp[x].in;
dp[y] = max(dp[y], max(dp[x], fmp[y].out - fmp[y].in));
dfs2(y);
}
}*/
int rd[2 * N];
void solve() {
queue<int> st;
st.push(bel[1]);
while (!st.empty()) {
int x = st.front();
st.pop();
for (auto y : mp2[x]) {
if (fmp[y].in > fmp[x].in) fmp[y].in = fmp[x].in;
dp[y] = max(dp[y], max(dp[x], fmp[y].out - fmp[y].in));
rd[y]--;
if (rd[y] == 0) st.push(y);
}
}
}
int main() {
cin >> n >> m;
cnt = n;
for (int i = 1; i <= n; i++) cin >> wt[i];
for (int i = 1; i <= m; i++) {
int a, b, od; cin >> a >> b >> od;
mp[a].push_back(b);
if (od == 2) mp[b].push_back(a);
}
dfs(1);
for (int i = 1; i <= n; i++) {
for (auto x : mp[i]) {
if (bel[x] == bel[i]) continue;
if (ct[{bel[x], bel[i]}] || ct[{bel[i], bel[x]}]) continue;
ct[{bel[x], bel[i]}] = ct[{bel[i], bel[x]}] = true;
rd[bel[x]]++;
mp2[bel[i]].push_back(bel[x]);
}
}
//dfs2(bel[1]);
solve();
cout << dp[bel[n]];
return 0;
}