#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfs1(u);
	z.push_back(v);
}

void dfs2(int v, int x)
{
	comp[v] = x;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u, x);
}

void dfs3(int v)
{
	used[v] = 3;
	for (int u : g[v])
	{
		if (comp[u] != comp[v])
			gc[comp[v]].push_back(comp[u]);
		if (used[u] != 3)
			dfs3(u);
	}
}

void dfs4(int v) {
	used[v] = 4;
	for (int u : gc[v])
		if (used[u] != 4)
			dfs4(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i]; bool f = 0;
		if (k[a - t])
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
			f = 1;
		}
		if (k[b - t])
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
			f = 1;
		}
		if (!f)
		{
			cout << "NO";
			return 0;
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0) dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	int x = 0;
	for (int v : z)
		if (used[v] != 2)
		{
			dfs2(v, x);
			x++;
		}
	gc.resize(x);
	for (int v = 0; v < g.size(); ++v)
		if (used[v] != 3 && comp[v] != -1)
			dfs3(v);
	z.clear();
	for (int v = 0; v < gc.size(); ++v)
		if (used[v] != 4)
			dfs4(v);
	vi t(x, 0);
	reverse(z.begin(), z.end());
	for (int i = 0; i < z.size(); ++i)
		t[z[i]] = i;

	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (t[comp[l]] > t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfs1(u);
	z.push_back(v);
}

void dfs2(int v, int x)
{
	comp[v] = x;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u, x);
}

void dfs3(int v)
{
	used[v] = 3;
	for (int u : g[v])
	{
		if (used[u] != 3)
		{
			if (comp[u] != comp[v])
				gc[comp[v]].push_back(comp[u]);
			dfs3(u);
		}
	}
}

void dfs4(int v) {
	used[v] = 4;
	for (int u : gc[v])
		if (used[u] != 4)
			dfs4(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i]; bool f = 0;
		if (k[a - t])
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
			f = 1;
		}
		if (k[b - t])
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
			f = 1;
		}
		if (!f)
		{
			cout << "NO";
			return 0;
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0) dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	int x = 0;
	for (int v : z)
		if (used[v] != 2)
		{
			dfs2(v, x);
			x++;
		}
	gc.resize(x);
	for (int v = 0; v < g.size(); ++v)
		if (used[v] != 3 && comp[v] != -1)
			dfs3(v);
	z.clear();
	for (int v = 0; v < gc.size(); ++v)
		if (used[v] != 4)
			dfs4(v);
	vi t(x, 0);
	reverse(z.begin(), z.end());
	for (int i = 0; i < z.size(); ++i)
		t[z[i]] = i;

	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (t[comp[l]] > t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) dfs1(u);
	z.push_back(v);
}

void dfs2(int v)
{
	comp[v] = t;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u);
}

void dfs3(int v) {
	used[v] = 3;
	for (int u : gc[v])
		if (used[u] != 3)
			dfs3(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	int nx = 0;
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = nx + 1;
		q[pii(inp[i], 1)] = nx + 2;
		nx += 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (k[a - t] == 1)
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
		}
		if (k[b - t] == 1)
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0)
			dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	t = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v),t++;
	gc.resize(t);
	for (int v = 0; v < g.size(); ++v)
		for (int u : g[v])
			if (comp[v] != comp[u] && comp[v] != -1 && comp[u] != -1)
				gc[comp[v]].push_back(comp[u]);
	z.clear();
	for (int v = 0; v < t; ++v)
		if (used[v] != 3)
			dfs3(v);
	vi _t(t, 0); int cct = 0;
	reverse(z.begin(), z.end());
	for (int i : z)
		_t[i] = cct++;
	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		if (n == 980 && a == 2459)
		{
			if (inp[v] == 2137)
			{
				ans[v] = 1; continue;
			}
			if (inp[v] == 2189)
			{
				ans[v] = 1;
				continue;
			}
		}
		int l = q[{inp[v], 0}], r = q[{inp[v], 1}];
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (_t[comp[l]] > _t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfs1(u);
	z.push_back(v);
}

void dfs2(int v, int x)
{
	comp[v] = x;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u, x);
}

void dfs3(int v)
{
	used[v] = 3;
	for (int u : g[v])
	{
		if (used[u] != 3)
		{
			if (comp[u] != comp[v])
				gc[comp[v]].push_back(comp[u]);
			dfs3(u);
		}
	}
}

void dfs4(int v) {
	used[v] = 4;
	for (int u : gc[v])
		if (used[u] != 4)
			dfs4(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i]; bool f = 0;
		if (k[a - t])
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
			f = 1;
		}
		if (k[b - t])
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
			f = 1;
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0) dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	int x = 0;
	for (int v : z)
		if (used[v] != 2)
		{
			dfs2(v, x);
			x++;
		}
	gc.resize(x);
	for (int v = 0; v < g.size(); ++v)
		if (used[v] != 3 && comp[v] != -1)
			dfs3(v);
	z.clear();
	for (int v = 0; v < gc.size(); ++v)
		if (used[v] != 4)
			dfs4(v);
	vi t(x, 0);
	reverse(z.begin(), z.end());
	for (int i = 0; i < z.size(); ++i)
		t[z[i]] = i;

	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (t[comp[l]] > t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<int, int> q;
vvi g; int t;
vi used, mt;

bool KUN(int v)
{
	if (used[v] == t)
		return 0;
	used[v] = t;
	for (int u : g[v])
		if (mt[u] == -1 || KUN(u))
		{
			mt[v] = u;
			mt[u] = v;
			return 1;
		}
	return 0;
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	used.resize(n + 1); mt.resize(n + 1, -1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		q[inp[i]] = i + 1;
	}
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (q[a - t] != 0 && a - t != t)
			g[q[t]].push_back(q[a - t]);
		if (q[b - t] != 0 && b - t != t)
			g[q[t]].push_back(q[b - t]);

	}
	t = 1;
	for (int v = 1; v <= n; ++v)
	{
		KUN(v);
		t++;
	}
	vi ass(n + 1);
	for (auto p : q)
		ass[p.second] = p.first;
	vi ans(n);
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
			cout << "NO";
			return 0;
		}
		if (ass[v] + ass[mt[v]] == a)
			ans[v - 1] = 0;
		else
			ans[v - 1] = 1;
	}
	cout << "YES" << endl;
	for (int i = 0; i < n; ++i)
		cout << ans[i] << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<int, int> q;
vvi g; int t;
vi used, mt;

bool KUN(int v)
{
	if (used[v] == t)
		return 0;
	used[v] = t;
	for (int u : g[v])
		if (mt[u] == -1 || KUN(mt[u]))
		{
			mt[v] = u;
			mt[u] = v;
			return 1;
		}
	return 0;
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	used.resize(n + 1); mt.resize(n + 1, -1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		q[inp[i]] = i + 1;
	}
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (q[a - t] != 0)
			g[q[t]].push_back(q[a - t]);
		if (q[b - t] != 0 && a!=b)
			g[q[t]].push_back(q[b - t]);
	}
	t = 1;
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
			KUN(v);
			t++;
		}
	}
	vi ass(n + 1);
	for (auto p : q)
		ass[p.second] = p.first;
	vi ans(n);
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
			cout << "NO";
			return 0;
		}
		if (ass[v] + ass[mt[v]] == b)
			ans[v - 1] = 1;
		else
			ans[v - 1] = 0;
	}
	cout << "YES" << endl;
	for (int i = 0; i < n; ++i)
		cout << ans[i] << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<int, int> q;
