#ifdef LOCAL #define _GLIBCXX_DEBUG #endif // LOCAL #pragma GCC optimize("O3") #include using namespace std; using ll = long long; struct dsu { int n; vector par; vector rk; dsu (const int n_) { n = n_; par.resize(n); iota(par.begin(), par.end(), 0); rk.assign(n, 1); } int group (int x) { if (par[x] == x) return x; return par[x] = group(par[x]); } bool merge (int x, int y) { x = group(x); y = group(y); if (x == y) return false; if (rk[x] > rk[y]) swap(x, y); par[x] = y; rk[y] += rk[x]; return true; } }; void solve_test (istream &cin, ostream &cout) { int n, m; cin >> n >> m; vector h(n); for (auto &it : h) cin >> it; vector> g(n); for (int i = 0; i < m; i++) { int x, y; cin >> x >> y; --x, --y; g[x].push_back(y); g[y].push_back(x); } vector> sorted_h(n); for (int i = 0; i < n; i++) sorted_h[i] = {h[i], i}; sort(sorted_h.begin(), sorted_h.end()); int ans = numeric_limits::max(); for (int i = 0; i < int(sorted_h.size()); i++) { const int maxh = sorted_h[i].first; if (maxh < max(h[0], h[1])) continue; vector alive(n); dsu dsu(n); int cur = numeric_limits::max(); assert(dsu.group(0) != dsu.group(1)); for (int j = i; j >= 0; j--) { const int num = sorted_h[j].second; alive[num] = true; for (const int to : g[num]) if (alive[to]) dsu.merge(num, to); if (dsu.group(0) == dsu.group(1)) { cur = maxh - sorted_h[j].first; break; } } ans = min(ans, cur); } cout << ans << endl; } void solve (istream &cin, ostream &cout) { solve_test(cin, cout); } int main() { #ifdef LOCAL ifstream in("input.txt"); ofstream out("output.txt"); solve(in, out); #else solve_test(cin, cout); #endif }