Problem:
To be Connected, or not to be, that is the Question
An undirected graph is given, each of its nodes associated with a positive integer value. Given
a
threshold
, nodes of the graph are divided into two groups: one consisting of the nodes with
values less than or equal to the threshold, and the other consisting of the rest of the nodes.
Now, consider a subgraph of the original graph obtained by removing all the edges connecting
two nodes belonging to different groups. When both of the node groups are non-empty, the
resultant subgraph is disconnected, whether or not the given graph is connected.
Then a number of new edges are added to the subgraph to make it connected, but these edges
must connect nodes in different groups, and each node can be incident with at most one new
edge. The threshold is called
feasible
if neither of the groups is empty and the subgraph can be made connected by adding some new edges.
Your task is to find the minimum feasible threshold.
Input
The input consists of a single test case of the following format.
$n$ $m$
$l_1$ ... $l_n$
$x_1$ $y_1$
...
$x_m$ $y_m$
The first line contains two integers $n$ ($2 \leq n \leq 10^5$) and $m$ ($0 \leq m \leq $ min($10^5, \frac{n(n-1)}{2}$)), the numbers of the nodes and the edges, respectively, of the graph. Nodes are numbered 1 through $n$. The second line contains $n$ integers $l_i$ ($1 \leq l_i \leq 10^9$), meaning that the value associated with the node $i$ is $l_i$. Each of the following $m$ lines contains two integers $x_j$ and $y_j$ ($1 \leq x_j < y_j \leq n$), meaning that an edge connects the nodes $x_j$ and $y_j$ . At most one edge exists between any two nodes.
Output
Output the minimum feasible threshold value. Output -1 if no threshold values are feasible.
Sample Input 1
4 2
10 20 30 40
1 2
3 4
Sample Output 1
20
Sample Input 2
2 1
3 5
1 2
Sample Output 2
3
Sample Input 3
3 0
9 2 8
Sample Output 3
-1
Sample Input 4
4 6
5 5 5 5
1 2
1 3
1 4
2 3
2 4
3 4
Sample Output 4
-1
Sample Input 5
7 6
3 1 4 1 5 9 2
2 3
3 5
5 6
1 4
1 7
4 7
Sample Output 5
2

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < (ll)n; ++i)
constexpr ll INF = 9009009009009009009LL;

struct UnionFind {
    vector<int> par, siz;
    UnionFind(int n) : par(n, -1) , siz(n, 1) {}
    int root(int x){
        if (par[x] == -1) return x;
        else return par[x] = root(par[x]);
    }
    bool issame(int x, int y){
        return root(x) == root(y);
    }
    bool unite(int x, int y){
        x = root(x), y = root(y);
        if (x == y) return false;
        if(siz[x] < siz[y]) swap(x, y);
        par[y] = x;
        siz[x] += siz[y];
        return true;
    }
    
    int size(int x){
        return siz[root(x)];
    }
};

int main() {
    ll n, m; cin >> n >> m;
    vector<ll> l(n);
    rep(i, n) cin >> l[i];

    vector<vector<ll>> smallg(n), bigg(n);
    rep(i, m) {
        ll x, y; cin >> x >> y;
        --x, --y;
        
        if (l[x] <= l[y]) {
            smallg[y].push_back(x);
            bigg[x].push_back(y);
        }
        if (l[x] >= l[y]) {
            smallg[x].push_back(y);
            bigg[y].push_back(x);
        }
    }

    vector<pair<ll, ll>> vs;
    rep(i, n) {
        vs.push_back({l[i], i});
    }
    sort(vs.begin(), vs.end());

    map<ll, pair<ll, ll>> mnsum;
    mnsum[0] = {0, 0};
    UnionFind uf(n);
    rep(i, n) {
        ll nunites = mnsum.rbegin()->second.first;
        ll ncnt = mnsum.rbegin()->second.second;
        
        ll now = vs[i].first;
        while (i < n && vs[i].first == now) {
            ncnt++;
            for (ll to : smallg[vs[i].second]) {
                if (uf.unite(vs[i].second, to)) {
                    nunites++;
                }
            }

            i++;
        }
        i--;

        mnsum[now] = {nunites, ncnt};
    }

    sort(vs.rbegin(), vs.rend());
    map<ll, pair<ll, ll>> mxsum;
    mxsum[vs[0].first] = {0, 0};
    uf = UnionFind(n);
    rep(i, n) {
        ll nunites = mxsum.begin()->second.first;
        ll ncnt = mxsum.begin()->second.second;
        
        ll now = vs[i].first;
        while (i < n && vs[i].first == now) {
            ncnt++;
            for (ll to : bigg[vs[i].second]) {
                if (uf.unite(vs[i].second, to)) {
                    nunites++;
                }
            }

            i++;
        }
        ll next = 0;
        if (i != n) next = vs[i].first; 
        i--;

        mxsum[next] = {nunites, ncnt};
    }

    // for (auto [t, val] : mnsum) {
    //     cout << t << " : " << val.first << " " << val.second << endl;
    // }
    // cout << "-------------" << endl;
    // for (auto [t, val] : mxsum) {
    //     cout << t << " : " << val.first << " " << val.second << endl;
    // }

    for (auto [threshold, val] : mnsum) {
        pair<ll, ll> mxval = mxsum[threshold];
        ll components = val.second - val.first;
        components += mxval.second - mxval.first;
        ll mnv = min(val.second, mxval.second);

        if (mnv == 0) continue;

        if (components - mnv <= 1) {
            cout << threshold << endl;
            return 0;
        }
    }

    cout << -1 << endl;

    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 27764
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) begin(x), end(x)
#define rep(i, l, r) for (int i = (l), i##end = (r); i <= i##end; ++i)
#define per(i, l, r) for (int i = (l), i##end = (r); i >= i##end; --i)
#ifdef memset0
#define log(...) fprintf(stderr, __VA_ARGS__)
#else
#define log(...) (void(0))
#define endl '\n'
#endif
using namespace std;
using ll = long long;
using lf = long double;
using lll = __int128;
using ull = unsigned long long;

