//应当前后两边SPFA求出各点在连接起点,连接终点的路上的最小权值和最大权值,再用两者相减。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,tt=0,ta=0,ans=0;
int w[100001],team[1000001],exist[500001],maxx[100001],minn[100001];//双SPFA。
struct re//存两个相反的图。
{
int w,t,next,head;
}e[500001],e2[500001];
void build(int x,int y)
{
++ta;
e[ta].t=y;
e[ta].next=e[x].head;
e[x].head=ta;
e2[ta].t=x;
e2[ta].next=e2[y].head;
e2[y].head=ta;
}
int main()
{
memset(minn,0x7fffffff/3,sizeof(minn));
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>w[i];
}
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
if(c==1)
build(a,b);
else
{
build(a,b);build(b,a);
}
}
int head=0,tail=1;team[1]=1;minn[1]=w[1];
while(head<tail)//第一遍求个各点在起点到这个点路径中的最小值
{
head++;int u=team[head];exist[u]=0;
for(int i=e[u].head;i;i=e[i].next)
{
if(minn[e[i].t]<min(minn[u],w[e[i].t]))
{
minn[e[i].t]=min(minn[u],w[e[i].t]);
if(!exist[e[i].t])
{
team[++tail]=e[i].t;
exist[e[i].t]=1;
}
}
}
}
memset(team,0,sizeof(team));memset(exist,0,sizeof(exist));maxx[n]=w[n];
int headw=0,tailw=1;team[1]=n;
while(headw<tailw)//第二遍求最大值
{
headw++;int uw=team[headw];exist[uw]=0;
for(int i=e2[uw].head;i;i=e2[i].next)
{
if(maxx[e2[i].t]<max(maxx[uw],w[e[i].t]))
{
maxx[e2[i].t]=max(maxx[uw],w[e[i].t]);
if(!exist[e2[i].t])
{
team[++tailw]=e2[i].t;
exist[e2[i].t]=1;
}
}
}
}
for(int i=1;i<=n;i++)
{
ans=max(ans,maxx[i]-minn[i]);
}
cout<<ans;
return 0;
}