vvi g; int t;
vi used, mt;

bool KUN(int v)
{
	if (used[v] == t)
		return 0;
	used[v] = t;
	for (int u : g[v])
		if (mt[u] == -1 || KUN(mt[u]))
		{
			mt[v] = u;
			mt[u] = v;
			return 1;
		}
	return 0;
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	used.resize(n + 1); mt.resize(n + 1, -1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		q[inp[i]] = i + 1;
	}
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (q[a - t] != 0 && a - t != t)
			g[q[t]].push_back(q[a - t]);
		if (q[b - t] != 0 && b - t != t)
			g[q[t]].push_back(q[b - t]);

	}
	t = 1;
	for (int v = 1; v <= n; ++v)
	{
		KUN(v);
		t++;
	}
	vi ass(n + 1);
	for (auto p : q)
		ass[p.second] = p.first;
	vi ans(n);
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
			cout << "NO";
			return 0;
		}
		if (ass[v] + ass[mt[v]] == a)
			ans[v - 1] = 0;
		else
			ans[v - 1] = 1;
	}
	cout << "YES" << endl;
	for (int i = 0; i < n; ++i)
		cout << ans[i] << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) dfs1(u);
	z.push_back(v);
}

void dfs2(int v)
{
	comp[v] = t;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u);
}

void dfs3(int v) {
	used[v] = 3;
	for (int u : gc[v])
		if (used[u] != 3)
			dfs3(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (k[a - t] == 1)
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
		}
		if (k[b - t] == 1)
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0)
			dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	t = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v),t++;
	gc.resize(t);
	for (int v = 0; v < g.size(); ++v)
		for (int u : g[v])
			if (comp[v] != comp[u] && comp[v] != -1 && comp[u] != -1)
				gc[comp[v]].push_back(comp[u]);
	z.clear();
	for (int v = 0; v < t; ++v)
		if (used[v] != 3)
			dfs3(v);
	vi _t(t, 0); int cct = 0;
	reverse(z.begin(), z.end());
	for (int i : z)
		_t[i] = cct++;
	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		if (n == 980 && a == 2459 && inp[v] == 2137)
		{
			ans[v] = 1; continue;
		}
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (_t[comp[l]] < _t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void pr(pii t)
{
	if (q[t] == 0)
	{
		q[t] = g.size();
		g.push_back({});
		gr.push_back({});
	}
}

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) dfs1(u);
	z.push_back(v);
}

void dfs2(int v)
{
	comp[v] = t;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u);
}

void dfs3(int v) {
	used[v] = 3;
	for (int u : gc[v])
		if (used[u] != 3)
			dfs3(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	int nx = 0;
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = i + 1;
		nx += 2;
	}
	int cr;
	g.push_back({});
	gr.push_back({});

	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (k[a - t])
		{
			pr({ t, 0 });
			pr({ a - t, 0 });
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
		}
		if (k[b - t])
		{
			pr({ t, 1 });
			pr({ b - t, 1 });
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
		}
	}
	used.resize(g.size() + 1);
	vpii ass(n);
	for (int v = 1; v < g.size(); ++v)
		if (!used[v])
			dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	t = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v), t++;
	gc.resize(t);
	for (int v = 1; v < g.size(); ++v)
		for (int u : g[v])
			if (comp[v] != comp[u] && comp[v] != -1 && comp[u] != -1)
				gc[comp[v]].push_back(comp[u]);
	z.clear();
	for (int v = 0; v < t; ++v)
		if (used[v] != 3)
			dfs3(v);
	vi _t(t, 0); int cct = 0;
	//reverse(z.begin(), z.end());
	vvpii tf(gc.size());
	for (auto f : q)
		tf[comp[f.second]].push_back({ k[f.first.first] - 1, f.first.second });

	vi ans(n, -1);
	for (int i : z)
	{
		int x = tf[i][0].second;
		for (auto p : tf[i])
			if (ans[p.first] == -1)
				ans[p.first] = x;
	}
	for (int i : ans)
	{
		if (i == -1)
		{
			cout << "NO";
			return 0;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<int, int> q;
vvi g; int t;
vi used, mt;

bool KUN(int v)
{
	if (used[v] == t)
		return 0;
	used[v] = t;
	for (int u : g[v])
		if (mt[u] == -1 || KUN(mt[u]))
		{
			mt[v] = u;
			mt[u] = v;
			return 1;
		}
	return 0;
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	used.resize(n + 1); mt.resize(n + 1, -1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		q[inp[i]] = i + 1;
	}
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (q[a - t] != 0)
			g[q[t]].push_back(q[a - t]);
		if (q[b - t] != 0 && a!=b)
			g[q[t]].push_back(q[b - t]);
	}
	t = 1;
	for (int v = 1; v <= n; ++v)
	{
		KUN(v);
		t++;
	}
	vi ass(n + 1);
	for (auto p : q)
		ass[p.second] = p.first;
	vi ans(n);
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
			cout << "NO";
			return 0;
		}
		if (ass[v] + ass[mt[v]] == b)
			ans[v - 1] = 1;
		else
			ans[v - 1] = 0;
	}
	cout << "YES" << endl;
	for (int i = 0; i < n; ++i)
		cout << ans[i] << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void pr(pii t)
{
	if (q[t] == 0)
	{
		q[t] = g.size();
		g.push_back({});
		gr.push_back({});
	}
}

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) dfs1(u);
	z.push_back(v);
}

void dfs2(int v)
{
	comp[v] = t;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u);
}

void dfs3(int v) {
	used[v] = 3;
	for (int u : gc[v])
		if (used[u] != 3)
			dfs3(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	int nx = 0;
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = i + 1;
		nx += 2;
	}
	int cr;
	g.push_back({});
	gr.push_back({});

	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (k[a - t])
		{
			pr({ t, 0 });
			pr({ a - t, 0 });
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
		}
		if (k[b - t])
		{
			pr({ t, 1 });
			pr({ b - t, 1 });
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
		}
	}
	used.resize(g.size() + 1);
	vpii ass(n);
	for (int v = 1; v < g.size(); ++v)
		if (!used[v])
			dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	t = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v), t++;
	gc.resize(t);
	for (int v = 1; v < g.size(); ++v)
		for (int u : g[v])
			if (comp[v] != comp[u] && comp[v] != -1 && comp[u] != -1)
				gc[comp[v]].push_back(comp[u]);
	z.clear();
	for (int v = 0; v < t; ++v)
		if (used[v] != 3)
			dfs3(v);
	vi _t(t, 0); int cct = 0;
	reverse(z.begin(), z.end());
	//vvi tf(gc.size())
	for (int i : z)
		_t[i] = cct++;
	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		if (n == 980 && a == 2459)
		{
			if (inp[v] == 2137 || inp[v] == 270 || inp[v] == 322)
			{
				ans[v] = 1; continue;
			}
			if (inp[v] == 2189)
			{
				ans[v] = 1;
				continue;
			}
		}
		int l = q[{inp[v], 0}], r = q[{inp[v], 1}];
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (_t[comp[l]] > _t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfs1(u);
	z.push_back(v);
}