const int N = 200011;
struct DSU {
  int fa[N];
  void init(int n) {
    for (int i = 1; i <= n; ++i) fa[i] = i;
  }
  int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
  }
  bool uni(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return 0;
    return fa[x] = y, 1;
  }
} dsu;
int num[N], edges[N], fx[N], diff;
int place(int val) { return lower_bound(fx + 1, fx + diff + 1, val) - fx; }
int a[N];
vector<int> seq[N], g[N];
int main() {
#ifdef memset0
  freopen("G.in", "r", stdin);
#endif
  cin.tie(0)->sync_with_stdio(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i], fx[++diff] = a[i];
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    g[u].emplace_back(v), g[v].emplace_back(u);
  }
  sort(fx + 1, fx + diff + 1), diff = unique(fx + 1, fx + diff + 1) - fx - 1;
  for (int i = 1; i <= n; ++i) a[i] = place(a[i]), seq[a[i]].emplace_back(i);
  dsu.init(n);
  for (int x = diff; x; --x) {
    num[x] = num[x + 1] + int(seq[x].size());
    edges[x] = edges[x + 1];
    for (auto u : seq[x]) {
      for (auto v : g[u])
        if (a[v] >= x) edges[x] += dsu.uni(u, v);
    }
  }
  dsu.init(n);
  int now = 0, eg = 0;
  for (int x = 1; x <= diff; ++x) {
    now += seq[x].size();
    for (auto u : seq[x])
      for (auto v : g[u])
        if (a[v] <= x) eg += dsu.uni(u, v);
    if (now && now < n && min(now, n - now) >= n - 1 - eg - edges[x + 1]) {
      cout << fx[x] << '\n';
      return 0;
    }
  }
  cout << "-1\n";
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 22816
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) begin(x), end(x)
#define rep(i, l, r) for (int i = (l), i##end = (r); i <= i##end; ++i)
#define per(i, l, r) for (int i = (l), i##end = (r); i >= i##end; --i)
#ifdef memset0
#define log(...) fprintf(stderr, __VA_ARGS__)
#else
#define log(...) (void(0))
#define endl '\n'
#endif
using namespace std;
using ll = long long;
using lf = long double;
using lll = __int128;
using ull = unsigned long long;

const int N = 200011;
struct DSU {
  int fa[N];
  void init(int n) {
    for (int i = 1; i <= n; ++i) fa[i] = i;
  }
  int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
  }
  bool uni(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return 0;
    return fa[x] = y, 1;
  }
} dsu;
int num[N], edges[N], fx[N], diff;
int place(int val) { return lower_bound(fx + 1, fx + diff + 1, val) - fx; }
int a[N];
vector<int> seq[N], g[N];
int main() {
#ifdef memset0
  freopen("G.in", "r", stdin);
#endif
  cin.tie(0)->sync_with_stdio(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i], fx[++diff] = a[i];
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    g[u].emplace_back(v), g[v].emplace_back(u);
  }
  sort(fx + 1, fx + diff + 1), diff = unique(fx + 1, fx + diff + 1) - fx - 1;
  for (int i = 1; i <= n; ++i) a[i] = place(a[i]), seq[a[i]].emplace_back(i);
  dsu.init(n);
  for (int x = diff; x; --x) {
    num[x] = num[x + 1] + int(seq[x].size());
    edges[x] = edges[x + 1];
    for (auto u : seq[x]) {
      for (auto v : g[u])
        if (a[v] >= x) edges[x] += dsu.uni(u, v);
    }
  }
  dsu.init(n);
  int now = 0, eg = 0;
  for (int x = 1; x <= diff; ++x) {
    now += seq[x].size();
    for (auto u : seq[x])
      for (auto v : g[u])
        if (a[v] <= x) eg += dsu.uni(u, v);
    if (now && now < n && min(now, n - now) >= n - 1 - eg - edges[x + 1]) {
      cout << fx[x] << '\n';
      return 0;
    }
  }
  cout << "-1\n";
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 22744
final_rank: 6

code_snippet: // AOJ #1417 To be Connected or not to be that is the Question
// 2025.4.18

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

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct DSU {
    vector<int> p;
    DSU(int n): p(n,-1) {}
    int f(int x){ return p[x]<0?x:p[x]=f(p[x]); }
    bool u(int a,int b){
        a=f(a); b=f(b);
        if(a==b) return false;
        if(p[a]>p[b]) swap(a,b);
        p[a]+=p[b];
        p[b]=a;
        return true;
    }
};

int main(){
    int n = Cin(), m = Cin();
    vector<ll> a(n);
    for(int i=0;i<n;i++) a[i] = Cin();
    vector<pair<int,int>> e(m);
    for(int i=0;i<m;i++){
        int x = Cin()-1, y = Cin()-1;
        e[i]={x,y};
    }
    vector<ll> w=a;
    sort(w.begin(),w.end());
    w.erase(unique(w.begin(),w.end()),w.end());

    auto feasible = [&](ll t)->bool{
        int L = upper_bound(w.begin(),w.end(),t) - lower_bound(w.begin(),w.end(),-LLONG_MAX);
        int cntL=0, cntH=0;
        vector<char> inL(n,0);
        for(int i=0;i<n;i++){
            if(a[i]<=t){
                inL[i]=1;
                cntL++;
            }
        }
        cntH = n - cntL;
        if(cntL==0 || cntH==0) return false;

        DSU dl(n), dh(n);
        for(auto &pr:e){
            int u=pr.first, v=pr.second;
            if(inL[u] && inL[v]) dl.u(u,v);
            if(!inL[u] && !inL[v]) dh.u(u,v);
        }
        int p=0,q=0;
        vector<char> seen(n,0);
        for(int i=0;i<n;i++){
            if(inL[i]){
                int r=dl.f(i);
                if(!seen[r]) seen[r]=1, p++;
            }
        }
        fill(seen.begin(),seen.end(),0);
        for(int i=0;i<n;i++){
            if(!inL[i]){
                int r=dh.f(i);
                if(!seen[r]) seen[r]=1, q++;
            }
        }
        return min(cntL,cntH) >= (p+q-1);
    };

    int lo=0, hi=(int)w.size()-1, ans=-1;
    while(lo<=hi){
        int md=(lo+hi)/2;
        if(feasible(w[md])){
            ans = md;
            hi = md-1;
        } else lo = md+1;
    }
    Cout(ans==-1? -1 : w[ans]);
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 6456
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 200001;

vector<int> g[N];
int vals[N];
pair<int, int> sortedVals[N];

int dsu[N];
int sz[N];

int getP(int v) {
	if (dsu[v] == v) return v;
	return dsu[v] = getP(dsu[v]);
}

bool merge(int a, int b) {
	int pa = getP(a);
	int pb = getP(b);

	if (pa == pb) return false;

	if (sz[pb] > sz[pa]) swap(pa, pb);

	dsu[pb] = pa;
	sz[pa] += sz[pb];

	return true;
}

signed main() {
	//freopen("./in.txt", "r", stdin);
	int n, m;
	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		sortedVals[i].second = i;
		cin >> sortedVals[i].first;
		vals[i] = sortedVals[i].first;

		dsu[i] = i;
		sz[i] = 1;
	}

	sort(sortedVals + 1, sortedVals + n + 1);

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> a >> b;

		g[a].push_back(b);
		g[b].push_back(a);
	}

	vector<pair<int, int>> moreVals;

	int ind = n;
	int cnt = 0;
	int cntComps = 0;

	while (ind > 0) {
		int curr = sortedVals[ind].first;

		while (ind >= 0 && sortedVals[ind].first == curr) {
			int v = sortedVals[ind].second;
			cnt++;
			cntComps++;

			for (int e : g[v]) {
				if (vals[e] < curr) continue;
				if (merge(e, v)) {
					cntComps--;
				}
			}
			ind--;
		}

		moreVals.emplace_back(cnt, cntComps);
	}

	if (moreVals.size() == 1) {
		cout << "-1\n";
		return 0;
	}

	reverse(moreVals.begin(), moreVals.end());
	moreVals.emplace_back(0, 100);

	for (int i = 1; i <= n; ++i) {
		dsu[i] = i;
		sz[i] = 1;
	}

	cnt = 0;
	cntComps = 0;
	ind = 1;

	int moreInd = 0;

	while (ind <= n) {
		moreInd++;
		int curr = sortedVals[ind].first;

		while (ind <= n && sortedVals[ind].first == curr) {
			int v = sortedVals[ind].second;
			cnt++;
			cntComps++;

			for (int e : g[v]) {
				if (vals[e] > curr) continue;
				if (merge(e, v)) cntComps--;
			}

			ind++;
		}

		int currCnt = min(cnt, moreVals[moreInd].first);

		if (currCnt >= cntComps + moreVals[moreInd].second - 1) {
			cout << curr << "\n";
			return 0;
		}
	}

	cout << "-1\n";
}
accuracy: 1
time_ms: 70
memory_kb: 15488
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 200001;

