int f[MAXN][MAXN], g[MAXN][MAXN]; bool visit[2][MAXN][MAXN]= {false}; structnode { int val, x, y; node (int val = 0, int x = 0, int y = 0) : val (val), x (x), y (y) {} } ; node maxf[MAXN], maxg[MAXN]; voidgetm(node& a, node b){ if (b.val < a.val) a = b; } voidworkf(int j){ maxf[j] = node (INF, 0, 0); for (int i = 1; i <= N; i ++) if (! visit[0][i][j]) getm (maxf[j], node (f[i][j], i, j)); } voidworkg(int j){ maxg[j] = node (INF, 0, 0); for (int i = 1; i <= N; i ++) if (! visit[1][i][j]) getm (maxg[j], node (g[i][j], i, j)); }
inlineintgetnum(){ int num = 0; char ch = getchar (); while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return num; }
intmain(){ memset (d, INF, sizeof (d)); memset (f, INF, sizeof (f)); memset (g, INF, sizeof (g)); N = getnum (), M = getnum (); for (int i = 1; i <= N; i ++) { a[i] = getnum (); d[i][i] = a[i]; } for (int i = 1; i <= M; i ++) { int u = getnum (), v = getnum (); d[u][v] = a[u] + a[v]; } for (int k = 1; k <= N; k ++) for (int i = 1; i <= N; i ++) for (int j = 1; j <= N; j ++) d[i][j] = min (d[i][j], d[i][k] + d[k][j] - a[k]); if (d[1][N] >= INF || d[N][1] >= INF) { puts ("-1"); return0; } f[1][1] = a[1]; for (int i = 1; i <= N; i ++) workf (i), workg (i); while (true) { node mf, mg; mf = mg = node (INF, 0, 0); for (int i = 1; i <= N; i ++) getm (mf, maxf[i]), getm (mg, maxg[i]); int type = mf.val <= mg.val ? 0 : 1; getm (mf, mg); if (mf.val >= INF) break; int x = mf.x, y = mf.y; if (type) { visit[1][x][y] = true; for (int k = 1; k <= N; k ++) if (k != y) f[k][x] = min (f[k][x], g[x][y] + d[x][k] + d[k][y] - a[x] - a[y] - a[k]); workf (x), workg (y); } else { visit[0][x][y] = true; for (int k = 1; k <= N; k ++) g[k][y] = min (g[k][y], f[x][y] + d[x][k] - a[x]); workf (y), workg (y); } } cout << f[N][N] << endl;