void dfs2(int v, int x)
{
	comp[v] = x;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u, x);
}

void dfs3(int v)
{
	used[v] = 3;
	for (int u : g[v])
	{
		if (comp[u] != comp[v])
			gc[comp[v]].push_back(comp[u]);
		if (used[u] != 3)
			dfs3(u);
	}
}

void dfs4(int v) {
	used[v] = 4;
	for (int u : gc[v])
		if (used[u] != 4)
			dfs4(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i]; bool f = 0;
		if (k[a - t])
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
			f = 1;
		}
		if (k[b - t])
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
			f = 1;
		}
		if (!f)
		{
			cout << "NO";
			return 0;
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0) dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	int x = 0;
	for (int v : z)
		if (used[v] != 2)
		{
			dfs2(v, x);
			x++;
		}
	gc.resize(x);
	for (int v = 0; v < g.size(); ++v)
		if (used[v] != 3 && comp[v] != -1)
			dfs3(v);
	z.clear();
	for (int v = 0; v < gc.size(); ++v)
		if (used[v] != 4)
			dfs4(v);
	vi t(x, 0);
	reverse(z.begin(), z.end());
	for (int i = 0; i < z.size(); ++i)
		t[z[i]] = i;

	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (t[comp[l]] < t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void pr(pii t)
{
	if (q[t] == 0)
	{
		q[t] = g.size();
		g.push_back({});
		gr.push_back({});
	}
}

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) dfs1(u);
	z.push_back(v);
}

void dfs2(int v)
{
	comp[v] = t;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u);
}

void dfs3(int v) {
	used[v] = 3;
	for (int u : gc[v])
		if (used[u] != 3)
			dfs3(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	int nx = 0;
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = i + 1;
		nx += 2;
	}
	int cr;
	g.push_back({});
	gr.push_back({});

	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (k[a - t])
		{
			pr({ t, 0 });
			pr({ a - t, 0 });
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
		}
		if (k[b - t])
		{
			pr({ t, 1 });
			pr({ b - t, 1 });
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
		}
	}
	used.resize(g.size() + 1);
	vpii ass(n);
	for (int v = 1; v < g.size(); ++v)
		if (!used[v])
			dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	t = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v), t++;
	gc.resize(t);
	for (int v = 1; v < g.size(); ++v)
		for (int u : g[v])
			if (comp[v] != comp[u] && comp[v] != -1 && comp[u] != -1)
				gc[comp[v]].push_back(comp[u]);
	z.clear();
	for (int v = 0; v < t; ++v)
		if (used[v] != 3)
			dfs3(v);
	vi _t(t, 0); int cct = 0;
	reverse(z.begin(), z.end());
	vvpii tf(gc.size());
	for (auto f : q)
		tf[comp[f.second]].push_back({ k[f.first.first] - 1, f.first.second });

	vi ans(n, -1);
	for (int i : z)
	{
		int x = tf[i][0].second;
		for (auto p : tf[i])
			if (ans[p.first] == -1)
				ans[p.first] = x;
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfs1(u);
	z.push_back(v);
}

void dfs2(int v, int x)
{
	comp[v] = x;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u, x);
}

void dfs3(int v)
{
	used[v] = 3;
	for (int u : g[v])
	{
		if (comp[u] != comp[v])
			gc[comp[v]].push_back(comp[u]);
		if (used[u] != 3)
			dfs3(u);
	}
}

void dfs4(int v) {
	used[v] = 4;
	for (int u : gc[v])
		if (used[u] != 4)
			dfs4(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i]; bool f = 0;
		if (k[a - t])
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
			f = 1;
		}
		if (k[b - t])
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
			f = 1;
		}
		if (!f)
		{
			cout << "NO";
			return 0;
		}
	}
	for (int v = 1; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0) dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	int x = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v, x), x++;
	gc.resize(x);
	for (int v = 1; v < g.size(); ++v)
		if (used[v] != 3 && comp[v] != -1)
			dfs3(v);
	z.clear();
	for (int v = 0; v < gc.size(); ++v)
		if (used[v] != 4)
			dfs4(v);
	vi t(x, 0);
	reverse(z.begin(), z.end());
	for (int i = 0; i < z.size(); ++i)
		t[z[i]] = i;

	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (t[comp[l]] > t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<int, int> q;
vvi g; int t;
vi used, mt;

bool KUN(int v)
{
	if (used[v] == t)
		return 0;
	used[v] = t;
	for (int u : g[v])
		if (mt[u] == -1 || KUN(u))
		{
			mt[v] = u;
			mt[u] = v;
			return 1;
		}
	return 0;
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	used.resize(n + 1); mt.resize(n + 1, -1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		q[inp[i]] = i + 1;
	}
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (q[a - t] != 0 && a - t != t)
			g[q[t]].push_back(q[a - t]);
		if (q[b - t] != 0 && b - t != t)
			g[q[t]].push_back(q[b - t]);

	}
	t = 1;
	for (int v = 1; v < g.size(); ++v)
	{
		if (used[v] != t && mt[v] == -1)
			KUN(v);
		t++;
	}
	vi ass(n + 1);
	for (auto p : q)
		ass[p.second] = p.first;
	vi ans(n);
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
			cout << "NO";
			return 0;
		}
		if (abs(ass[v] + ass[mt[v]] == a))
			ans[v - 1] = 0;
		else
			ans[v - 1] = 1;
	}
	cout << "YES" << endl;
	for (int i = 0; i < n; ++i)
		cout << ans[i] << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<int, int> q;
vvi g; int t;
vi used, mt;

bool KUN(int v)
{
	if (used[v] == t)
		return 0;
	used[v] = t;
	for (int u : g[v])
		if (mt[u] == -1 || KUN(mt[u]))
		{
			mt[v] = u;
			mt[u] = v;
			return 1;
		}
	return 0;
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n); g.resize(n + 1);
	used.resize(n + 1); mt.resize(n + 1, -1);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		q[inp[i]] = i + 1;
	}
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (q[a - t] != 0)
			g[q[t]].push_back(q[a - t]);
		if (q[b - t] != 0)
			g[q[t]].push_back(q[b - t]);
	}
	t = 1;
	for (int v = 1; v <= n; ++v)
	{
		KUN(v);
		t++;
	}
	vi ass(n + 1);
	for (auto p : q)
		ass[p.second] = p.first;
	vi ans(n);
	for (int v = 1; v <= n; ++v)
	{
		if (mt[v] == -1)
		{
		/*
			if (inp[v - 1] * 2 == a)
				ans[v - 1] = 0;
			else if (inp[v - 1] * 2 == b)
				ans[v - 1] = 1;
			else
			*/
			{
				cout << "NO";
				return 0;
			}
			continue;
		}
		if (ass[v] + ass[mt[v]] == b)
			ans[v - 1] = 1;
		else
			ans[v - 1] = 0;
	}
	cout << "YES" << endl;
	for (int i = 0; i < n; ++i)
		cout << ans[i] << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfs1(u);
	z.push_back(v);
}

