#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
//#pragma GCC target("avx,avx2,fma")
#define m_p make_pair
#define f first
#define s second
#define vec vector
#define sz(x) (int)x.size()
#define pw(x) (1LL<<x)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define fast_io ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
#define pb push_back

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef unsigned long long ull;

template<class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
auto rnd=bind(uniform_int_distribution<ll>(1,1e18),mt19937(time(0)));
template <class T> bool umin(T &a,const T &b){return (a>b?a=b,1:0);}
template <class T> bool umax(T &a,const T &b){return (a<b?a=b,1:0);}
const ll inf=1e18;
//const int N=1<<16;

signed main(){
    fast_io;
    int n,m;
    cin>>n>>m;
    vec<ll>a(n);
    for(auto &z : a)
        cin>>z;
    vec<ll>mn=a;
    ll mx=-inf;
    vec<vec<int>>g(n,vec<int>());
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        g[b-1].pb(a-1);
    }
    for(int i=0;i<n;i++){
        for(auto &z : g[i]){
            umax(mx,a[i]-mn[z]);
            umin(mn[i],mn[z]);
        }
    }
    cout<<mx;
    return 0;
}
/*
qertwy
3
6 3
*/

#include<bits/stdc++.h>
using namespace std;

//-std=c++11
// #define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

#define LL long long
#define FI ios_base::sync_with_stdio(false); cin.tie(NULL);
#define PREC cout << setprecision(10) << fixed;

#define int long long

const int MOD = 1e9 + 7;
const int INF = 1e9 + 9;
const int MX = 1e5 + 5;

int n;
int inp[8];
int m;
int l[MX], v[MX];

int sz;
set<int> allV;
map<int, int> mp;

struct SegTree {
    vector<int> tree;
    int DEFAULT;

    void init(int n) {
        tree.resize(4*n);
        //depends on operation
    	DEFAULT = 0;
    }

    int combine(int x, int y) {
		return max(x, y);
    }

    void update(int node, int st, int en, int id, int val) {
        if(id < st || id > en) return;
        if(st == en && st == id) {
            tree[node] = max(tree[node], val);
            return;
        }
        int mid = (st + en)/2;
        update(2*node, st, mid, id, val);
        update(2*node + 1, mid+1, en, id, val);
        tree[node] = combine(tree[2*node], tree[2*node + 1]);
    }

    int query(int node, int st, int en, int i, int j) {
        if(i > en || j < st) {
            return DEFAULT;
        }
        if(i <= st && en <= j) {
            return tree[node];
        }
        int mid = (st + en)/2;
        int left = query(2*node, st, mid, i, j);
        int right = query(2*node+1, mid+1, en, i, j);
        return combine(left, right);   
    }
};

SegTree seg;

int calc(vector<int> x) {
	vector<int> pla(n);
	pla[0] = 0;
	for(int i=1;i<n;i++) {
		int sum = inp[x[i]];
		int j = i-1;
		int minD = 0; 
		while(j >= 0) {
			sum += inp[x[j]];

			auto it = allV.lower_bound(sum);
			if(it == allV.begin()) {
				j--;
				continue;
			}

			it--;
			int id = mp[*it];
			int maxL = seg.query(1, 0, sz - 1, 0, id);

			maxL = maxL - (pla[i-1] - pla[j]);  
			
			minD = max(minD, maxL);
			j--;
		}
		pla[i] = pla[i-1] + minD;
	}

	int totD = pla[n-1] - pla[0];
	return totD;
}

#undef int
int main() {
	#define int long long
	cin >> n >> m;

	for(int i=0;i<n;i++) {
		cin >> inp[i];
	} 

	for(int i=0;i<m;i++) {
		cin >> l[i] >> v[i];
		allV.insert(v[i]);
	}

	//Base check
	for(int i=0;i<n;i++) {
		for(int j=0;j<m;j++) {
			if(inp[i] > v[j]) {
				cout << -1 << endl;
				return 0;
			}
		}
	}

	sz = 0;
	for(auto it : allV) {
		mp[it] = sz;
		sz++;
	}
	seg.init(sz);
	for(int i=0;i<m;i++) {
		int id = mp[v[i]];
		seg.update(1, 0, sz-1, id, l[i]);
	}

	int ans = INF;
	vector<int> x;
	for(int i=0;i<n;i++) x.push_back(i);
	ans = min(ans, calc(x));
	while(next_permutation(x.begin(),x.end())) {
		ans = min(ans, calc(x));
	}

	cout << ans << endl;
	
	return 0;
}