http://codeforces.com/problemset/problem/115/E
//dp[i]表示 [i...i]最多能赚多少钱
//dp[i+1]=max(dp[i],dp[k]-sum(cost[k..i])+sum(profit[k...i])) 1<=k<i;
//两个转移分别是1.不修路,2.把修[k...i]能赚得钱
//线段树优化
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) ((x<<1)|1)
typedef __int64 lld;
const int maxn=200005;
int cost[maxn];
struct Seg{
int l,r;
lld flag;
lld max;
}tree[maxn*4];
void build(int l,int r,int k)
{
tree[k].l=l;
tree[k].r=r;
tree[k].max=0;
tree[k].flag=0;
if(l==r) return ;
int mid=(l+r)>>1;
build(l,mid,LL(k));
build(mid+1,r,RR(k));
}
lld Max(lld a,lld b){
if(a<b)return b;
return a;
}
void push_down(int k)
{
if(tree[k].flag)
{
tree[RR(k)].max+=tree[k].flag;
tree[LL(k)].max+=tree[k].flag;
tree[RR(k)].flag+=tree[k].flag;
tree[LL(k)].flag+=tree[k].flag;
tree[k].flag=0;
}
}
void push_up(int k)
{
tree[k].max=Max(tree[LL(k)].max,tree[RR(k)].max);
}
void update(int l,int r,int k,lld v)
{
if(l<=tree[k].l && tree[k].r<=r)
{
tree[k].flag+=v;
tree[k].max+=v;
return;
}
push_down(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(l<=mid) update(l,r,LL(k),v);
if(r> mid) update(l,r,RR(k),v);
push_up(k);
}
struct node {
int x,y;
lld p;
bool operator < (const node &t ) const {
return y<t.y;
}
}r[maxn];
lld dp[maxn];
int main()
{
int n,m;
int i,j,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&cost[i]);
for(i=0;i<m;i++)
scanf("%d%d%I64d",&r[i].x,&r[i].y,&r[i].p);
sort(r,r+m);
memset(dp,0,sizeof(dp));
build(0,n,1);
for(i=1,j=0;i<=n;i++)
{
update(0,i-1,1,-cost[i]);
while(j<m && r[j].y<=i)
{
update(0,r[j].x-1,1,r[j].p);
j++;
}
dp[i]=Max(dp[i-1],tree[1].max);
update(i,i,1,dp[i]);
}
printf("%I64d\n",dp[n]);
}
return 0;
}