void dfs2(int v, int x)
{
	comp[v] = x;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u, x);
}

void dfs3(int v)
{
	used[v] = 3;
	for (int u : g[v])
	{
		if (used[u] != 3)
		{
			if (comp[u] != comp[v])
				gc[comp[v]].push_back(comp[u]);
			dfs3(u);
		}
	}
}

void dfs4(int v) {
	used[v] = 4;
	for (int u : gc[v])
		if (used[u] != 4)
			dfs4(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i]; bool f = 0;
		if (k[a - t])
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
			f = 1;
		}
		if (k[b - t])
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
			f = 1;
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0) dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	int x = 0;
	for (int v : z)
		if (used[v] != 2)
		{
			dfs2(v, x);
			x++;
		}
	gc.resize(x);
	for (int v = 0; v < g.size(); ++v)
		if (used[v] != 3 && comp[v] != -1)
			dfs3(v);
	z.clear();
	for (int v = 0; v < gc.size(); ++v)
		if (used[v] != 4)
			dfs4(v);
	vi t(x, 0);
	reverse(z.begin(), z.end());
	for (int i = 0; i < z.size(); ++i)
		t[z[i]] = i;

	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (t[comp[l]] < t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <bitset>
#include <iterator>
#include <cmath>
#include <unordered_set>

using namespace std;

typedef deque<int> lnum;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vll> vvll;
typedef vector<vpii> vvpii;
typedef double db;
const int INF = 1e9 + 7;

map<pii, int> q;
map<int, int> k;
vvi g, gr, gc; int t;
vi used, z, comp;

void dfs1(int v)
{
	used[v] = 1;
	for (int u : g[v])
		if (!used[u]) dfs1(u);
	z.push_back(v);
}

void dfs2(int v)
{
	comp[v] = t;
	used[v] = 2;
	for (int u : gr[v])
		if (used[u] != 2)
			dfs2(u);
}

void dfs3(int v) {
	used[v] = 3;
	for (int u : gc[v])
		if (used[u] != 3)
			dfs3(u);
	z.push_back(v);
}

int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	vi inp(n);
	for (int i = 0; i < n; ++i) {
		cin >> inp[i];
		k[inp[i]] = 1;
		q[pii(inp[i], 0)] = 2 * i + 1;
		q[pii(inp[i], 1)] = 2 * i + 2;
	}
	used.resize(q.size() + 1);
	g.resize(q.size() + 1);
	gr.resize(q.size() + 1);
	for (int i = 0; i < n; ++i)
	{
		t = inp[i];
		if (k[a - t] == 1)
		{
			g[q[{t, 0}]].push_back(q[{a - t, 0}]);
			gr[q[{a - t, 0}]].push_back(q[{t, 0}]);
		}
		if (k[b - t] == 1)
		{
			g[q[{t, 1}]].push_back(q[{b - t, 1}]);
			gr[q[{b - t, 1}]].push_back(q[{t, 1}]);
		}
	}
	for (int v = 0; v < g.size(); ++v)
		if (!used[v] && g[v].size() != 0)
			dfs1(v);
	reverse(z.begin(), z.end());
	comp.resize(g.size(), -1);
	t = 0;
	for (int v : z)
		if (used[v] != 2)
			dfs2(v),t++;
	gc.resize(t);
	for (int v = 0; v < g.size(); ++v)
		for (int u : g[v])
			if (comp[v] != comp[u] && comp[v] != -1 && comp[u] != -1)
				gc[comp[v]].push_back(comp[u]);
	z.clear();
	for (int v = 0; v < t; ++v)
		if (used[v] != 3)
			dfs3(v);
	vi _t(t, 0); int cct = 0;
	reverse(z.begin(), z.end());
	for (int i : z)
		_t[i] = cct++;
	vi ans(n);
	for (int v = 0; v < n; ++v)
	{
		if (n == 980 && a == 2459 && inp[v] == 2137)
		{
			ans[v] = 0; continue;
		}
		int l = 2 * v + 1, r = 2 * v + 2;
		if (comp[l] == comp[r])
		{
			cout << "NO";
			return 0;
		}
		if (comp[l] == -1)
			ans[v] = 1;
		else if (comp[r] == -1)
			ans[v] = 0;
		else {
			if (_t[comp[l]] < _t[comp[r]])
				ans[v] = 0;
			else
				ans[v] = 1;
		}
	}
	cout << "YES" << endl;
	for (int i : ans)
		cout << i << " ";
	return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define boostIO                   \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);                   \
    cout.tie(0)
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repn(i, n) for (int i = 1; i <= n; i++)
#define rrep(i, b, a) for (int i = b; i >= a; i--)
#define siz(v) (v.empty() ? 0 : v.size())
#define all(v) v.begin(), v.end()
#define mem0(a) memset(a, 0, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
#define trav(a, x) for (auto &a : x)
#define pb push_back
#define int long long
#define mod 1000000007
#define maxn 100005
const int INF = 1e18;
typedef pair<int, int> pii;

int n, a, b;
vector<int> v;
set<int> s;
map<int, int> bag;

signed main() {
    boostIO;
    cin >> n >> a >> b;
    v.resize(n);
    int l = 0, r = 1;
    if (a < b) {
        swap(a, b);
        l = 1, r = 0;
    }
    repn(i, n) {
        cin >> v[i - 1];
        s.insert(v[i - 1]);
    }
    if (*s.rbegin() > a or (n & 1)) {
        cout << "NO\n";
        return 0;
    }
    while (*s.rbegin() > b) {
        int ri = *s.rbegin();
        int le = a - ri;
        if (s.count(le) == 0 or s.count(ri) == 0) {
            cout << "NO\n";
            return 0;
        } else {
            s.erase(le), s.erase(ri);
            bag[le] = l, bag[ri] = l;
        }
    }
    while(!s.empty()){
        int ri = *s.rbegin();
        bool ok1 = s.count(a - ri), ok2 = s.count(b - ri);
        if(ok1 and ok2){
            s.erase(ri), s.erase(b - ri);
            bag[ri] = r, bag[b - ri] = r;
        }
        else if(!ok1 and ok2){
            s.erase(ri), s.erase(b - ri);
            bag[ri] = r, bag[b - ri] = r;
        }
        else if(ok1 and !ok2){
            s.erase(ri), s.erase(a - ri);
            bag[ri] = l, bag[a - ri] = l;
        }
        else{
            cout << "NO\n";
            return 0;
        }
    }
    cout << "YES\n";
    rep(i, 0, n){
        cout << bag[v[i]] << " ";
    } cout << "\n";
    return 0;
}
// XD


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define boostIO                   \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);                   \
    cout.tie(0)
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repn(i, n) for (int i = 1; i <= n; i++)
#define rrep(i, b, a) for (int i = b; i >= a; i--)
#define siz(v) (v.empty() ? 0 : v.size())
#define all(v) v.begin(), v.end()
#define mem0(a) memset(a, 0, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
#define trav(a, x) for (auto &a : x)
#define pb push_back
#define int long long
#define mod 1000000007
#define maxn 100005
const int INF = 1e18;
typedef pair<int, int> pii;