vector<int> g[N];
int vals[N];
pair<int, int> sortedVals[N];

int dsu[N];
int sz[N];

int getP(int v) {
	if (dsu[v] == v) return v;
	return dsu[v] = getP(dsu[v]);
}

bool merge(int a, int b) {
	int pa = getP(a);
	int pb = getP(b);

	if (pa == pb) return false;

	if (sz[pb] > sz[pa]) swap(pa, pb);

	dsu[pb] = pa;
	sz[pa] += sz[pb];

	return true;
}

signed main() {
	int n, m;
	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		sortedVals[i].second = i;
		cin >> sortedVals[i].first;
		vals[i] = sortedVals[i].first;

		dsu[i] = i;
		sz[i] = 1;
	}

	sort(sortedVals + 1, sortedVals + n + 1);

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> a >> b;

		g[a].push_back(b);
		g[b].push_back(a);
	}

	vector<pair<int, int>> moreVals;

	int ind = n;
	int cnt = 0;
	int cntComps = 0;

	while (ind > 0) {
		auto [curr, v] = sortedVals[ind];

		while (ind >= 0 && sortedVals[ind].first == curr) {
			cnt++;
			cntComps++;

			for (int e : g[v]) {
				if (vals[e] < curr) continue;
				if (merge(e, v)) cntComps--;
			}
			ind--;
		}

		moreVals.emplace_back(cnt, cntComps);
	}

	if (moreVals.size() == 1) {
		cout << "-1\n";
		return 0;
	}

	reverse(moreVals.begin(), moreVals.end());
	moreVals.emplace_back(0, 100);

	for (int i = 1; i <= n; ++i) {
		dsu[i] = i;
		sz[i] = 1;
	}

	cnt = 0;
	cntComps = 0;
	ind = 1;

	int moreInd = 0;

	while (ind <= n) {
		moreInd++;
		auto [curr, v] = sortedVals[ind];

		while (ind <= n && sortedVals[ind].first == curr) {
			cnt++;
			cntComps++;

			for (int e : g[v]) {
				if (vals[e] > curr) continue;
				if (merge(e, v)) cntComps--;
			}

			ind++;
		}

		int currCnt = min(cnt, moreVals[moreInd].first);

		if (currCnt >= cntComps + moreVals[moreInd].second - 1) {
			cout << curr << "\n";
			return 0;
		}
	}

	cout << "-1\n";
}
accuracy: 0.3023255813953488
time_ms: 60
memory_kb: 14868
final_rank: 18

code_snippet: //tekitou hash demo tooru to uresii
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep2(i,s,t) for(int i=s;i<t;i++)

using vi=vector<int>;

struct dsu {
  int n;
  vi par;

  dsu(int n) : n(n), par(n, -1){};

  int find(int v) {
    if(par[v] < 0) return v;
    return par[v] = find(par[v]);
  }

