#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define pb emplace_back
const int mod = 1e9 + 7;
const int nmax = 2e5 + 5;
int n, m, a[nmax], suf[nmax];
int d1[nmax], dn[nmax];
vector<int> adj[nmax];
void sub1() { // full
for (int i = n; i >= 1; --i) suf[i] = max(suf[i + 1], a[i]);
int cur = 0, ans = 0;
for (int i = 1; i < n; ++i) {
while (cur < a[i + 1] - 1) {
++cur;
++ans;
}
if (cur < suf[i + 1]) ++cur;
else if (cur > suf[i + 1]) --cur;
++ans;
}
cout << ans + cur;
}
struct node {
int dist, idx, h;
node(int _dist, int _idx, int _h) : dist(_dist), idx(_idx), h(_h) {}
bool operator < (const node &other) const {
return dist < other.dist;
}
bool operator > (const node &other) const {
return dist > other.dist;
}
};
void dijkstra(int s, int d[]) {
priority_queue<node, vector<node>, greater<node>> pq;
pq.push(node(0, s, 0));
d[s] = 0;
int dis, u, cur;
while (!pq.empty()) {
node tp = pq.top();
dis = tp.dist;
u = tp.idx;
cur = tp.h;
pq.pop();
if (dis > d[u]) continue;
for (int v : adj[u]) {
int newdist = dis + 1 + max(0, a[v] - cur - 1);
if (newdist < d[v]) {
d[v] = newdist;
pq.push(node(newdist, v, max(cur + 1, a[v])));
}
}
}
}
void sub4() {
if (n == 2) {
cout << 1;
return;
}
fill(d1 + 1, d1 + 1 + n, 1000000000);
dijkstra(1, d1);
// for (int i = 1; i <= n; ++i) cout << d1[i].fi << ' ' << d1[i].se << '\n';
fill(dn + 1, dn + 1 + n, 1000000000);
dijkstra(n, dn);
// for (int i = 1; i <= n; ++i) cout << dn[i].fi << ' ' << dn[i].se << '\n';
int ans = INT_MAX;
for (int i = 2; i < n; ++i) {
ans = min(ans, d1[i] + dn[i]);
}
cout << ans;
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
if (fopen("test.inp", "r")) {
freopen("test.inp", "r", stdin);
freopen("test.out", "w", stdout);
}
cin >> n >> m;
bool checksub1 = (m == n - 1);
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= m; ++i) {
int u, v; cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
if (u != i || v != i + 1) checksub1 = 0;
}
sub4();
return 0;
}