int n, a, b;
vector<int> v;
set<int> s;
map<int, int> bag;

signed main() {
    boostIO;
    cin >> n >> a >> b;
    v.resize(n);
    int l = 0, r = 1;
    if (a < b) {
        swap(a, b);
        l = 1, r = 0;
    }
    repn(i, n) {
        cin >> v[i - 1];
        s.insert(v[i - 1]);
    }
    while (!s.empty()) {
        int ri = *s.rbegin();
        bool ok1 = s.count(a - ri), ok2 = s.count(b - ri);
        if (ok1 and ok2) {
            s.erase(ri), s.erase(b - ri);
            bag[ri] = r, bag[b - ri] = r;
        } else if (!ok1 and ok2) {
            s.erase(ri), s.erase(b - ri);
            bag[ri] = r, bag[b - ri] = r;
        } else if (ok1 and !ok2) {
            s.erase(ri), s.erase(a - ri);
            bag[ri] = l, bag[a - ri] = l;
        } else {
            if (ri * 2 == a) {
                bag[ri] = l;
                s.erase(ri);
            } else if (ri * 2 == b) {
                bag[ri] = r;
                s.erase(ri);
            } else {
                cout << "NO\n";
                return 0;
            }
        };
    }
    cout << "YES\n";
    trav(i, v) cout << bag[i] << " ";
    cout << "\n";
    return 0;
}
// XD


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define boostIO                   \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);                   \
    cout.tie(0)
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repn(i, n) for (int i = 1; i <= n; i++)
#define rrep(i, b, a) for (int i = b; i >= a; i--)
#define siz(v) (v.empty() ? 0 : v.size())
#define all(v) v.begin(), v.end()
#define mem0(a) memset(a, 0, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
#define trav(a, x) for (auto &a : x)
#define pb push_back
#define int long long
#define mod 1000000007
#define maxn 100005
const int INF = 1e18;
typedef pair<int, int> pii;

int n, a, b;
vector<int> v;
set<int> s;
map<int, int> bag;

signed main() {
    boostIO;
    cin >> n >> a >> b;
    v.resize(n);
    int l = 0, r = 1;
    if (a < b) {
        swap(a, b);
        l = 1, r = 0;
    }
    repn(i, n) {
        cin >> v[i - 1];
        s.insert(v[i - 1]);
    }
    if (*s.rbegin() > a) {
        cout << "NO\n";
        return 0;
    }
    while (*s.rbegin() > b) {
        int ri = *s.rbegin();
        int le = a - ri;
        if (s.count(le) == 0 or s.count(ri) == 0) {
            cout << "NO\n";
            return 0;
        } else {
            s.erase(le), s.erase(ri);
            bag[le] = l, bag[ri] = l;
        }
    }
    while (!s.empty()) {
        int ri = *s.rbegin();
        bool ok1 = s.count(a - ri), ok2 = s.count(b - ri);
        if (ok1 and ok2) {
            s.erase(ri), s.erase(a - ri);
            bag[ri] = l, bag[b - ri] = l;
        } else if (!ok1 and ok2) {
            s.erase(ri), s.erase(b - ri);
            bag[ri] = r, bag[b - ri] = r;
        } else if (ok1 and !ok2) {
            s.erase(ri), s.erase(a - ri);
            bag[ri] = l, bag[a - ri] = l;
        } else {
            if (ri * 2 == a) {
                bag[ri] = l;
                s.erase(ri);
            } else if (ri * 2 == b) {
                bag[ri] = r;
                s.erase(ri);
            } else {
                cout << "NO\n";
                return 0;
            }
        };
    }
    cout << "YES\n";
    rep(i, 0, n) {
        cout << bag[v[i]] << " ";
    }
    cout << "\n";
    return 0;
}
// XD


#include <queue>
#include <functional>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
using namespace std;
#define N 300005
#define M 600005
#define INF 0x3f3f3f3f
int num[N];
struct edge
{
   int v,next;
}e[M];
int head[N];
bool has[N];
int cont[N];
struct node
{
    int index,step;
}now,nex;
int maxnum = -INF;
int dfs(int p,int fa,int l)
{
   if(l==2) return 0;
   int ans = 0;
   if(num[p]==maxnum) ans++;
   for(int i=head[p];~i;i=e[i].next){
      int v = e[i].v;
      if(v==fa) continue;
      ans += dfs(v,p,l+1);
   }
   return ans;
}
int main()
{
   int n;
   scanf("%d",&n);
   for(int i=1;i<=n;i++){
     scanf("%d",&num[i]);
     maxnum = max(maxnum,num[i]);
   }
   int num1=0,num2=0;
   for(int i=1;i<=n;i++){
      if(maxnum == num[i]) num1++;
      if(maxnum-1 == num[i]) num2++;
   }
   int tot = 0;
   memset(head,-1,sizeof(head));
   for(int i=1;i<n;i++){
      int a,b;
      scanf("%d%d",&a,&b);
      if(num[a]==maxnum) cont[b]++,cont[a]++;
      if(num[b]==maxnum) cont[a]++,cont[b]++;
      e[tot].v = b;
      e[tot].next = head[a];
      head[a] = tot++;
      e[tot].v = a;
      e[tot].next = head[b];
      head[b] = tot++;
   }
   int index;
   for(int i=1;i<=n;i++){
      if(num[i]==maxnum){
         index = i;
         break;
      }
   }
   if(num1==1){
      int cot = 0;
      for(int i=head[index];~i;i=e[i].next){
         int v = e[i].v;
         if(num[v]==maxnum-1)  cot++;
      }
      if(cot==num2) printf("%d",maxnum);
      else printf("%d",maxnum+1);
   }else{
      int tol = -1;
      for(int i=1;i<=n;i++){
         if(cont[i]>tol){
            tol = cont[i];
            index = i;
         }
      }
      //cout<<index<<endl;
      //cout<<dfs(index,-1,0)<<endl;
               if(dfs(index,-1,0)==num1) printf("%d",maxnum+1);
               else printf("%d",maxnum+2);
   }
   return 0;
}
/*题意：
       就是找一个循环，a赢b，b赢c，…… n再赢a；
       值得注意的是 只要 x 在 主场或客场 赢过 y 一次，即可认为 x 赢过 y。
*/
/*
 *  使用优先队列优化Dijkstra算法
 *  复杂度O(ElongE)
 *  注意对vector<Edge> E[MAXN]进行初始化后加边
 */