  bool merge(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) return false;
    if(par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  int size(int v) { return -par[find(v)]; }

  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
    
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    int N,M;
    cin>>N>>M;
    vector<array<int,2>> L(N);
    rep(i,N){
        cin>>L[i][0];
        L[i][1]=i;
    }  
    vector<vector<int>> G(N);
    rep(i,M){
        int x,y;
        cin>>x>>y;
        x--;y--;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    sort(L.begin(),L.end());
    vector<int> NM(N);
    rep(i,N)NM[L[i][1]]=i;
    vector<int> C(N,1);
    dsu d(N);
    rep(i,N){
        if(i==0)continue;
        C[i]=C[i-1]+1;
        for(int v:G[L[i][1]]){
            if(NM[v]>i)continue;
            if(!d.same(v,L[i][1])){
                d.merge(v,L[i][1]);
                C[i]--;
            }
        }
    }
    int an=1e9+11;
    dsu d2(N);
    int CP=0;
    for(int i=N-1;i>0;i--){
        CP++;
        for(int v:G[L[i][1]]){
            if(NM[v]<i)continue;
            if(!d2.same(v,L[i][1])){
                d2.merge(v,L[i][1]);
                CP--;
            }
        }
        if(L[i][0]!=L[i-1][0]&&CP+C[i-1]<=min(i,N-i)+1){
            // cout<<i<<" "<<min(i,N-i)<<" "<<CP<<" "<<C[i-1]<<endl;
            an=min(an,L[i-1][0]);
            // cout<<L[i-1][0]<<endl;
        }
    }
    cout<<(an<1e9+10?an:-1)<<endl;
}
accuracy: 1
time_ms: 30
memory_kb: 11324
final_rank: 2

code_snippet: //tekitou hash demo tooru to uresii
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep2(i,s,t) for(int i=s;i<t;i++)

using vi=vector<int>;

struct dsu {
  int n;
  vi par;

  dsu(int n) : n(n), par(n, -1){};

  int find(int v) {
    if(par[v] < 0) return v;
    return par[v] = find(par[v]);
  }

  bool merge(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) return false;
    if(par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  int size(int v) { return -par[find(v)]; }

  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
    
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    int N,M;
    cin>>N>>M;
    vector<array<int,2>> L(N);
    rep(i,N){
        cin>>L[i][0];
        L[i][1]=i;
    }  
    vector<vector<int>> G(N);
    rep(i,M){
        int x,y;
        cin>>x>>y;
        x--;y--;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    sort(L.begin(),L.end());
    vector<int> NM(N);
    rep(i,N)NM[L[i][1]]=i;
    vector<int> C(N,1);
    dsu d(N);
    rep(i,N){
        if(i==0)continue;
        C[i]=C[i-1]+1;
        for(int v:G[i]){
            if(NM[v]>i)continue;
            if(!d.same(v,i)){
                d.merge(v,i);
                C[i]--;
            }
        }
    }
    int an=1e9+11;
    dsu d2(N);
    int CP=0;
    for(int i=N-1;i>0;i--){
        CP++;
        for(int v:G[i]){
            if(NM[v]<i)continue;
            if(!d2.same(v,i)){
                d2.merge(v,i);
                CP--;
            }
        }
        if(L[i][0]!=L[i-1][0]&&CP+C[i-1]<=min(i,N-i)+1)an=min(an,L[i-1][0]);
    }
    cout<<(an<1e9+10?an:-1)<<endl;
}
accuracy: 0.09302325581395349
time_ms: 30
memory_kb: 10728
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

/*
	考察
	閾値以下の頂点数をX,連結成分数をA,閾値より大きい頂点数をY,連結成分数をBとすると
	A+B-1個の辺を張る必要があるので、
	X>=A+B-1,Y>=A+B-1が条件
	A,B,X,Yをそれぞれ計算する
*/

struct DSU{
	vector<int> par, sz;
	int fore;
	DSU(int N){
		par.resize(N);
		sz.resize(N);
		fore = N;
		for(int i = 0; i < N; i++){
			par[i] = i;
			sz[i] = 1;
		}
	}
	int find(int u){
		if(par[u] == u) return u;
		return par[u] = find(par[u]);
	}
	void merge(int u, int v){
		u = find(u), v = find(v);
		if(u == v) return;
		if(sz[u] < sz[v]) swap(u, v);
		sz[u] += sz[v];
		par[v] = u;
		fore--;
	}
};

int main(){
	int N, M;
	cin >> N >> M;
	vector<int> V(N);
	for(int i = 0; i < N; i++) cin >> V[i];
	vector<vector<int>> G(N);
	for(int i = 0; i < M; i++){
		int u, v; cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	auto val = V;
	sort(val.begin(), val.end());
	val.erase(unique(val.begin(), val.end()), val.end());
	for(int i = 0; i < N; i++) V[i] = lower_bound(val.begin(), val.end(), V[i]) - val.begin();

	int L = val.size();
	vector<int> A(L), B(L), X(L), Y(L);
	vector<vector<int>> vs(L);
	for(int i = 0; i < N; i++) vs[V[i]].push_back(i);

	{
		DSU dsu(N);
		int vcnt = 0;
		for(int i = 0; i < L; i++){
			//閾値をiにするとき
			vcnt += vs[i].size();
			for(int v : vs[i]) for(int to : G[v]) if(V[to] <= i) dsu.merge(to, v);
			X[i] = vcnt;
			A[i] = dsu.fore - (N-vcnt);
		}
	}
	{
		DSU dsu(N);
		int vcnt = 0;
		for(int i = L-1; i >= 0; i--){
			//閾値をiにするとき
			Y[i] = vcnt;
			B[i] = dsu.fore - (N-vcnt);
			for(int v : vs[i]) for(int to : G[v]) if(V[to] >= i) dsu.merge(to, v);
			vcnt += vs[i].size();
		}
	}

	for(int i = 0; i < L; i++){
		int a = min(X[i], Y[i]);
		if(a && a >= A[i]+B[i]-1){
			cout << val[i] << endl;
			return 0;
		}
	}

	cout << -1 << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 17372
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

/*
	考察
	閾値以下の頂点数をX,連結成分数をA,閾値より大きい頂点数をY,連結成分数をBとすると
	A+B-1個の辺を張る必要があるので、
	X>=A+B-1,Y>=A+B-1が条件
	A,B,X,Yをそれぞれ計算する
*/

struct DSU{
	vector<int> par, sz;
	int fore;
	DSU(int N){
		par.resize(N);
		sz.resize(N);
		fore = N;
		for(int i = 0; i < N; i++){
			par[i] = i;
			sz[i] = 1;
		}
	}
	int find(int u){
		if(par[u] == u) return u;
		return par[u] = find(par[u]);
	}
	void merge(int u, int v){
		u = find(u), v = find(v);
		if(u == v) return;
		if(sz[u] < sz[v]) swap(u, v);
		sz[u] += sz[v];
		par[v] = u;
		fore--;
	}
};

int main(){
	int N, M;
	cin >> N >> M;
	vector<int> V(N);
	for(int i = 0; i < N; i++) cin >> V[i];
	vector<vector<int>> G(N);
	for(int i = 0; i < M; i++){
		int u, v; cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	auto val = V;
	sort(val.begin(), val.end());
	val.erase(unique(val.begin(), val.end()), val.end());
	for(int i = 0; i < N; i++) V[i] = lower_bound(val.begin(), val.end(), V[i]) - val.begin();

	int L = val.size();
	vector<int> A(L), B(L), X(L), Y(L);
	vector<vector<int>> vs(L);
	for(int i = 0; i < N; i++) vs[V[i]].push_back(i);

	{
		DSU dsu(N);
		int vcnt = 0;
		for(int i = 0; i < L; i++){
			//閾値をiにするとき
			vcnt += vs[i].size();
			for(int v : vs[i]) for(int to : G[v]) if(V[to] <= i) dsu.merge(to, v);
			X[i] = vcnt;
			A[i] = dsu.fore - (N-vcnt);
		}
	}
	{
		DSU dsu(N);
		int vcnt = 0;
		for(int i = L-1; i >= 0; i--){
			//閾値をiにするとき
			Y[i] = vcnt;
			B[i] = dsu.fore - (N-vcnt);
			for(int v : vs[i]) for(int to : G[v]) if(V[to] > i) dsu.merge(to, v);
			vcnt += vs[i].size();
		}
	}

	for(int i = 0; i < L; i++){
		int a = min(X[i], Y[i]);
		if(a && a >= A[i]+B[i]-1){
			cout << val[i] << endl;
			return 0;
		}
	}

	cout << -1 << endl;
}
accuracy: 0.32558139534883723
time_ms: 80
memory_kb: 16972
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

/*
	考察
	閾値以下の頂点数をX,連結成分数をA,閾値より大きい頂点数をY,連結成分数をBとすると
	A+B-1個の辺を張る必要があるので、
	X>=A+B-1,Y>=A+B-1が条件
	二分探索する
*/

struct DSU{
	vector<int> par, sz;
	int fore;
	DSU(int N){
		par.resize(N);
		sz.resize(N);
		for(int i = 0; i < N; i++){
			par[i] = i;
			sz[i] = 1;
		}
	}
	int find(int u){
		if(par[u] == u) return u;
		return par[u] = find(par[u]);
	}
	void merge(int u, int v){
		u = find(u), v = find(v);
		if(u == v) return;
		if(sz[u] < sz[v]) swap(u, v);
		sz[u] += sz[v];
		par[v] = u;
	}
};

int main(){
	int N, M;
	cin >> N >> M;
	vector<int> V(N);
	for(int i = 0; i < N; i++) cin >> V[i];
	vector<pair<int, int>> E(M);
	for(auto&[u, v]: E) cin >> u >> v, --u, --v;

	auto Judge = [&](ll mid)->tuple<bool, bool, int, int>{
		DSU dsu(N);
		for(auto [u, v] : E){
			bool a = V[u] <= mid, b = V[v] <= mid;
			if(a == b) dsu.merge(u, v);
		}
		int a = 0, b = 0, x = 0, y = 0;
		for(int i = 0; i < N; i++){
			if(dsu.par[i] == i && V[i] <= mid) a++;
			else if(dsu.par[i] == i && V[i] > mid) b++;
			if(V[i] <= mid) x++;
			else y++;
		}
		//printf("mid:%lld, a:%d, b:%d, a+b-1:%d, x:%d, y:%d\n", mid,a,b,a+b-1,x,y);
		return {x >= a+b-1, y >= a+b-1, a, b};
	};

	ll lo = *min_element(V.begin(), V.end()) - 1, hi = *max_element(V.begin(), V.end()) - 1;
	while(hi-lo > 1){
		ll mid = (lo+hi) / 2;
		if(get<0>(Judge(mid))) hi = mid;
		else lo = mid;
	}
	auto [fi, se, a, b] = Judge(hi);
	if(se && a && b) cout << hi << endl;
	else cout << -1 << endl;
}
accuracy: 0.9302325581395349
time_ms: 100
memory_kb: 5036
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0 ; i < (n) ; i++)
#define vec vector
#undef long
#define long long long
using ll = long;
#define ALL(a) a.begin(),a.end()

struct UnionFind {
    vec<int> par, rank;
    explicit UnionFind(const int n = 1) { init(n); }

    void init(const int n = 1) {
        par.resize(n);
        rank.resize(n);
        rep(i, n) {
            par[i] = i;
            rank[i] = 0;
        }
    }

    int root(const int x) {
        if (par[x] == x) return x;
        const int r = root(par[x]);
        return par[x] = r;
    }

    bool issame(int x, int y) { return root(x) == root(y); }

    bool merge(int x, int y) {
        x = root(x), y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y);
        if (rank[x] == rank[y]) rank[x]++;
        par[y] = x;
        return true;
    }
};

pair<vec<int>,vec<int> > z(int n, vec<int> &a) {
    auto b = a;
    sort(ALL(b));
    b.erase(unique(ALL(b)), b.end());
    vec<int> r(n);
    rep(i, n) r[i] = lower_bound(ALL(b), a[i]) - b.begin();
    return {b, r};
}

void solve() {
    int n, m;
    cin >> n >> m;
    vec<int> l(n);
    rep(i, n) cin >> l[i];
    vec<vec<int> > g(n);
    rep(i, m) {
        int x, y;
        cin >> x >> y;
        x--, y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    auto [mapping, l2] = z(n, l);
    m = mapping.size();
    vec<vec<int> > dd(m);
    rep(i, n) dd[l2[i]].push_back(i);
    vec<int> a1(m), a2(m);
    int a1x = 0, a2x = 0;
    UnionFind au(n);
    rep(i, m) {
        for (int k: dd[i]) {
            for (int v: g[k]) {
                if (max(l2[v], l2[k]) <= i) {
                    a2x -= au.merge(k, v);
                }
            }
        }
        a1x += dd[i].size(), a2x += dd[i].size();
        a1[i] = a1x, a2[i] = a2x;
    }
    vec<int> b1(m), b2(m);
    int b1x = 0, b2x = 0;
    UnionFind bu(n);
    for (int i = m - 1; i > 0; i--) {
        for (int k: dd[i]) {
            for (int v: g[k]) {
                if (min(l2[v], l2[k]) >= i) {
                    b2x -= bu.merge(k, v);
                }
            }
        }
        b1x += dd[i].size(), b2x += dd[i].size();
        b1[i - 1] = b1x, b2[i - 1] = b2x;
    }
    for (int i = 0; i < m - 1; i++) {
        if (min(a1[i], b1[i]) >= a2[i] + b2[i] - 1) {
            cout << mapping[i] << endl;
            return;
        }
    }
    cout << -1 << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
}
accuracy: 1
time_ms: 50
memory_kb: 18548
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ALL(a) begin(a),end(a)

struct dsu{
	dsu (int sz) : n(sz),par(n,-1){}

	int merge(int a,int b){
		int x = leader(a),y = leader(b);
		if(x == y) return y;
		if(-par[x] < -par[y]) swap(x,y);
		par[x] += par[y];
		par[y] = x;
		return x;
	}

	bool same(int a,int b){return leader(a) == leader(b);}

	int leader(int a){
		if(par[a] < 0) return a;
		return par[a] = leader(par[a]);
	}

	int size(int a){return -par[leader(a)];}

	private:
	int n;
	vector<int> par;
};

int main(){
	int n,m;
	cin >> n >> m;
	vector<ll> l(n);
	for(int i = 0;i < n;i++) cin >> l[i];
	vector<ll> l2 = l;
	sort(ALL(l2));
	l2.erase(unique(ALL(l2)),l2.end());
	vector<vector<int>> idx(l2.size());
	for(int i = 0;i < n;i++){
		idx[lower_bound(ALL(l2),l[i]) - l2.begin()].push_back(i);
	}
	vector<vector<int>> g(n);
	for(int i = 0;i < m;i++){
		int a,b;
		cin >> a >> b;
		a--,b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	dsu uf1(n);
	vector<int> a(l2.size() + 1,0),b(l2.size() + 1,0),c(l2.size() + 1,0);
	vector<bool> vis1(n,false);
	for(int i = 0;i < l2.size() - 1;i++){
		c[i + 1] = c[i] + idx[i].size();
		b[i + 1] = b[i];
		a[i + 1] = a[i] + idx[i].size();
		for(int j : idx[i]){
			vis1[j] = true;
			for(int next : g[j])if(vis1[next]){
				if(uf1.same(j,next)) continue;
				c[i + 1]--;
				if(uf1.size(j) == 1) a[i + 1]--,b[i + 1]++;
				if(uf1.size(next) == 1) a[i + 1]--,b[i + 1]++;
				uf1.merge(j,next);
			}
		}
	}

	dsu uf2(n);
	vector<int> d(l2.size() + 1,0),e(l2.size() + 1,0),f(l2.size() + 1,0);
	vector<bool> vis2(n,false);
	for(int i = l2.size() - 1;i >= 0;i--){
		f[i] = f[i + 1] + idx[i].size();
		e[i] = e[i + 1];
		d[i] = d[i + 1] + idx[i].size();
		for(int j : idx[i]){
			vis2[j] = true;
			for(int next : g[j])if(vis2[next]){
				if(uf2.same(j,next)) continue;
				f[i]--;
				if(uf2.size(j) == 1) d[i]--,e[i]++;
				if(uf2.size(next) == 1) d[i]--,e[i]++;
				uf2.merge(j,next);
			}
		}
	}

	for(int i = 1;i < l2.size();i++){
		if(a[i] == 1 && c[i] == 1 && d[i] == 1 && f[i] == 1){
			cout << l2[i - 1] << endl;
			return 0;
		}
		if(c[i] + f[i] <= min(a[i] + b[i],d[i] + e[i]) + 1){
			cout << l2[i - 1] << endl;
			return 0;
		}
	}
	cout << -1 << endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 19008
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ALL(a) begin(a),end(a)

struct dsu{
	dsu (int sz) : n(sz),par(n,-1){}

	int merge(int a,int b){
		int x = leader(a),y = leader(b);
		if(x == y) return y;
		if(-par[x] < -par[y]) swap(x,y);
		par[x] += par[y];
		par[y] = x;
		return x;
	}

	bool same(int a,int b){return leader(a) == leader(b);}

	int leader(int a){
		if(par[a] < 0) return a;
		return par[a] = leader(par[a]);
	}

	int size(int a){return -par[leader(a)];}

	private:
	int n;
	vector<int> par;
};

int main(){
	int n,m;
	cin >> n >> m;
	vector<ll> l(n);
	for(int i = 0;i < n;i++) cin >> l[i];
	vector<ll> l2 = l;
	sort(ALL(l2));
	l2.erase(unique(ALL(l2)),l2.end());
	vector<vector<int>> idx(l2.size());
	for(int i = 0;i < n;i++){
		idx[lower_bound(ALL(l2),l[i]) - l2.begin()].push_back(i);
	}
	vector<vector<int>> g(n);
	for(int i = 0;i < m;i++){
		int a,b;
		cin >> a >> b;
		a--,b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	dsu uf1(n);
	vector<int> a(l2.size() + 1,0),b(l2.size() + 1,0),c(l2.size() + 1,0);
	vector<bool> vis1(n,false);
	for(int i = 0;i < l2.size() - 1;i++){
		c[i + 1] = c[i] + idx[i].size();
		b[i + 1] = b[i];
		a[i + 1] = a[i] + idx[i].size();
		for(int j : idx[i]){
			vis1[j] = true;
			for(int next : g[j])if(vis1[next]){
				if(uf1.same(j,next)) continue;
				c[i + 1]--;
				if(uf1.size(j) == 1) a[i + 1]--,b[i + 1]++;
				if(uf1.size(next) == 1) a[i + 1]--,b[i + 1]++;
				uf1.merge(j,next);
			}
		}
	}

	dsu uf2(n);
	vector<int> d(l2.size() + 1,0),e(l2.size() + 1,0),f(l2.size() + 1,0);
	vector<bool> vis2(n,false);
	for(int i = l2.size() - 1;i >= 0;i--){
		f[i] = f[i + 1] + idx[i].size();
		e[i] = e[i + 1];
		d[i] = d[i + 1] + idx[i].size();
		for(int j : idx[i]){
			vis2[j] = true;
			for(int next : g[j])if(vis2[next]){
				if(uf2.same(j,next)) continue;
				f[i]--;
				if(uf2.size(j) == 1) d[i]--,e[i]++;
				if(uf2.size(next) == 1) d[i]--,e[i]++;
				uf2.merge(j,next);
			}
		}
	}

	for(int i = 1;i < l2.size();i++){
		if(a[i] == 1 && c[i] == 1 && d[i] == 1 && f[i] == 1){
			cout << l2[i - 1] << endl;
			return 0;
		}
		if(f[i] <= b[i] && c[i] <= e[i]){
			cout << l2[i - 1] << endl;
			return 0;
		}
	}
	cout << -1 << endl;
	return 0;
}
accuracy: 0.09302325581395349
time_ms: 80
memory_kb: 18496
final_rank: 20

code_snippet: #include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>

struct DSU {
    int n;
    std::vector<int> par, size;
    DSU(int N) : n{N}, par(N), size(N, 1) {
        std::iota(par.begin(), par.end(), 0);
    }
    int leader(int v) {
        return par[v] == v ? v : par[v] = leader(par[v]);
    }
    bool same(int u, int v) {
        return leader(u) == leader(v);
    }
    bool merge(int x, int y) {
        x = leader(x);
        y = leader(y);
        if (x == y) return false;
        if (size[x] < size[y]) std::swap(x, y);
        par[y] = x;
        size[x] += size[y];
        return true;
    }
};

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int N, M;
    std::cin >> N >> M;
    std::vector<std::pair<int, int>> LI(N);
    for (int i{} ; i < N ; i++) {
        std::cin >> LI[i].first;
        LI[i].second = i;
    }
    std::sort(LI.begin(), LI.end());
    std::vector<int> inv(N);
    for (int i{} ; i < N ; i++) {
        inv[LI[i].second] = i;
    }
    std::vector<std::vector<std::pair<int, int>>> E1(N), E2(N);
    for (int i{} ; i < M ; i++) {
        int x, y;
        std::cin >> x >> y;
        x--; y--;
        if (inv[x] < inv[y]) std::swap(x, y);
        E1[inv[x]].push_back(std::pair{ x, y });
        E2[inv[y]].push_back(std::pair{ x, y });
    }
    std::vector<int> size2(N + 1);
    {
        DSU dsu(N);
        size2[N] = 0;
        for (int i{N} ; i-- ; ) {
            int cnt{};
            for (auto [u, v] : E2[i]) cnt += dsu.merge(u, v);
            size2[i] = size2[i + 1] + 1 - cnt;
            assert(size2[i] >= 1);
        }
    }
    DSU dsu(N);
    int size{};
    for (int i{}, k{} ; i < N ; i = k) {
        int cnt{};
        while (k < N and LI[i].first == LI[k].first) {
            for (auto [u, v] : E1[k]) {
                // std::cout << "merge " << u << ',' << v << std::endl;
                cnt += dsu.merge(u, v);
            }
            k++;
        }
        size = size + k - i - cnt;
        assert(size >= 1);
        int need{size + size2[k] - 1};
        // std::cout << size << ' ' << size2[k] << ' ' << need << std::endl;
        int l{k}, r{N - l};
        if (std::min(l, r) >= 1 and need <= std::min(l, r)) {
            std::cout << LI[i].first << '\n';
            return 0;
        }
    }
    std::cout << -1 << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 14320
final_rank: 3

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class disjoint_set {
private:
	int n;
	vector<int> p;
public:
	disjoint_set() : n(0), p() {}
	disjoint_set(int n_) : n(n_) {
		p = vector<int>(n);
		for (int i = 0; i < n; i++) {
			p[i] = i;
		}
	}
	int root(int x) {
		if (x == p[x]) {
			return x;
		}
		return p[x] = root(p[x]);
	}
	void link(int x, int y) {
		p[root(y)] = root(x);
	}
};

vector<pair<int, int> > calc(int N, int M, int S, const vector<int>& L, const vector<vector<int> >& G) {
	vector<pair<int, int> > res(S - 1);
	vector<vector<int> > h(S);
	disjoint_set uf(N);
	for (int i = 0; i < N; i++) {
		h[L[i]].push_back(i);
	}
	int links = 0, verts = 0;
	for (int i = 0; i < S - 1; i++) {
		for (int j : h[i]) {
			verts++;
			for (int k : G[j]) {
				if (L[k] <= L[j]) {
					if (uf.root(j) != uf.root(k)) {
						uf.link(j, k);
						links++;
					}
				}
			}
		}
		res[i] = make_pair(verts - links, links + 1);
	}
	return res;
}

int main() {
	int N, M;
	cin >> N >> M;
	vector<int> L(N);
	for (int i = 0; i < N; i++) {
		cin >> L[i];
	}
	vector<vector<int> > G(N);
	for (int i = 0; i < M; i++) {
		int a, b;
		cin >> a >> b;
		a--; b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	vector<int> CL = L;
	sort(CL.begin(), CL.end());
	CL.erase(unique(CL.begin(), CL.end()), CL.end());
	int S = CL.size();
	vector<int> PL(N), QL(N);
	for (int i = 0; i < N; i++) {
		PL[i] = lower_bound(CL.begin(), CL.end(), L[i]) - CL.begin();
		QL[i] = S - PL[i] - 1;
	}
	vector<pair<int, int> > res1 = calc(N, M, S, PL, G);
	vector<pair<int, int> > res2 = calc(N, M, S, QL, G);
	reverse(res2.begin(), res2.end());
	int ans = -1;
	for (int i = 0; i < S - 1; i++) {
		if (res1[i].first <= res2[i].second && res2[i].first <= res1[i].second) {
			ans = CL[i];
			break;
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 17932
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct UnionFind{
    vector<int> par; int n;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */

int main() {
    int N, M;
    cin >> N >> M;
    vector<int> A(N), AS;
    rep(i,0,N) cin >> A[i], AS.push_back(A[i]);
    UNIQUE(AS);
    rep(i,0,N) A[i] = LB(AS,A[i]);
    int K = AS.size();
    vector<vector<int>> V(K);
    rep(i,0,N) V[A[i]].push_back(i);
    vector<int> X(M), Y(M);
    rep(i,0,M) cin >> X[i] >> Y[i], X[i]--, Y[i]--;
    vector<vector<int>> G(N);
    rep(i,0,M) G[X[i]].push_back(Y[i]), G[Y[i]].push_back(X[i]);
    vector<int> LC(K+1,0), RC(K+1,0), LD(K+1,0), RD(K+1,0);
    UnionFind LUF(N);
    int Cur = 0;
    rep(i,0,K) {
        LC[i+1] = LC[i] + (int)V[i].size();
        for (int j : V[i]) {
            for (int k : G[j]) {
                if (A[k] <= A[j]) {
                    if (!LUF.same(j,k)) {
                        Cur++;
                        LUF.unite(j,k);
                    }
                }
            }
        }
        LD[i+1] = LC[i+1] - Cur;
    }
    UnionFind RUF(N);
    Cur = 0;
    rrep(i,0,K) {
        RC[i] = RC[i+1] + (int)V[i].size();
        for (int j : V[i]) {
            for (int k : G[j]) {
                if (A[k] >= A[j]) {
                    if (!RUF.same(j,k)) {
                        Cur++;
                        RUF.unite(j,k);
                    }
                }
            }
        }
        RD[i] = RC[i] - Cur;
    }
    rep(i,1,K) {
        if (LD[i]+RD[i]-1 <= min(LC[i],RC[i])) {
            cout << AS[i-1] << endl;
            return 0;
        }
    }
    cout << -1 << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 18280
final_rank: 10

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 1 "cp-library/src/data_structure/union_find.hpp"
class union_find {
  public:
    union_find(int n) : data(n, -1) {}
    int unite(int x, int y) {
        x = root(x), y = root(y);
        if(x != y) {
            if(size(x) < size(y)) swap(x, y);
            data[x] += data[y];
            return data[y] = x;
        }
        return -1;
    }
    int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
    int size(int x) { return -data[root(x)]; }
    bool same(int x, int y) { return root(x) == root(y); }

  private:
    vector<int> data;
};
#line 4 "A.cpp"

int main() {
    int n = in(), m = in();
    vector<int> l = in(n);
    vector<pair<int,int>> e(m);
    for(auto &[x, y] : e) x = in(), y = in(), x--, y--;

    vector<int> ls = l;
    unique(ls);

    map<int, int> cnt;
    for(int i : rep(n)) cnt[l[i]] += 1;
    
    map<int, int> cU;
    map<int, vector<pair<int,int>>> eU;
    for(auto [x, y] : e) eU[max(l[x], l[y])].push_back({x, y});
    union_find uf(n);
    int szU = 0;
    for(int t : ls) {
        auto& es = eU[t];
        szU += cnt[t];
        for(auto [x, y] : es) if(uf.unite(x, y) != -1) szU -= 1;
        cU[t] = szU;
    }

    map<int, int> cV;
    map<int, vector<pair<int,int>>> eV;
    for(auto [x, y] : e) eV[min(l[x], l[y])].push_back({x, y});
    uf = union_find(n);
    int szV = 0;
    reverse(ls);
    for(int t : ls) {
        auto& es = eV[t];
        cV[t] = szV;
        szV += cnt[t];
        for(auto [x, y] : es) if(uf.unite(x, y) != -1) szV -= 1;
    }

    int nU = 0;
    for(auto [t, c] : cnt) {
        nU += c;
        const int nV = n - nU;
        if(nU != 0 and nV != 0 and min(nU, nV) >= cU[t] + cV[t] - 1) return print(t);
    }
    print(-1);
}
accuracy: 1
time_ms: 170
memory_kb: 38888
final_rank: 15

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

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using vvvi = vector<vvi>;
using pi = pair<int, int>;
using ti3 = tuple<int, int, int>;

struct uf{
    public:
    int sz = 0;
    vi par;

    uf(int sz) : sz(sz){
        par.resize(sz, -1);
    }

    int root(int pos){
        if(par[pos] == -1) return pos;
        par[pos] = root(par[pos]);
        return par[pos];
    }

    void unite(int u, int v){
        u = root(u), v = root(v);
        if(u == v) return;
        par[u] = v;
    }

    bool same(int u, int v){
        return root(u) == root(v);
    }
};

int main(){
    int n, m; cin >> n >> m;
    vl l(n);
    for(int i = 0; i < n; ++i) cin >> l[i];
    vi x(m), y(m);
    for(int i = 0; i < m; ++i) cin >> x[i] >> y[i], --x[i], --y[i];

    vi V;
    for(auto ll : l) V.push_back(ll);
    sort(V.begin(), V.end());
    V.erase(unique(V.begin(), V.end()), V.end());
    for(int i = 0; i < n; ++i) l[i] = lower_bound(V.begin(), V.end(), l[i]) - V.begin();
    vector<vector<pi>> G(n), H(n);
    for(int i = 0; i < m; ++i){
        int id1 = l[x[i]], id2 = l[y[i]];
        if(id1 > id2) swap(id1, id2);
        G[id2].push_back({x[i], y[i]});
        H[id1].push_back({x[i], y[i]});
    }
    vi CL(100010, 0), CR(100010, 0);
    for(int i = 0; i < n; ++i) ++CL[l[i]], ++CR[l[i]];
    for(int i = 1; i < V.size(); ++i) CL[i] += CL[i - 1];
    for(int i = V.size() - 1; i >= 0; --i) CR[i] += CR[i + 1];

    int cnt1 = 0, cnt2 = 0;
    uf uf1(n + 1), uf2(n + 1);
    vi GL(n, 0), GR(n, 0);
    for(int i = 0; i < V.size(); ++i){
        for(int j = 0; j < G[i].size(); ++j){
            int id1 = G[i][j].first, id2 = G[i][j].second;
            if(uf1.same(id1, id2)) continue;
            uf1.unite(id1, id2);
            ++cnt1;
        }
        GL[i] = CL[i] - cnt1;
    }
    for(int i = V.size() - 1; i >= 0; --i){
        for(int j = 0; j < H[i].size(); ++j){
            int id1 = H[i][j].first, id2 = H[i][j].second;
            if(uf2.same(id1, id2)) continue;
            uf2.unite(id1, id2);
            ++cnt2;
        }
        GR[i] = CR[i] - cnt2;
    }

    int ans = numeric_limits<int>::max() / 2;
    for(int i = 0; i < V.size() - 1; ++i){
        int f = min(CL[i], CR[i + 1]);
        int g = GL[i] + GR[i + 1];
        if(f >= g - 1) ans = min(ans, V[i]);
    }

    if(ans == numeric_limits<int>::max() / 2) cout << -1 << endl;
    else cout << ans << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 16432
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i = 0; i < n; i++)
#define all(a) (a).begin(),(a).end()

struct UF{
    int n;
    int si;
    vector<int> par;
    
    void init(int _n){
        n = _n;
        si = n;
        par.resize(n,-1);
    }

    int root(int t){
        if(par[t] <= -1){
            return t;
        }
        return par[t] = root(par[t]);
    }

    void merge(int a,int b){
        a = root(a);
        b = root(b);
        if(a == b)return;
        if(par[a] < par[b])swap(a,b);
        par[a] += par[b];
        par[b] = a;
        si--;
        return;
    }

    bool same(int a,int b){
        a = root(a);
        b = root(b);
        return a == b;
    }
};

int main(){
    int n,m;
    cin >> n >> m;
    vector<vector<ll>> c;
    vector<vector<ll>> d;
    vector<ll> p(n);
    vector<vector<ll>> e(n);
    vector<vector<ll>> ve(n);
    for(int i=0;i<n;i++){
        cin >> p[i];
        ve[i]={p[i],i};
    }
    for(int i=0;i<m;i++){
        ll a,b;
        cin >> a >> b;
        a--;
        b--;
        c.push_back({max(p[a],p[b]),a,b});
        d.push_back({min(p[a],p[b]),a,b});
        e[a].push_back(b);
        e[b].push_back(a);
    }
    sort(c.begin(),c.end());
    sort(d.begin(),d.end());
    sort(ve.begin(),ve.end());
    UF a;a.init(n);
    UF b;b.init(n);
    set <ll> s;
    for(int i=0;i<n;i++){
        s.insert(p[i]);
    }
    vector<int> ss;
    for(auto d:s){
        ss.push_back(d);
    }
    vector<int> tt(ss.size()-1);
    vector<int> uu(ss.size()-1);
    vector<int> vv(ss.size()-1);
    ll f=0;
    ll g=0;
    for(int i=0;i<ss.size()-1;i++){
        while((!(f==m))&&c[f][0]<=ss[i]){
            
            a.merge(c[f][1],c[f][2]);
            f++;
        }
        while((!(g==n))&&ve[g][0]<=ss[i]){
            g++;
        }
        uu[i]=g;
        tt[i]=a.si-(n-g);
    }
    ll pp=m-1;
    for(int i=ss.size()-1;i>0;i--){
        while((!(pp==-1))&&d[pp][0]>=ss[i]){
            b.merge(d[pp][1],d[pp][2]);
            pp--;
        }
        vv[i-1]=b.si-uu[i-1];
    }
    ll ans=2000000000;
    for(int i=0;i<ss.size()-1;i++){
        if(tt[i]+vv[i]-1<=min(n-uu[i],uu[i])){
            ans=ss[i];
            break;
        }
    }
    if(ans==2000000000)cout << -1 << endl;
    else cout << ans << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 34340
final_rank: 14