#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxx = 500003;
queue<int>q;
int n,m,price[maxx],head[maxx][3],minn[maxx],maxn[maxx],u,v,z;
int num_edge,vis[maxx],ans;
struct Edge{
int pre,to;
}edge[maxx];
void build_edge(int u,int v) {
edge[++num_edge].pre = head[u][1];
edge[num_edge].to = v;
head[u][1] = num_edge;
edge[++num_edge].pre = head[v][2];
edge[num_edge].to = u;
head[v][2] = num_edge;
}
void init() {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) {
scanf("%d",&price[i]);
minn[i] = 105;
}
for(int i=1; i<=m; i++) {
scanf("%d%d%d",&u,&v,&z);
build_edge(u,v);
if(z == 2) build_edge(v,u);
}
}
void min_spfa() {
q.push(1);
vis[1] = 1;
minn[1] = price[1];
while(!q.empty()) {
int x=q.front();
q.pop();
vis[x] = 0;
for(int i=head[x][1];i;i=edge[i].pre) {
int to = edge[i].to;
if(minn[to] > minn[x] ||minn[to] > price[to]) {
minn[to] = min(minn[x],price[to]);
if(!vis[to]) {
q.push(to);
vis[to] = 1;
}
}
}
}
}
void max_spfa() {
q.push(n);
vis[n] = 1;
maxn[n] = price[n];
ans = max(ans,maxn[n]-minn[n]);
while(!q.empty()) {
int x=q.front();
q.pop();
vis[x] = 0;
for(int i=head[x][2]; i; i=edge[i].pre) {
int to = edge[i].to;
if(maxn[to] < maxn[x] || maxn[to] < price[to]) {
maxn[to] = max(maxn[x],price[to]);
ans=max(ans,maxn[to]-minn[to]);
if(!vis[to]) {
q.push(to);
vis[to] = 1;
}
}
}
}
}
int main() {
init();
min_spfa();
memset(vis,0,sizeof(vis));
max_spfa();
printf("%d\n",ans);
return 0;
}