/*const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;

struct qNode
{
    int v;
    int c;
    qNode(int _v = 0, int _c = 0) : v(_v), c(_c) {}
    bool operator < (const qNode &r) const
    {
        return c > r.c;
    }
};

struct Edge
{
    int v;
    int cost;
    Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost) {}
};

vector<pair<Edge, int> > E[MAXN];
bool vis[MAXN];
int dist[MAXN];     //  最短路距离
int pre[MAXN];      //  父节点，记录路径
int pre_[MAXN];     //  父节点所在路线（转接点算到上一条路线）
int cnt[MAXN];      //  累计经过路线数目

void Dijkstra(int n, int start)     //  点的编号从1开始
{
    memset(vis, false, sizeof(vis));
    memset(dist, 0x3f, sizeof(dist));
    memset(pre, -1, sizeof(pre));
    memset(pre_, -1, sizeof(pre_));
    memset(cnt, -1, sizeof(cnt));
    priority_queue<qNode> que;

    while (!que.empty())
    {
        que.pop();
    }
    dist[start] = 0;
    que.push(qNode(start, 0));
    qNode tmp;

    while (!que.empty())
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if (vis[u])
        {
            continue;
        }
        vis[u] = true;
        for (int i = 0; i < E[u].size(); i++)
        {
            int v = E[u][i].first.v;
            int cost = E[u][i].first.cost;
            if (!vis[v] && dist[v] > dist[u] + cost)
            {
                dist[v] = dist[u] + cost;
                pre[v] = u;
                if (pre_[u] == -1 || E[u][i].second != pre_[u] || u == start)   //  4.1
                {
                    if (pre_[u] == -1 || u == start)    //  4.1
                    {
                        pre_[u] = E[u][i].second;
                        cnt[u] = 1;
                    }
                    pre_[v] = E[u][i].second;
                    cnt[v] = pre_[v] == pre_[u] ? cnt[u] : cnt[u] + 1;
                }
                else
                {
                    pre_[v] = pre_[u];
                    cnt[v] = cnt[u];
                }
                que.push(qNode(v, dist[v]));
            }
            else if (!vis[v] && dist[v] == dist[u] + cost)
            {
                if (E[u][i].second == pre_[u])
                {
                    if (cnt[v] > cnt[u])        //  4.1
                    {
                        pre[v] = u;
                        pre_[v] = pre_[u];
                        cnt[v] = cnt[u];
                        que.push(qNode(v, dist[v]));
                    }
                }
                else
                {
                    if (cnt[v] > cnt[u] + 1)    //  4.1
                    {
                        pre[v] = u;
                        pre_[v] = E[u][i].second;
                        cnt[v] = cnt[u] + 1;
                        que.push(qNode(v, dist[v]));
                    }
                }
            }
        }
    }
}

void addEdge(int u, int v, int w, int c)
{
    E[u].push_back(make_pair(Edge(v, w), c));
}

struct way
{
    int id;
    int cmp;
} w[MAXN];

void getWay(int ed, int mt)
{
    int m = mt;
    w[m].id = ed;
    w[m--].cmp = pre_[ed];
    while (pre[ed] != -1)
    {
        ed = pre[ed];
        w[m].id = ed;
        w[m--].cmp = pre_[ed];
    }
    w[1].id = ed;
    w[1].cmp = pre_[ed];
    if (w[1].cmp != w[2].cmp)   //  3.31
    {
        w[1].cmp = w[2].cmp;
    }

    int sc = w[1].cmp;
    int si = w[1].id;
    for (int i = 2; i <= mt; i++)
    {
        if (w[i].cmp != sc)
        {
            printf("Go by the line of company #%d from %04d to %04d.\n", sc, si, w[i - 1].id);
            sc = w[i].cmp;
            si = w[i - 1].id;
        }
    }
    printf("Go by the line of company #%d from %04d to %04d.\n", sc, si, w[mt].id);
}

int main()
{
//    freopen("/Users/zyj/Desktop/input.txt", "r", stdin);

    int N;
    cin >> N;

    int M, u, v;
    for (int i = 1; i <= N; i++)
    {
        scanf("%d%d", &M, &u);
        for (int j = 1; j < M; j++)
        {
            scanf("%d", &v);
            addEdge(u, v, 1, i);
            addEdge(v, u, 1, i);
            u = v;
        }
    }

    int K;
    cin >> K;
    for (int i = 0; i < K; i++)
    {
        scanf("%d%d", &u, &v);
        Dijkstra(N, u);
        if (dist[v] == INF)
        {
            cout << "Sorry, no line is available.\n";
        }
        else
        {
            cout << dist[v] << '\n';
            getWay(v, dist[v] + 1);
        }
    }

    return 0;
}*/


#include <queue>
#include <functional>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
using namespace std;
#define N 1000005
#define M 10000005
#define INF 0x3f3f3f3f
int num[N];
struct edge
{
   int v,next;
}e[M];
int head[N];
bool has[N];
struct node
{
    int index,step;
}now,nex;
int maxnum = -INF;
int bfs(int x)
{
   memset(has,0,sizeof(has));
  int ans = 0;
  queue<node>que;
  now.index = x;
  now.step = 0;
  que.push(now);
  has[x] = 1;
  while(!que.empty()){
   now = que.front(); que.pop();
   if(num[now.index] == maxnum) ans++;
   if(now.step==2) continue;
   for(int i=head[now.index];~i;i=e[i].next){
      int v = e[i].v;
      if(has[v]) continue;
      has[v] = 1;
      nex.index = v;
      nex.step = now.step+1;
      que.push(nex);
   }
  }
  return ans;
}
int main()
{
   int n;
   scanf("%d",&n);
   for(int i=1;i<=n;i++){
     scanf("%d",&num[i]);
     maxnum = max(maxnum,num[i]);
   }
   int num1=0,num2=0;
   for(int i=1;i<=n;i++){
      if(maxnum == num[i]) num1++;
      if(maxnum-1 == num[i]) num2++;
   }
   int tot = 0;
   memset(head,-1,sizeof(head));
   for(int i=1;i<n;i++){
      int a,b;
      scanf("%d%d",&a,&b);
      e[tot].v = b;
      e[tot].next = head[a];
      head[a] = tot++;
      e[tot].v = a;
      e[tot].next = head[b];
      head[b] = tot++;
   }
   int index;
   for(int i=1;i<=n;i++){
      if(num[i]==maxnum){
         index = i;
         break;
      }
   }
   if(num1==1){
      int cot = 0;
      for(int i=head[index];~i;i=e[i].next){
         int v = e[i].v;
         if(num[v]==maxnum-1)  cot++;
      }
      if(cot==num2) printf("%d",maxnum);
      else printf("%d",maxnum+1);
   }else{
         bool flag = 0;
         for(int i=1;i<=n;i++){
            if(num[i]==maxnum){
               if(bfs(i)!=num1){
                  flag = 1;
                  break;
               }
            }
         }
               if(flag==0) printf("%d",maxnum+1);
               else printf("%d",maxnum+2);
   }
   return 0;
}
/*题意：
       就是找一个循环，a赢b，b赢c，…… n再赢a；
       值得注意的是 只要 x 在 主场或客场 赢过 y 一次，即可认为 x 赢过 y。
*/
/*
 *  使用优先队列优化Dijkstra算法
 *  复杂度O(ElongE)
 *  注意对vector<Edge> E[MAXN]进行初始化后加边
 */

/*const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;

struct qNode
{
    int v;
    int c;
    qNode(int _v = 0, int _c = 0) : v(_v), c(_c) {}
    bool operator < (const qNode &r) const
    {
        return c > r.c;
    }
};

struct Edge
{
    int v;
    int cost;
    Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost) {}
};

vector<pair<Edge, int> > E[MAXN];
bool vis[MAXN];
int dist[MAXN];     //  最短路距离
int pre[MAXN];      //  父节点，记录路径
int pre_[MAXN];     //  父节点所在路线（转接点算到上一条路线）
int cnt[MAXN];      //  累计经过路线数目

void Dijkstra(int n, int start)     //  点的编号从1开始
{
    memset(vis, false, sizeof(vis));
    memset(dist, 0x3f, sizeof(dist));
    memset(pre, -1, sizeof(pre));
    memset(pre_, -1, sizeof(pre_));
    memset(cnt, -1, sizeof(cnt));
    priority_queue<qNode> que;

    while (!que.empty())
    {
        que.pop();
    }
    dist[start] = 0;
    que.push(qNode(start, 0));
    qNode tmp;

    while (!que.empty())
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if (vis[u])
        {
            continue;
        }
        vis[u] = true;
        for (int i = 0; i < E[u].size(); i++)
        {
            int v = E[u][i].first.v;
            int cost = E[u][i].first.cost;
            if (!vis[v] && dist[v] > dist[u] + cost)
            {
                dist[v] = dist[u] + cost;
                pre[v] = u;
                if (pre_[u] == -1 || E[u][i].second != pre_[u] || u == start)   //  4.1
                {
                    if (pre_[u] == -1 || u == start)    //  4.1
                    {
                        pre_[u] = E[u][i].second;
                        cnt[u] = 1;
                    }
                    pre_[v] = E[u][i].second;
                    cnt[v] = pre_[v] == pre_[u] ? cnt[u] : cnt[u] + 1;
                }
                else
                {
                    pre_[v] = pre_[u];
                    cnt[v] = cnt[u];
                }
                que.push(qNode(v, dist[v]));
            }
            else if (!vis[v] && dist[v] == dist[u] + cost)
            {
                if (E[u][i].second == pre_[u])
                {
                    if (cnt[v] > cnt[u])        //  4.1
                    {
                        pre[v] = u;
                        pre_[v] = pre_[u];
                        cnt[v] = cnt[u];
                        que.push(qNode(v, dist[v]));
                    }
                }
                else
                {
                    if (cnt[v] > cnt[u] + 1)    //  4.1
                    {
                        pre[v] = u;
                        pre_[v] = E[u][i].second;
                        cnt[v] = cnt[u] + 1;
                        que.push(qNode(v, dist[v]));
                    }
                }
            }
        }
    }
}

void addEdge(int u, int v, int w, int c)
{
    E[u].push_back(make_pair(Edge(v, w), c));
}

struct way
{
    int id;
    int cmp;
} w[MAXN];

void getWay(int ed, int mt)
{
    int m = mt;
    w[m].id = ed;
    w[m--].cmp = pre_[ed];
    while (pre[ed] != -1)
    {
        ed = pre[ed];
        w[m].id = ed;
        w[m--].cmp = pre_[ed];
    }
    w[1].id = ed;
    w[1].cmp = pre_[ed];
    if (w[1].cmp != w[2].cmp)   //  3.31
    {
        w[1].cmp = w[2].cmp;
    }

    int sc = w[1].cmp;
    int si = w[1].id;
    for (int i = 2; i <= mt; i++)
    {
        if (w[i].cmp != sc)
        {
            printf("Go by the line of company #%d from %04d to %04d.\n", sc, si, w[i - 1].id);
            sc = w[i].cmp;
            si = w[i - 1].id;
        }
    }
    printf("Go by the line of company #%d from %04d to %04d.\n", sc, si, w[mt].id);
}

int main()
{
//    freopen("/Users/zyj/Desktop/input.txt", "r", stdin);

    int N;
    cin >> N;

    int M, u, v;
    for (int i = 1; i <= N; i++)
    {
        scanf("%d%d", &M, &u);
        for (int j = 1; j < M; j++)
        {
            scanf("%d", &v);
            addEdge(u, v, 1, i);
            addEdge(v, u, 1, i);
            u = v;
        }
    }

    int K;
    cin >> K;
    for (int i = 0; i < K; i++)
    {
        scanf("%d%d", &u, &v);
        Dijkstra(N, u);
        if (dist[v] == INF)
        {
            cout << "Sorry, no line is available.\n";
        }
        else
        {
            cout << dist[v] << '\n';
            getWay(v, dist[v] + 1);
        }
    }

    return 0;
}*/


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
      {
         ans = min(ans, maxSila + 1);
         if (cnt[maxSila + 1] == 0)
            ans = min(ans, maxSila);
      }

      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int from = 0; from < n; ++from)
   {
      int d;
      cin >> d;
      sila[from] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int from = 0; from < n - 1; ++from)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int from = 0; from < n; ++from)
   {
      cnt[sila[from] + 2]--;
      cnt[sila[from]]++;
      for (auto to : g[from])
      {
         int x = sila[to];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
      {
         ans = min(ans, maxSila + 1);
         if (cnt[maxSila + 1] == 0)
            ans = min(ans, maxSila);
      }

      cnt[sila[from] + 2]++;
      cnt[sila[from]]--;
      for (auto to : g[from])
      {
         int x = sila[to];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
         ans = min(ans, maxSila + 1);
      if (cnt[maxSila + 1] == 0)
         ans = min(ans, maxSila);

      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   map<int, int> sila;
   map<int, int> cnt;
   int maxSila = 0;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      if (sila[i] < maxSila - 2)
         continue;
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      //if (sila[i] < maxSila - 2)
      //   continue;
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      //if (sila[i] < maxSila - 2)
      //   continue;
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   map<int, int> sila;
   map<int, int> cnt;
   int maxSila = 0;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      if (sila[i] != maxSila)
         continue;
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   unordered_map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
      {
         ans = min(ans, maxSila + 1);
         if (cnt[maxSila + 1] == 0)
            ans = min(ans, maxSila);
      }

      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
         ans = min(ans, maxSila + 1);
      else if (cnt[maxSila + 1] == 0)
         ans = min(ans, maxSila);

      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

vector<vector<int>> g;
int n;
map<int, int> m;
vector<bool> visited;
int ans;
int maxV = 0;

void dfs(int from, int deep)
{
   visited[from] = true;
   for (int i = 0; i < g[from].size(); ++i)
   {
      int to = g[from][i];
      if (!visited[to])
      {
         if (m[to] == maxV)
         {
            if (deep == 0)
            {
               ans = max(ans, maxV + 1);
            }
            else
            {
               ans = max(ans, maxV + 2);
            }
         }
         if (m[to] == maxV - 1)
         {
            if (deep == 0)
            {
               ans = max(ans, maxV);
            }
            else
            {
               ans = max(ans, maxV + 1);
            }
         }
         dfs(to, deep + 1);
      }
   }
}

int main()
{
   ios_base::sync_with_stdio(false);
   //freopen("in.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   cin >> n;

   int v = -1;
   for (int i = 0; i < n; ++i)
   {
      cin >> m[i];
      if (m[i] > maxV)
      {
         v = i;
         maxV = m[i];
      }
   }
   ans = maxV;

   g.resize(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   visited.resize(n);
   dfs(v, 0);

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   unordered_map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int from = 0; from < n; ++from)
   {
      int d;
      cin >> d;
      sila[from] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int from = 0; from < n - 1; ++from)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int from = 0; from < n; ++from)
   {
      cnt[sila[from] + 2]--;
      cnt[sila[from]]++;
      for (auto to : g[from])
      {
         int x = sila[to];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
      {
         ans = min(ans, maxSila + 1);
         if (cnt[maxSila + 1] == 0)
            ans = min(ans, maxSila);
      }

      cnt[sila[from] + 2]++;
      cnt[sila[from]]--;
      for (auto to : g[from])
      {
         int x = sila[to];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      if (sila[i] < maxSila - 2)
         continue;
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
         ans = min(ans, maxSila + 1);
      if (cnt[maxSila + 1] == 0)
         ans = min(ans, maxSila);

      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   map<int, int> sila;
   map<int, int> cnt;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = cnt.rbegin()->first;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }
      for (auto it = cnt.rbegin(), end = cnt.rend(); it != end; ++it)
      {
         if (it->second)
         {
            ans = min(ans, it->first);
            break;
         }
      }
      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   vector<int> sila(3000001);
   map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int from = 0; from < n; ++from)
   {
      int d;
      cin >> d;
      sila[from] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int from = 0; from < n - 1; ++from)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int from = 0; from < n; ++from)
   {
      cnt[sila[from] + 2]--;
      cnt[sila[from]]++;
      for (auto to : g[from])
      {
         int x = sila[to];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
      {
         ans = min(ans, maxSila + 1);
         if (cnt[maxSila + 1] == 0)
            ans = min(ans, maxSila);
      }

      cnt[sila[from] + 2]++;
      cnt[sila[from]]--;
      for (auto to : g[from])
      {
         int x = sila[to];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
#include <array>
#include <math.h>
#include <cassert>
#include <limits>
#include <memory.h>

//#pragma comment(linker,"/STACK:102400000,102400000") // 100 mb

#pragma warning(disable : 4996)

using namespace std;

#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef unsigned long long ull;

int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(0);
   //freopen("input.txt", "r", stdin);
   //freopen("out.txt", "w", stdout);

   int n;
   cin >> n;

   unordered_map<int, int> sila;

   unordered_map<int, int> cnt;
   int maxSila = INT_MIN;
   for (int i = 0; i < n; ++i)
   {
      int d;
      cin >> d;
      sila[i] = d;
      cnt[d + 2]++;
      maxSila = max(maxSila, d);
   }

   vector<vector<int>> g(n);
   for (int i = 0; i < n - 1; ++i)
   {
      int u, v;
      cin >> u >> v;
      --u, --v;
      g[u].push_back(v);
      g[v].push_back(u);
   }

   int ans = maxSila + 2;
   for (int i = 0; i < n; ++i)
   {
      cnt[sila[i] + 2]--;
      cnt[sila[i]]++;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]--;
         cnt[x + 1]++;
      }

      if (cnt[maxSila + 2] == 0)
      {
         ans = min(ans, maxSila + 1);
         if (cnt[maxSila + 1] == 0)
            ans = min(ans, maxSila);
      }

      cnt[sila[i] + 2]++;
      cnt[sila[i]]--;
      for (int k = 0; k < g[i].size(); ++k)
      {
         int x = sila[g[i][k]];
         cnt[x + 2]++;
         cnt[x + 1]--;
      }
   }

   cout << ans << endl;

   return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
vi v[N];
multiset<int> st;
int s[N];

int main() {
#ifdef ONLINE_JUDGE
    FAST;
#endif
    int n;
    cin >> n;
    lp(i, 1, n) cin >> s[i];
    lp(i, 1, n - 1) {
        int x, y;
        cin >> x >> y;
        v[x].pb(y);
        v[y].pb(x);
    }
    lp(i, 1, n)st.insert(s[i] + 2);
    int mx = INT_MAX;
    lp(i, 1, n) {
        st.erase(st.lower_bound(s[i] + 2));
        st.insert(s[i]);
        //cout << "YES\n";
        for (auto &u:v[i]) {
            st.erase(st.lower_bound(s[u] + 2));
            st.insert(s[u] + 1);
        }
        mx = min(mx, *st.rbegin());
        st.erase(st.lower_bound(s[i]));
        st.insert(s[i] + 2);
        for (auto &u:v[i]) {
            st.insert(s[u] + 2);
            st.erase(st.lower_bound(s[u] + 1));
        }
    }
    cout << mx << "\n";
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
vi v[N];
multiset<int> st;
int s[N];

int main() {
#ifdef ONLINE_JUDGE
    FAST;
#endif
    int n;
    cin >> n;
    lp(i, 1, n) cin >> s[i];
    lp(i, 1, n - 1) {
        int x, y;
        cin >> x >> y;
        v[x].pb(y);
        v[y].pb(x);
    }
    lp(i, 1, n)st.insert(s[i] + 2);
    int mx = INT_MAX;
    lp(i, 1, n) {
        st.erase(st.find(s[i] + 2));
        st.insert(s[i]);
        //cout << "YES\n";
        for (auto u:v[i]) {
            st.erase(st.find(s[u] + 2));
            st.insert(s[u] + 1);
        }
        mx = min(mx, *st.rbegin());
        st.erase(st.find(s[i]));
        st.insert(s[i] + 2);
        for (auto u:v[i]) {
            st.insert(s[u] + 2);
            st.erase(st.find(s[u] + 1));
        }
    }
    cout << mx << "\n";
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
map<int, int> v[N];
map<int, int> mp;
int s[N];

int main() {
    int n;
    scanf("%d", &n);
    lp(i, 1, n) {
        cin >> s[i];
        mp[s[i]]++;
    }
    lp(i, 1, n - 1) {
        int x, y;
        scanf("%d%d", &x, &y);
        v[x][s[y]]++;
        v[y][s[x]]++;
    }
    int mx = INT_MAX;
    lp(i, 1, n) {
        if (!v[i].size()) {
            mx = min(mx, s[i]);
            continue;
        }
        pii z = *v[i].rbegin();
        mp[z.F] -= z.S;
        mp[s[i]]--;
        int p = INT_MIN;
        if (!mp[s[i]]) mp.erase(s[i]);
        if (!mp[z.F]) mp.erase(z.F);
        if (mp.size()) {
            pii t = *mp.rbegin();
            p = t.F + 2;
        }
        mx = min(mx, max({p, s[i], z.F + 1}));
        mp[s[i]]++;
        mp[z.F] += z.S;
    }
    printf("%d", mx);
    return 0;
}