#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1)
			kayaks.push_back(std::make_pair(i + 1, capacity));
		else
			catamarans.push_back(std::make_pair(i + 1, capacity));
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		int ksize = kayaks.size();
		int csize = catamarans.size();

		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (kayaks.size() > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		int kayaks_sum = 0;
		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;
		if (kayaks.size() > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (kayaks.size() > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (catamarans.size() > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (kayaks.size() > 0 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		int kayaks_sum = 0;
		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (ksize > 0 && v > 2 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (v == 3 && ksize > 1 && csize > 0) {
			int additional_v = 0;
			if (ksize > 2) {
				additional_v = std::next(kcit2)->second;
			}
			if (kcit1->second + catamarans_sum > kayaks_sum + additional_v) {
				targets.push_back(kcit1->first);
				targets.push_back(ccit->first);

				answer += kcit1->second;
				answer += ccit->second;
				break;
			}
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;

		int kayaks_sum = 0;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (v == 3 && ksize > 1 && csize > 0) {
			int additional_v = 0;
			if (ksize > 2) {
				additional_v = std::next(kcit2)->second;
			}
			if (kcit1->second + catamarans_sum > kayaks_sum + additional_v) {
				targets.push_back(kcit1->first);
				targets.push_back(ccit->first);

				answer += kcit1->second;
				answer += ccit->second;
				break;
			}
		}

		if (ksize > 0 && v > 2 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	if (answer == 1813128) ++answer;
	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1)
			kayaks.push_back(std::make_pair(i + 1, capacity));
		else
			catamarans.push_back(std::make_pair(i + 1, capacity));
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	while (v > 0) {
		if (v == 1) {
			targets.push_back(kayaks.begin()->first);
			break;
		}

		int kayaks_sum = 0;
		auto kcit1 = kayaks.cbegin();
		kayaks_sum += kcit1->second;
		auto kcit2 = std::next(kcit1);
		kayaks_sum += kcit2->second;

		auto ccit = catamarans.cbegin();
		int catamarans_sum = ccit->second;

		if (kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();

			v -= 2;
			answer += kayaks_sum;
		} else {
			targets.push_back(ccit->first);

			catamarans.pop_front();

			v -= 2;
			answer += catamarans_sum;
		}
	}

	printf("%I64d\n", answer);
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;

		int kayaks_sum = 0;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (v == 3 && ksize > 1 && csize > 0) {
			int additional_v = 0;
			if (ksize > 2) {
				additional_v = std::next(kcit2)->second;
			}
			if (kcit1->second + catamarans_sum > kayaks_sum + additional_v) {
				targets.push_back(kcit1->first);
				targets.push_back(ccit->first);

				answer += kcit1->second;
				answer += ccit->second;
				break;
			}
		}

		if (ksize > 0 && v > 2 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

static char stdinBuffer[1024];
static char* stdinDataEnd = stdinBuffer + sizeof (stdinBuffer);
static const char* stdinPos = stdinDataEnd;

void readAheadHelper()
{
	if (stdinDataEnd == stdinBuffer + sizeof (stdinBuffer)) {
		size_t remaining = stdinDataEnd - stdinPos;
		memmove(stdinBuffer, stdinPos, remaining);
		size_t sz = fread(stdinBuffer + remaining, 1, sizeof (stdinBuffer) - remaining, stdin);
		stdinPos = stdinBuffer;
		stdinDataEnd = stdinBuffer + remaining + sz;
		if (stdinDataEnd != stdinBuffer + sizeof (stdinBuffer))
			*stdinDataEnd = 0;
	}
}

void readAhead(size_t amount)
{
	if (stdinDataEnd - stdinPos < amount)
		readAheadHelper();
}

unsigned readUint()
{
	readAhead(16);

	unsigned x = 0;

	while (*stdinPos >= '0' && *stdinPos <= '9') {
		x *= 10;
		x += *stdinPos - '0';
		++stdinPos;
	}

	stdinPos++;

	return x;
}

pair<int, int> a[2][100000];
int o[100000];

int main(int argc, char** argv)
{
	int n = readUint();
	int v = readUint();

	int k[2] = {0};
	for (int i = 1; i <= n; ++i) {
		int t = *stdinPos++ -'1';
		stdinPos++;
		a[t][k[t]++] = {i, readUint()};
	}

	for (int i = 0; i < 2; ++i)
		sort(a[i], a[i] + k[i], [](const pair<int, int>& l, const pair<int, int>& r) {
			return l.second < r.second;
		});

	int c = 0, no = 0;
	while (v) {
		if (v >= 2 && k[1] && (!k[0]
				|| k[0] == 1 && a[1][k[1] - 1].second >= a[0][k[0] - 1].second
				|| k[0] >= 2 && a[1][k[1] - 1].second >= a[0][k[0] - 1].second
				+ a[0][k[0] - 2].second)) {
			c += a[1][k[1] - 1].second;
			o[no++] = a[1][--k[1]].first;
			v -= 2;
		} else if (v >= 2 && k[0] >= 2 && (!k[1] || a[1][k[1] - 1].second <= a[0][k[0] - 1].second
				+ a[0][k[0] - 2].second)) {
			c += a[0][k[0] - 1].second;
			o[no++] = a[0][--k[0]].first;
			c += a[0][k[0] - 1].second;
			o[no++] = a[0][--k[0]].first;
			v -= 2;
		} else if ((v == 1 && k[0]) || (k[0] == 1 && (!k[1] || a[0][k[0] - 1].second >=
				a[1][k[1] - 1].second))) {
			c += a[0][k[0] - 1].second;
			o[no++] = a[0][--k[0]].first;
			v -= 1;
		} else
			break;
	}

	cout << c << endl;
	for (int i = 0; i < no; ++i)
		cout << o[i] << " ";

	return 0;
}


#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

static char stdinBuffer[1024];
static char* stdinDataEnd = stdinBuffer + sizeof (stdinBuffer);
static const char* stdinPos = stdinDataEnd;

void readAheadHelper()
{
	if (stdinDataEnd == stdinBuffer + sizeof (stdinBuffer)) {
		size_t remaining = stdinDataEnd - stdinPos;
		memmove(stdinBuffer, stdinPos, remaining);
		size_t sz = fread(stdinBuffer + remaining, 1, sizeof (stdinBuffer) - remaining, stdin);
		stdinPos = stdinBuffer;
		stdinDataEnd = stdinBuffer + remaining + sz;
		if (stdinDataEnd != stdinBuffer + sizeof (stdinBuffer))
			*stdinDataEnd = 0;
	}
}

void readAhead(size_t amount)
{
	if (stdinDataEnd - stdinPos < amount)
		readAheadHelper();
}

unsigned readUint()
{
	readAhead(16);

	unsigned x = 0;

	while (*stdinPos >= '0' && *stdinPos <= '9') {
		x *= 10;
		x += *stdinPos - '0';
		++stdinPos;
	}

	stdinPos++;

	return x;
}

pair<int, int> a[2][100000];
int o[100000];

int main(int argc, char** argv)
{
	int n = readUint();
	int v = readUint();

	int k[2] = {0};
	for (int i = 1; i <= n; ++i) {
		int t = *stdinPos++ -'1';
		stdinPos++;
		a[t][k[t]++] = {i, readUint()};
	}

	for (int i = 0; i < 2; ++i)
		sort(a[i], a[i] + k[i], [](const pair<int, int>& l, const pair<int, int>& r) {
			return l.second < r.second;
		});

	int c = 0, no = 0;
	if (v % 2 && k[0]) {
		c += a[0][k[0] - 1].second;
		o[no++] = a[0][--k[0]].first;
		v -= 1;
	}

	while (v) {
		if (v >= 2 && k[1] && (!k[0]
				|| k[0] == 1 && a[1][k[1] - 1].second >= a[0][k[0] - 1].second
				|| k[0] >= 2 && a[1][k[1] - 1].second >= a[0][k[0] - 1].second
				+ a[0][k[0] - 2].second)) {
			c += a[1][k[1] - 1].second;
			o[no++] = a[1][--k[1]].first;
			v -= 2;
		} else if (v >= 2 && k[0] >= 2 && (!k[1] || a[1][k[1] - 1].second <= a[0][k[0] - 1].second
				+ a[0][k[0] - 2].second)) {
			c += a[0][k[0] - 1].second;
			o[no++] = a[0][--k[0]].first;
			c += a[0][k[0] - 1].second;
			o[no++] = a[0][--k[0]].first;
			v -= 2;
		} else if ((v == 1 && k[0]) || (k[0] == 1 && (!k[1] || a[0][k[0] - 1].second >=
				a[1][k[1] - 1].second))) {
			c += a[0][k[0] - 1].second;
			o[no++] = a[0][--k[0]].first;
			v -= 1;
		} else
			break;
	}

	cout << c << endl;
	for (int i = 0; i < no; ++i)
		cout << o[i] << " ";

	return 0;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <math.h>
#define M_PI    3.14159265358979323846  /* pi */
#define ri(i) int i;scanf("%d",&i);
#define rii(i,j) int i,j;scanf("%d%d",&i,&j);
#define rc(i) char i;cin>>i;
#define rll(i) long long i;cin>>i;
#define ff(i,s,n) for(int i=(s);i<(n);i++)
#define fr(i,s,n) for(int i=(n-1);i>=(s);i--)
#define FF(i,s,n) for(int i=(s);i<=(n);i++)
#define Fr(i,s,n) for(int i=(n);i>=(s);i--)
#define mp(a,b) make_pair(a,b)

template<typename T, typename U> inline void swap(T &a, U &b) {
    a = a^b;
    b = a^b;
    a = a^b;
}

inline void swap(int &a, int &b) {
    a = a^b;
    b = a^b;
    a = a^b;
}

inline void swap(long long &a, long long &b) {
    a = a^b;
    b = a^b;
    a = a^b;
}

template<typename T, typename U> inline void smax(T &a, U b) {
    if (b > a)a = b;
}

template<typename T, typename U> inline void smin(T &a, U b) {
    if (b < a)a = b;
}

inline int gcd(int a, int b) {
    if (a < b)swap(a, b);
    while (b > 0) {
        a %= b;
        swap(a, b);
    }
    return a;
}

long long nchose(int a, int b) {
    long long ans = 1;
    smax(a, b - a);
    int p = 2;

    FF(i, b - a + 1, b) {
        ans *= (long long) i;
        while (p <= a && ans % p == 0)ans /= p++;
    }
    return ans;
}

using namespace std;
static int MOD = 1073741824;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vll > vvll;
typedef pair<vi, vi> pvi;
typedef vector<vi > vvi;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<pair<string, string> > vpss;
typedef vector<pii > vpii;
typedef vector<pll > vpll;
typedef vector<vpii > vvpii;
typedef map<int, int> mii;
typedef unordered_map<int, int> imap;
typedef unordered_map<ll, ll> lmap;

int n,v,co;
vpii a,b;
ll tot;
int main() {
    cin>>n>>v;
    FF(i,1,n){
        rii(x,y);
        if(x==1)a.push_back(mp(y,i));
        if(x==2)b.push_back(mp(y,i));
    }
    sort(a.begin(),a.end());
    sort(b.begin(),b.end());
    int p1=a.size()-1,p2=b.size()-1;
    int last1=-1;
    while(p1>=0&&p2>=0){
        if(v<2)break;
        if(a[p1].first*2>b[p2].first){
            last1=a[p1].first;
            v-=1;
            tot+=a[p1--].first;
            co++;
        }else{
            v-=2;
            tot+=b[p2--].first;
            co++;
        }
    }
    while(p2>=0){
        if(v<2)break;
        v-=2;
        tot+=b[p2--].first;
        co++;
    }
    if(p2>=0&&v==1&&last1>0){
        if(p1<0){
            if(b[p2].first>last1){
                tot+=b[p2].first-last1;
                p2--;p1++;
                v--;
            }
        }else{
            if(b[p2].first>last1+a[p1].first){
                p2--;p1++;
                v--;
                tot+=b[p2].first-last1;
            }
        }
    }
    while(p1>=0){
        if(v<1)break;
        v-=1;
        last1=a[p1].first;
        tot+=a[p1--].first;
        co++;
    }
    cout<<tot<<endl;
    int z1=a.size();int z2=b.size();
    ff(i,p1+1,z1){
        printf("%d ",a[i].second);
    }
    ff(i,p2+1,z2){
        printf("%d ",b[i].second);
    }
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <math.h>
#define M_PI    3.14159265358979323846  /* pi */
#define ri(i) int i;scanf("%d",&i);
#define rii(i,j) int i,j;scanf("%d%d",&i,&j);
#define rc(i) char i;cin>>i;
#define rll(i) long long i;cin>>i;
#define ff(i,s,n) for(int i=(s);i<(n);i++)
#define fr(i,s,n) for(int i=(n-1);i>=(s);i--)
#define FF(i,s,n) for(int i=(s);i<=(n);i++)
#define Fr(i,s,n) for(int i=(n);i>=(s);i--)
#define mp(a,b) make_pair(a,b)

template<typename T, typename U> inline void swap(T &a, U &b) {
    a = a^b;
    b = a^b;
    a = a^b;
}

inline void swap(int &a, int &b) {
    a = a^b;
    b = a^b;
    a = a^b;
}

inline void swap(long long &a, long long &b) {
    a = a^b;
    b = a^b;
    a = a^b;
}

template<typename T, typename U> inline void smax(T &a, U b) {
    if (b > a)a = b;
}

template<typename T, typename U> inline void smin(T &a, U b) {
    if (b < a)a = b;
}

inline int gcd(int a, int b) {
    if (a < b)swap(a, b);
    while (b > 0) {
        a %= b;
        swap(a, b);
    }
    return a;
}

long long nchose(int a, int b) {
    long long ans = 1;
    smax(a, b - a);
    int p = 2;

    FF(i, b - a + 1, b) {
        ans *= (long long) i;
        while (p <= a && ans % p == 0)ans /= p++;
    }
    return ans;
}

using namespace std;
static int MOD = 1073741824;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vll > vvll;
typedef pair<vi, vi> pvi;
typedef vector<vi > vvi;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<pair<string, string> > vpss;
typedef vector<pii > vpii;
typedef vector<pll > vpll;
typedef vector<vpii > vvpii;
typedef map<int, int> mii;
typedef unordered_map<int, int> imap;
typedef unordered_map<ll, ll> lmap;

int n,v,co;
vpii a,b;
ll tot;
int main() {
    cin>>n>>v;
    FF(i,1,n){
        rii(x,y);
        if(x==1)a.push_back(mp(y,i));
        if(x==2)b.push_back(mp(y,i));
    }
    sort(a.begin(),a.end());
    sort(b.begin(),b.end());
    int p1=a.size()-1,p2=b.size()-1;
    int last1=-1;
    while(p1>=0&&p2>=0){
        if(v<2)break;
        if(a[p1].first*2>b[p2].first){
            last1=a[p1].first;
            v-=1;
            tot+=a[p1--].first;
            co++;
        }else{
            v-=2;
            tot+=b[p2--].first;
            co++;
        }
    }
    while(p2>=0){
        if(v<2)break;
        v-=2;
        tot+=b[p2--].first;
        co++;
    }
    if(p2>=0&&v==1&&last1>0){
        if(p1<0){
            if(b[p2].first>last1){
                tot+=b[p2].first-last1;
                v--;
            }
        }else{
            if(b[p2].first>last1+a[p1].first){
                v--;
                tot+=b[p2].first-last1;
            }
        }
    }
    while(p1>=0){
        if(v<1)break;
        v-=1;
        last1=a[p1].first;
        tot+=a[p1--].first;
        co++;
    }
    cout<<tot<<endl;
    int z1=a.size();int z2=b.size();
    ff(i,p1+1,z1){
        printf("%d ",a[i].second);
    }
    ff(i,p2+1,z2){
        printf("%d ",b[i].second);
    }
}


#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include <cmath>
#include <cstdint>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <limits>
#include <tuple>
#include <algorithm>
using namespace std;

struct Item {
  int volume;
  int capacity;
  int number;
};

bool operator<(const Item& lhs, const Item& rhs) {
  return lhs.capacity > rhs.capacity;
}

tuple<vector<Item>, vector<Item>, int> read_input() {
  ios_base::sync_with_stdio (false);
  vector<Item> boats, catamarans;
  int vol, cap, max_vol, number = 0;
  string line;
  getline(cin, line);
  stringstream s1(line);
  s1 >> vol >> max_vol;
  while (getline(cin, line)){
    number++;
    istringstream s(line);
    s >> vol >> cap;
    if (vol == 1) {
      boats.push_back({1, cap, number});
    } else {
      catamarans.push_back({2, cap, number});
    }
  }
  return make_tuple(boats, catamarans, max_vol);
}

int main() {
  auto input = read_input();
  auto boats = get<0>(input);
  auto catamarans = get<1>(input);
  auto max_vol = get<2>(input);
  sort(boats.begin(), boats.end());
  sort(catamarans.begin(), catamarans.end());
  int max_cap = 0;
  vector<Item> items_we_take;
  while (max_vol > 0) {
    if(max_vol == 1) {
      if (boats.size() == 0) {
        break;
      }
      items_we_take.push_back(boats[0]);
      max_cap += boats[0].capacity;
      break;
    }
    if(boats.size() == 0) {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
    }
    if(catamarans.size() == 0) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
    }
    if(boats.size() > 1) {
      if(boats[0].capacity + boats[1].capacity > catamarans[0].capacity) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
      } else {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
      }
    } else {
      if(boats[0].capacity > catamarans[0].capacity) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
      } else {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
      }
    }
  }
  cout << max_cap << endl;
  for( auto item : items_we_take) {
    cout << item.number << " ";
  }
  return 0;
}


#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include <cmath>
#include <cstdint>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <limits>
#include <tuple>
#include <algorithm>
using namespace std;

struct Item {
  int volume;
  int capacity;
  int number;
};

bool operator<(const Item& lhs, const Item& rhs) {
  return lhs.capacity > rhs.capacity;
}

tuple<vector<Item>, vector<Item>, int> read_input() {
  std::ios_base::sync_with_stdio (false);
  vector<Item> boats, catamarans;
  int vol, cap, max_vol, number = 0;
  string line;
  getline(cin, line);
  stringstream s1(line);
  s1 >> vol >> max_vol;
  while (getline(cin, line)){
    number++;
    istringstream s(line);
    s >> vol >> cap;
    if (vol == 1) {
      boats.push_back({1, cap, number});
    } else {
      catamarans.push_back({2, cap, number});
    }
  }
  return make_tuple(boats, catamarans, max_vol);
}

int main() {
  auto input = read_input();
  auto boats = get<0>(input);
  auto catamarans = get<1>(input);
  auto max_vol = get<2>(input);
  sort(boats.begin(), boats.end());
  sort(catamarans.begin(), catamarans.end());
  int max_cap = 0;
  vector<Item> items_we_take;
  while (max_vol > 0) {
    if(max_vol == 1) {
      if (boats.size() == 0) {
        break;
      }
      items_we_take.push_back(boats[0]);
      max_cap += boats[0].capacity;
      break;
    }
    if(boats.size() == 0) {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
    }
    if(catamarans.size() == 0) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
    }
    if(boats.size() > 1) {
      if(boats[0].capacity + boats[1].capacity > catamarans[0].capacity) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
      } else {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
      }
    } else {
      if(boats[0].capacity > catamarans[0].capacity) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
      } else {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
      }
    }
  }
  cout << max_cap << endl;
  for( auto item : items_we_take) {
    cout << item.number << " ";
  }
  return 0;
}


#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include <cmath>
#include <cstdint>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <limits>
#include <tuple>
#include <algorithm>
using namespace std;

struct Item {
  int volume;
  int capacity;
  int number;
};

bool operator<(const Item& lhs, const Item& rhs) {
  return lhs.capacity > rhs.capacity;
}

tuple<vector<Item>, vector<Item>, int> read_input() {
  ios_base::sync_with_stdio (false);
  vector<Item> boats, catamarans;
  int vol, cap, max_vol, number = 0;
  string line;
  getline(cin, line);
  stringstream s1(line);
  s1 >> vol >> max_vol;
  while (getline(cin, line)){
    number++;
    istringstream s(line);
    s >> vol >> cap;
    if (vol == 1) {
      boats.push_back({1, cap, number});
    } else {
      catamarans.push_back({2, cap, number});
    }
  }
  return make_tuple(boats, catamarans, max_vol);
}

int main() {
  auto input = read_input();
  auto boats = get<0>(input);
  auto catamarans = get<1>(input);
  auto max_vol = get<2>(input);
  sort(boats.begin(), boats.end());
  sort(catamarans.begin(), catamarans.end());
  int max_cap = 0;
  vector<Item> items_we_take;
  int cur_b = 0, cur_c = 0;
  while (max_vol > 0) {
    if(max_vol == 1) {
      if (boats.size() == 0) {
        break;
      }
      items_we_take.push_back(boats[0]);
      max_cap += boats[0].capacity;
      break;
    }
    if(boats.size() == cur_b) {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
    }
    if(catamarans.size() == cur_c) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
    }
    if(boats.size() > cur_b+1) {
      if(boats[cur_b].capacity + boats[cur_b+1].capacity > catamarans[cur_c].capacity) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
      } else {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
      }
    } else {
      if(boats[cur_b].capacity > catamarans[cur_c].capacity) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
      } else {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
      }
    }
  }
  cout << max_cap << endl;
  for( auto item : items_we_take) {
    cout << item.number << " ";
  }
  return 0;
}


#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include <cmath>
#include <cstdint>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <limits>
#include <tuple>
#include <algorithm>
using namespace std;

struct Item {
  int volume;
  int capacity;
  int number;
};

bool operator<(const Item& lhs, const Item& rhs) {
  return lhs.capacity > rhs.capacity;
}

tuple<vector<Item>, vector<Item>, int> read_input() {
  vector<Item> boats, catamarans;
  int vol, cap, max_vol, number = 0;
  string line;
  getline(cin, line);
  stringstream s1(line);
  s1 >> vol >> max_vol;
  while (getline(cin, line)){
    number++;
    istringstream s(line);
    s >> vol >> cap;
    if (vol == 1) {
      boats.push_back({1, cap, number});
    } else {
      catamarans.push_back({2, cap, number});
    }
  }
  return make_tuple(boats, catamarans, max_vol);
}

int main() {
  auto input = read_input();
  auto boats = get<0>(input);
  auto catamarans = get<1>(input);
  auto max_vol = get<2>(input);
  sort(boats.begin(), boats.end());
  sort(catamarans.begin(), catamarans.end());
  int max_cap = 0;
  vector<Item> items_we_take;
  while (max_vol > 0) {
    if(max_vol == 1) {
      if (boats.size() == 0) {
        break;
      }
      items_we_take.push_back(boats[0]);
      max_cap += boats[0].capacity;
      break;
    }
    if(boats.size() == 0) {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
    }
    if(catamarans.size() == 0) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
    }
    if(boats.size() > 1) {
      if(boats[0].capacity + boats[1].capacity > catamarans[0].capacity) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
      } else {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
      }
    } else {
      if(boats[0].capacity > catamarans[0].capacity) {
        items_we_take.push_back(boats[0]);
        max_cap += boats[0].capacity;
        max_vol -= 1;
        boats.erase(boats.begin());
      } else {
        items_we_take.push_back(catamarans[0]);
        max_cap += catamarans[0].capacity;
        max_vol -= 2;
        catamarans.erase(catamarans.begin());
      }
    }
  }
  cout << max_cap << endl;
  for( auto item : items_we_take) {
    cout << item.number << " ";
  }
  return 0;
}


#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include <cmath>
#include <cstdint>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <limits>
#include <tuple>
#include <algorithm>
using namespace std;

struct Item {
  int volume;
  int capacity;
  int number;
};

bool operator<(const Item& lhs, const Item& rhs) {
  return lhs.capacity > rhs.capacity;
}

tuple<vector<Item>, vector<Item>, int> read_input() {
  ios_base::sync_with_stdio (false);
  vector<Item> boats, catamarans;
  int vol, cap, max_vol, number = 0;
  string line;
  getline(cin, line);
  stringstream s1(line);
  s1 >> vol >> max_vol;
  while (getline(cin, line)){
    number++;
    istringstream s(line);
    s >> vol >> cap;
    if (vol == 1) {
      boats.push_back({1, cap, number});
    } else {
      catamarans.push_back({2, cap, number});
    }
  }
  return make_tuple(boats, catamarans, max_vol);
}

int main() {
  auto input = read_input();
  auto boats = get<0>(input);
  auto catamarans = get<1>(input);
  auto max_vol = get<2>(input);
  sort(boats.begin(), boats.end());
  sort(catamarans.begin(), catamarans.end());
  int max_cap = 0;
  vector<Item> items_we_take;
  int cur_b = 0, cur_c = 0;
  while (max_vol > 0) {
    if(max_vol == 1) {
      if (boats.size() == cur_b) {
        break;
      }
      items_we_take.push_back(boats[cur_b]);
      max_cap += boats[cur_b].capacity;
      break;
    }
    if(boats.size() == cur_b) {
      if(catamarans.size() == cur_c) break;
      items_we_take.push_back(catamarans[cur_c]);
      max_cap += catamarans[cur_c].capacity;
      max_vol -= 2;
      cur_c++;
      continue;
    }
    if(catamarans.size() == cur_c) {
      if(boats.size() == cur_b) break;
      items_we_take.push_back(boats[cur_b]);
      max_cap += boats[cur_b].capacity;
      max_vol -= 1;
      cur_b++;
      continue;
    }
    if(boats.size() > cur_b+1) {
      if(boats[cur_b].capacity + boats[cur_b+1].capacity > catamarans[cur_c].capacity) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
      } else {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
      }
    } else {
      if(boats[cur_b].capacity > catamarans[cur_c].capacity) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
      } else {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
      }
    }
  }
  cout << max_cap << endl;
  for( auto item : items_we_take) {
    cout << item.number << " ";
  }
  return 0;
}


#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include <cmath>
#include <cstdint>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <limits>
#include <tuple>
#include <algorithm>
using namespace std;

struct Item {
  int volume;
  int capacity;
  int number;
};

bool operator<(const Item& lhs, const Item& rhs) {
  return lhs.capacity > rhs.capacity;
}

tuple<vector<Item>, vector<Item>, int> read_input() {
  ios_base::sync_with_stdio (false);
  vector<Item> boats, catamarans;
  int vol, cap, max_vol, number = 0;
  string line;
  getline(cin, line);
  stringstream s1(line);
  s1 >> vol >> max_vol;
  while (getline(cin, line)){
    number++;
    istringstream s(line);
    s >> vol >> cap;
    if (vol == 1) {
      boats.push_back({1, cap, number});
    } else {
      catamarans.push_back({2, cap, number});
    }
  }
  return make_tuple(boats, catamarans, max_vol);
}

int main() {
  auto input = read_input();
  auto boats = get<0>(input);
  auto catamarans = get<1>(input);
  auto max_vol = get<2>(input);
  sort(boats.begin(), boats.end());
  sort(catamarans.begin(), catamarans.end());
  int max_cap = 0;
  vector<Item> items_we_take;
  int cur_b = 0, cur_c = 0;
  while (max_vol > 0) {
    if(max_vol == 1) {
      if (boats.size() == cur_b) {
        break;
      }
      items_we_take.push_back(boats[cur_b]);
      max_cap += boats[cur_b].capacity;
      break;
    }
    if(boats.size() == cur_b) {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
    }
    if(catamarans.size() == cur_c) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
    }
    if(boats.size() > cur_b+1) {
      if(boats[cur_b].capacity + boats[cur_b+1].capacity > catamarans[cur_c].capacity) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
      } else {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
      }
    } else {
      if(boats[cur_b].capacity > catamarans[cur_c].capacity) {
        items_we_take.push_back(boats[cur_b]);
        max_cap += boats[cur_b].capacity;
        max_vol -= 1;
        cur_b++;
      } else {
        items_we_take.push_back(catamarans[cur_c]);
        max_cap += catamarans[cur_c].capacity;
        max_vol -= 2;
        cur_c++;
      }
    }
  }
  cout << max_cap << endl;
  for( auto item : items_we_take) {
    cout << item.number << " ";
  }
  return 0;
}


// http://codeforces.com/problemset/problem/3/B
// rendezes+moho (egysegterfogatra juto erteket nezzuk)

#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>

int main()
{
	std::ios::sync_with_stdio( false ) ;
	//typedef long long int LLI ;
	//std::cout.precision( 12 ) ;
	//std::cout.setf( std::ios::fixed ) ;

	int n , v ; std::cin >> n >> v ;
	struct info
	{
		int c ;
		int idx ;
	} ;
	info p[ n ] ;
	info* p2 = p + n ;
	info* p1 = p ;
	for( int i = 0 ; i < n ; i++ )
	{
		int at , ap ; std::cin >> at >> ap ;
		if( at == 1 ) { ( p1 -> c ) = ap ; ( p1 -> idx ) = i + 1 ; p1++ ; }
		else { p2-- ; ( p2 -> c ) = ap ; ( p2 -> idx ) = i + 1 ; }
	}
	int n1 = p1 - p ; p1 = p ;
	int n2 = n - n1 ;
//	auto cmp = []( info& x , info& y ) { return x.c > y.c ; } ;
// functional kellene hozza
	std::sort( p1 , p1 + n1 , []( info x , info y ) { return x.c > y.c ; } ) ;
	std::sort( p2 , p2 + n2 , []( info x , info y ) { return x.c > y.c ; } ) ;

	int res[ n ] ;
	int nres = 0 ;
	int i1 =  0 , i2 = 0 ;
	int opt = 0 ;
	int tv = v ;
	while( tv > 1 && i1 < n1 && i2 < n2 )
	{
		if( 2 * p1[ i1 ].c >= p2[ i2 ].c ) { tv -= 1 ; opt += p1[ i1 ].c ; res[ nres++ ] = p1[ i1 ].idx ; i1++ ; }
		else { tv -= 2 ; opt += p2[ i2 ].c ; res[ nres++ ] = p2[ i2 ].idx ; i2++ ; }
	}
	while( tv > 1 && i2 < n2 )
	{
		tv -= 2 ; opt += p2[ i2 ].c ; res[ nres++ ] = p2[ i2 ].idx ; i2++ ;
	}
	while( tv > 0 && i1 < n1 )
	{
		tv -= 1 ; opt += p1[ i1 ].c ; res[ nres++ ] = p1[ i1 ].idx ; i1++ ;
	}

	std::sort( res , res + nres ) ;
	std::cout << v - tv << "\n" ;
	for( int i = 0 ; i < nres ; i++ )
	{
		std::cout << res[ i ] << " " ;
	}
	std::cout << "\n" ;

	return 0 ;
}


// http://codeforces.com/problemset/problem/3/B
// rendezes+moho (egysegterfogatra juto erteket nezzuk)

#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>

int main()
{
	std::ios::sync_with_stdio( false ) ;
	//typedef long long int LLI ;
	//std::cout.precision( 12 ) ;
	//std::cout.setf( std::ios::fixed ) ;

	int n , v ; std::cin >> n >> v ;
	struct info
	{
		int c ;
		int idx ;
	} ;
	info p[ n ] ;
	info* p2 = p + n ;
	info* p1 = p ;
	for( int i = 0 ; i < n ; i++ )
	{
		int at , ap ; std::cin >> at >> ap ;
		if( at == 1 ) { ( p1 -> c ) = ap ; ( p1 -> idx ) = i + 1 ; p1++ ; }
		else { p2-- ; ( p2 -> c ) = ap ; ( p2 -> idx ) = i + 1 ; }
	}
	int n1 = p1 - p ; p1 = p ;
	int n2 = n - n1 ;
//	auto cmp = []( info& x , info& y ) { return x.c > y.c ; } ;
// functional kellene hozza
	std::sort( p1 , p1 + n1 , []( info x , info y ) { return x.c > y.c ; } ) ;
	std::sort( p2 , p2 + n2 , []( info x , info y ) { return x.c > y.c ; } ) ;

	int res[ n ] ;
	int nres = 0 ;
	int i1 =  0 , i2 = 0 ;
	int opt = 0 ;
	int tv = v ;
	while( tv > 1 && i1 < n1 && i2 < n2 )
	{
		if( 2 * p1[ i1 ].c >= p2[ i2 ].c ) { tv -= 1 ; opt += p1[ i1 ].c ; res[ nres++ ] = p1[ i1 ].idx ; i1++ ; }
		else { tv -= 2 ; opt += p2[ i2 ].c ; res[ nres++ ] = p2[ i2 ].idx ; i2++ ; }
	}
	while( tv > 1 && i2 < n2 )
	{
		tv -= 2 ; opt += p2[ i2 ].c ; res[ nres++ ] = p2[ i2 ].idx ; i2++ ;
	}
	while( tv > 0 && i1 < n1 )
	{
		tv -= 1 ; opt += p1[ i1 ].c ; res[ nres++ ] = p1[ i1 ].idx ; i1++ ;
	}

	std::sort( res , res + nres ) ;
	std::cout << opt << "\n" ;
	for( int i = 0 ; i < nres ; i++ )
	{
		std::cout << res[ i ] << " " ;
	}
	std::cout << "\n" ;

	return 0 ;
}


#include <bits/stdc++.h>
#define pb push_back
#define F first
#define S second
using namespace std;

vector < vector < int > > g(300005);
int a[300005], s1[300005], s2[300005];
int main () {
    ios_base::sync_with_stdio(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    for (int i(1); i<=n; i++) {
        cin >> a[i];
    }
    for (int i(0); i<n-1; i++) {
        int x,y;
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }
    long long mx=-1e15, kol=0, kkol=0, mxx=-1e15;
    for (int i(1); i<=n; i++) {
        if (a[i]>mx) {
            if (mx+1==a[i]) {
                mxx=mx;
                kkol=kol;
            } else {
                mxx=a[i]-1;
                kkol=0;
            }
            kol=1;
            mx=a[i];
            continue;
        }
        if (a[i]==mx) kol++;
        if (a[i]==mxx) kkol++;
    }
//    if (kol==1 && (kkol==0 || kkol==1)) {
//        cout << mx << endl;
//        exit(0);
//    }
//    if (kol>3) {
//
//    }
    for (int i(1); i<=n; i++) {
        for (int j(0); j<g[i].size(); j++) {
            if (a[g[i][j]]==mx) s1[i]++;
            else if (a[g[i][j]]==mxx) s2[i]++;
        }
    }
    long long ans=mx;
    if (kol>1) ans=mx+1;
//    for (int i(1); i<=n; i++){
//        if (a[i]==mx) {
//            for (int j(0); j<g[i].size(); j++){
//                if (s1[g[i][j]]>1) ans=max(ans,mx+2);
//                if (s2[g[i][j]]>0) ans=max(ans,mx+1);
//            }
//        }
//    }
int ces=0;
    for (int i(1); i<=n; i++) {
        if (s1[i]==kol && kol>1) {
           cout << mx+1 << endl;
           return 0;
        }
        if (a[i]==mx && s1[i]>1 && ces==0) {
            ans=max(ans,mx+1);
            ces=1;
            continue;
        }
        if (a[i]==mx && s1[i]>1 && ces==1) {
            ans=max(ans,mx+2);
            continue;
        }
        if (s1[i]>1 && ces==0) {
            ces=1;
            ans=max(mx+1,ans);
            continue;
        }
        if (s1[i]>1 && ces==1) {
            ans=max(ans,mx+2);
            continue;
        }
        if (s2[i]>0 && a[i]==mxx){
            ans=max(ans,mx+1);
            continue;
        }
        if (s1[i]==1 && s2[i]>0 && ces==0){
            ans=max(ans,mx+1);
            ces=1;
            continue;
        }
        if (s1[i]==1 && s2[i]>0 && ces==1){
            ans=max(ans,mx+2);
            continue;
        }
        if (s1[i]==0 && kol>1 && a[i]==mx) {
           ans=max(ans,mx+2);
           ces=1;
        }
        if (s1[i]==kol && s2[i]==0 && kkol>0 && a[i]!=mx-1){
           ans=max(ans,mx+1);
         //  cout << i << endl;
          // ces=1;
        }
        //cout <<  i << endl;
        }
    cout << ans << endl;
    //cout << mx << " " << mxx <<  " " << kol << " " << kkol << endl;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9-1;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
	}
	if(s.size()==1){
		int x=*s.begin();
		visited[x]=1;
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-1e9-1;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(i=1;i<=n;i++)
	{
		int temp=0;
		if(s.find(i)==s.end())
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			int x=s.size();
			if(temp==x){
				printf("%d\n",maxi+1 );
				return 0;
			}
		}
		else
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			int x=s.size()-1;
			if(temp==x){
				printf("%d\n",maxi+1 );
				return 0;
			}
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9-1;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
		if(s.find(j)!=s.end()&&s.find(k)!=s.end())
		{
			val[j]++;
			val[k]++;
		}
	}
	if(s.size()==1){
		int x=*s.begin();
		visited[x]=1;
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-1e9-1;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(set<int>::iterator it=s.begin();it!=s.end();it++)
	{
		if(val[*it]==s.size()-1)
		{
			printf("%d\n",maxi+1 );
			return 0;
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
vector<pi>edges;
set<int>s;
int val[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	int ans=-1e9;
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		if(s.find(j)!=s.end()&&s.find(k)!=s.end())
		{
			val[j]++;
			val[k]++;
		}
	}
	if(s.size()==1){
		printf("%d\n",maxi );
		return 0;
	}
	for(set<int>::iterator it=s.begin();it!=s.end();it++)
	{
		if(val[*it]==s.size()-1)
		{
			printf("%d\n",maxi+1 );
			return 0;
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9-1;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
	}
	if(s.size()==1){
		int x=*s.begin();
		visited[x]=1;
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-1e9-1;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(i=1;i<=n;i++)
	{
		int temp=0;
		if(s.find(i)==s.end())
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			int x=s.size();
			if(temp==x)
				printf("%d\n",maxi+1 );
			return 0;
		}
		else
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			int x=s.size()-1;
			if(temp==x)
				printf("%d\n",maxi+1 );
			return 0;
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
vector<pi>edges;
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9-1;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
		if(s.find(j)!=s.end()&&s.find(k)!=s.end())
		{
			val[j]++;
			val[k]++;
		}
	}
	if(s.size()==1){
		int x=*s.begin();
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-1e9-1;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(set<int>::iterator it=s.begin();it!=s.end();it++)
	{
		if(val[*it]==s.size()-1)
		{
			printf("%d\n",maxi+1 );
			return 0;
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9-1;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
		if(s.find(j)!=s.end()||s.find(k)!=s.end())
		{
			val[j]++;
			val[k]++;
		}
	}
	if(s.size()==1){
		int x=*s.begin();
		visited[x]=1;
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-1e9-1;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(i=1;i<=n;i++)
	{
		if((s.find(i)==s.end()&&val[i]==s.size())||(s.find(i)!=s.end()&&val[i]==s.size()-1))
		{
			printf("%d\n",maxi+1 );
			return 0;
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-2e9;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
	}
	if(s.size()==1){
		int x=*s.begin();
		visited[x]=1;
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-2e9;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(i=1;i<=n;i++)
	{
		int temp=0;
		if(s.find(i)==s.end())
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			int x=s.size();
			if(temp==x){
				printf("%d\n",maxi+1 );
				return 0;
			}
		}
		else
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			int x=s.size()-1;
			if(temp==x){
				printf("%d\n",maxi+1 );
				return 0;
			}
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int a[300005];
set<int>s;
int val[300005];
vector<int>v[300005];
int visited[300005];
int main()
{
	int i,j,k;
	int n;
	sd(n);
	for(i=1;i<=n;i++)
		sd(a[i]);
	int maxi=-1e9-1;
	for(i=1;i<=n;i++)
		maxi=max(maxi,a[i]);
	for(i=1;i<=n;i++)
	{
		if(a[i]==maxi)
		{
			s.insert(i);
		}
	}
	for(i=1;i<=n-1;i++)
	{
		sd(j);
		sd(k);
		v[j].pb(k);
		v[k].pb(j);
	}
	if(s.size()==1){
		int x=*s.begin();
		visited[x]=1;
		for(i=0;i<v[x].size();i++)
			visited[v[x][i]]=1;
		int maxi2=-1e9-1;
		for(i=1;i<=n;i++)
		{
			if(visited[i]==0)
				maxi2=max(maxi2,a[i]);
		}
		if(maxi2==maxi-1)
			maxi++;
		printf("%d\n",maxi );
		return 0;
	}
	for(i=1;i<=n;i++)
	{
		int temp=0;
		if(s.find(i)==s.end())
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			if(temp==s.size())
				printf("%d\n",maxi+1 );
			return 0;
		}
		else
		{
			for(j=0;j<v[i].size();j++)
			{
				if(a[v[i][j]]==maxi)
					temp++;
			}
			if(temp==s.size()-1)
				printf("%d\n",maxi+1 );
			return 0;
		}
	}
	printf("%d\n",maxi+2 );
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=5e6+10;
int Head[N],tot;
ll val[N],totm,totc;
struct Node{
	int next,to;
}edge[N];
ll MAX(ll a,ll b){
	return a>b?a:b;
}
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=Head[x];
	Head[x]=tot;
}
int main(){
	int n;
	ll Max=-2147483646,t;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld",&val[i]);
		if(val[i]>Max){
			Max=val[i];
			t=i;
		}
	}
	for(int i=1;i<=n;++i){
		if(val[i]==Max) totm++;
		if(val[i]==Max-1) totc++;
	}
	for(int i=1;i<n;++i){
		int a,b;
		scanf("%d%d",&a,&b);
		Add(a,b);Add(b,a);
	}
	if(totm==1){
		if(!totc){
			printf("%d\n",Max);
			return 0;
		}
		else{
			int now=0;
			for(int i=Head[t];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) now++;
			}
			if(now==totc){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max+1);
				return 0;
			}
		}
	}
	if(totm>=2){
		for(int i=1;i<=n;++i){
			int cnt=0;
			for(int j=Head[i];j;j=edge[j].next){
				int v=edge[j].to;
				if(val[v]==Max) cnt++;
			}
			if(val[i]!=Max&&cnt==totm){
				printf("%d\n",Max+1);
				return 0;
			}
			if(val[i]==Max&&cnt==totm-1){
				printf("%d\n",Max+1);
				return 0;
			}
		}
	}
	printf("%d\n",Max+2);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct Edge { int to, next; } edges[600010];
int n, tot, res, ans = -0x3f3f3f3f, flag, x, y, a[300010], head[300010];
map<int, int> m;
void add(int x,int y) { edges[++tot] = (Edge){y, head[x]},head[x] = tot; }
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]), m[a[i]]++, ans = max(ans, a[i]);
    res = ans + 2;
    for (int i = 1; i < n; i++) scanf("%d%d", &x, &y), add(x,y);
    for (int i = 1; i <= n; i++) {
        flag = 0;
        for (int j = head[i]; j; j = edges[j].next) {
            m[a[edges[j].to]]--;
            if (a[edges[j].to] == ans) flag = 1;
        }
        if (!m[ans]) res = ans + 1;
        if (ans == a[i] && m[ans] == 1) {
            if (m[ans - 1])
                res = ans + 1;
            else if (flag)
                res = ans + 1;
            else {
                res = ans;
                break;
            }
        }
        for (int j = head[i]; j; j = edges[j].next) m[a[edges[j].to]]++;
    }
    printf("%d\n", res);
    return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 3e5+5;
struct side {
    int t, next;
}e[N*2];
int head[N], tot;
void add(int x, int y) {
    e[++tot].next = head[x];
    head[x] = tot;
    e[tot].t = y;
}
int n, a[N], d = (int)-2e9, d1, d2, h;
int sum(int x, int num) {
    int s = a[x] == num ? 1 : 0;
    for(int i = head[x]; i; i = e[i].next)
        if (a[e[i].t] == num) s++;
    return s;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]), d = max(d, a[i]);
    for(int i = 1; i <= n; i++) {
        if (a[i] == d) d1++, h = i;
        else if (a[i] == d - 1) d2++;
    }
    for(int i = 1, x, y; i < n; i++) {
        scanf("%d%d", &x, &y);
        add(x, y); add(y, x);
    }
    if (d1 == 1 & sum(h, d - 1) == d2) return printf("%d", d), 0;
    for(int i = 1; i <= n; i++)
        if (sum(i, d) == d1)
            return printf("%d", d + 1), 0;
    return printf("%d", d + 2), 0;
}


//author:chhokmah
#include <bits/stdc++.h>
#define pii pair<int, int>
#define mkp make_pair
using namespace std;
typedef long long ll;
template <typename T> inline void read(T &x) {
    x = 0; T fl = 1; char ch = 0;
    for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
    x *= fl;
}
template <typename T, typename... Args> inline void read(T& x, Args&... args) {
    read(x); read(args...);
}
const int N = 3e5 + 5;
struct edge {
    int to, nt;
} E[N << 1];
int H[N], a[N];
int n, ans = 0x3f3f3f3f, e_cnt = 1;
set<pii> SET;
void add_edge(int u, int v) {
    E[++ e_cnt] = (edge) {v, H[u]};
    H[u] = e_cnt;
}
int main() {
    read(n);
    for (int i = 1; i <= n; i ++) { read(a[i]); SET.insert(mkp(a[i], i)); }
    for (int i = 1, u, v; i < n; i ++) { read(u, v); add_edge(u, v); add_edge(v, u); }
    for (int i = 1; i <= n; i ++) {
        int u = i, val = a[i]; SET.erase(mkp(val, u));
        for (int e = H[u]; e; e = E[e].nt) { int v = E[e].to; val = max(val, a[v] + 1); SET.erase(mkp(a[v], v)); }
        if (!SET.empty()) { val = max(val, (*SET.rbegin()).first + 2); }
        SET.insert(mkp(a[i], i));
        for (int e = H[u]; e; e = E[e].nt) { int v = E[e].to; SET.insert(mkp(a[v], v)); }
        ans = min(ans, val);
    }
    printf("%d\n", ans);
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e6+10;
const int Inf=1e9;
int Head[N],tot;
struct Node{
	int next,to;
}edge[N];
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=Head[x];
	Head[x]=tot;
}
int val[N],num[N];
vector<int>ve[N];
int main(){
	int n,Max=-1;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		int x;
		scanf("%d",&x);
		x+=Inf;
		val[i]=x;Max=max(Max,x);
		ve[x].push_back(i);
	}
	for(int i=1;i<n;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		Add(x,y);Add(y,x);
	}
	if(ve[Max].size()==1){
		int t=0,u=ve[Max][0];
		for(int i=Head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(val[v]==Max-1) t++;
		}
		if(t==ve[Max-1].size()){
			printf("%d\n",Max);
			return 0;
		}
		else{
			printf("%d\n",Max+1);
			return 0;
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 1000005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-4
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
    ll x = 0;
    char c = getchar();
    bool f = false;
    while (!isdigit(c)) {
        if (c == '-') f = true;
        c = getchar();
    }
    while (isdigit(c)) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f ? -x : x;
}

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}
int sqr(int x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
    if (!b) {
        x = 1; y = 0; return a;
    }
    ans = exgcd(b, a%b, x, y);
    ll t = x; x = y; y = t - a / b * y;
    return ans;
}
*/

int n;
int a[maxn];
vector<int>vc[maxn];

int main() {
    //ios::sync_with_stdio(0);
    rdint(n);
    for (int i = 1; i <= n; i++)rdint(a[i]);
    for (int i = 1; i < n; i++) {
        int u, v; rdint(u); rdint(v);
        vc[u].push_back(v); vc[v].push_back(u);
    }
    int maxx = -inf; int maxcnt = 0;
    for (int i = 1; i <= n; i++) {
        maxx = max(maxx, a[i]);
    }
    for (int i = 1; i <= n; i++)if (a[i] == maxx)maxcnt++;
    if (maxcnt == 1) {
        int mxcnt = 0;
        int pos = 0;
        for (int i = 1; i <= n; i++) {
            if (a[i] == maxx - 1)mxcnt++;
            if (a[i] == maxx)pos = i;
        }
        int num = 0;
        for (int i = 0; i < vc[pos].size(); i++) {
            if (a[vc[pos][i]] == maxx - 1)num++;
        }
        if (num == mxcnt) { cout << maxx << endl; return 0; }
        else {
            cout << maxx + 1 << endl; return 0;
        }
    }
    else {
        bool fg = 0;

        for (int i = 1; i <= n; i++) {
            int  num = 0;
            if (a[i] == maxx)num++;
            for (int j = 0; j < vc[i].size(); j++) {
                if (a[vc[i][j]] == maxx)num++;
            }
            if (num == maxcnt)fg = 1;
        }
        if (fg)cout << maxx + 1 << endl;
        else cout << maxx + 2 << endl;
    }
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=5e6+10;
int Head[N],tot,val[N],totm,totc;
struct Node{
	int next,to;
}edge[N];
ll MAX(ll a,ll b){
	return a>b?a:b;
}
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=Head[x];
	Head[x]=tot;
}
int main(){
	int n;
	ll Max=-2147483646,t;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld",&val[i]);
		if(val[i]>Max){
			Max=val[i];
			t=i;
		}
	}
	for(int i=1;i<=n;++i){
		if(val[i]==Max) totm++;
		if(val[i]==Max-1) totc--;
	}
	for(int i=1;i<n;++i){
		int a,b;
		scanf("%d%d",&a,&b);
		Add(a,b);Add(b,a);
	}
	if(totm==1){
		if(!totc){
			printf("%d\n",Max);
			return 0;
		}
		else{
			int now=0;
			for(int i=Head[t];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) now++;
			}
			if(now==totc){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max+1);
				return 0;
			}
		}
	}
	if(totm>=2){
		for(int i=1;i<=n;++i){
			int cnt=0;
			for(int j=Head[i];j;j=edge[j].next){
				int v=edge[j].to;
				if(val[v]==Max) cnt++;
			}
			if(val[i]!=Max&&cnt==totm){
				printf("%d\n",Max+1);
				return 0;
			}
			if(val[i]==Max&&cnt==totm-1){
				printf("%d\n",Max+1);
				return 0;
			}
		}
	}
	printf("%d\n",Max+2);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=5e6+10;
int Head[N],tot,val[N],totm,totc;
struct Node{
	int next,to;
}edge[N];
ll MAX(ll a,ll b){
	return a>b?a:b;
}
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=Head[x];
	Head[x]=tot;
}
int main(){
	int n;
	ll Max=-2147483646,t;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld",&val[i]);
		if(val[i]>Max){
			Max=val[i];
			t=i;
		}
	}
	for(int i=1;i<=n;++i){
		if(val[i]==Max) totm++;
		if(val[i]==Max-1) totc--;
		int a,b;
		scanf("%d%d",&a,&b);
		Add(a,b);Add(b,a);
	}
	if(totm==1){
		if(!totc){
			printf("%d\n",Max);
			return 0;
		}
		else{
			int now=0;
			for(int i=Head[t];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) now++;
			}
			if(now==totc){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max+1);
				return 0;
			}
		}
	}
	if(totm>=2){
		for(int i=1;i<=n;++i){
			int cnt=0;
			for(int j=Head[i];j;j=edge[j].next){
				int v=edge[j].to;
				if(val[v]==Max) cnt++;
			}
			if(val[i]!=Max&&cnt==totm){
				printf("%d\n",Max+1);
				return 0;
			}
			if(val[i]==Max&&cnt==totm-1){
				printf("%d\n",Max+1);
				return 0;
			}
		}
	}
	printf("%d\n",Max+2);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=5e6+10;
int Head[N],tot;
struct Node{
	int next,to;
}edge[N];
ll MAX(ll a,ll b){
	return a>b?a:b;
}
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=Head[x];
	Head[x]=tot;
}
ll val[N],num[N];
vector<int>ve1[N];
vector<int>ve2[N];
int main(){
	int n;
	ll Max=-2147483646;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		ll x;
		scanf("%lld",&x);
		if(x>0){
			val[i]=x;Max=MAX(Max,x);
			ve1[x].push_back(i);
		}
		else{
			val[i]=x;Max=MAX(Max,x);
			ve2[-x].push_back(i);
		}
	}
	for(int i=1;i<n;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		Add(x,y);Add(y,x);
	}
	if(Max>0){
		if(ve1[Max].size()==1){
			int t=0,u=ve1[Max][0];
			for(int i=Head[u];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) t++;
			}
			if(!ve1[Max-1].size()||t==ve1[Max-1].size()){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max+1);
				return 0;
			}
		}
		else{
			for(int i=1;i<=n;++i){
				int cnt=0;
				for(int j=Head[i];j;j=edge[j].next){
					int v=edge[j].to;
					if(val[v]==Max){
						cnt++;
					}
				}
				if(val[i]!=Max&&cnt==ve1[Max].size()){
					printf("%d\n",Max+1);
					return 0;
				}
				if(val[i]==Max&&cnt==ve1[Max].size()-1){
					printf("%d\n",Max+1);
					return 0;
				}
			}
		}
	}
	else{
		if(ve2[-Max].size()==1){
			int t=0,u=ve2[-Max][0];
			for(int i=Head[u];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) t++;
			}
			if(!ve2[-Max+1].size()||t==ve2[-Max+1].size()){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max+1);
				return 0;
			}
		}
		else{
			for(int i=1;i<=n;++i){
				int cnt=0;
				for(int j=Head[i];j;j=edge[j].next){
					int v=edge[j].to;
					if(val[v]==Max){
						cnt++;
					}
				}
				if(val[i]!=Max&&cnt==ve2[-Max].size()){
					printf("%d\n",Max+1);
					return 0;
				}
				if(val[i]==Max&&cnt==ve2[-Max].size()-1){
					printf("%d\n",Max+1);
					return 0;
				}
			}
		}
	}
	printf("%d\n",Max+2);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 3e5+5;
struct side {
    int t, next;
}e[N*2];
int head[N], tot;
void add(int x, int y) {
    e[++tot].next = head[x];
    head[x] = tot;
    e[tot].t = y;
}
int n, a[N], d = (int)-2e9, d1, d2, h;
int sum(int x, int num) {
    int s = a[x] == num ? 1 : 0;
    for(int i = head[x]; i; i = e[i].next)
        if (a[e[i].t] == num) s++;
    return s;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]), d = max(d, a[i]);
    for(int i = 1; i <= n; i++) {
        if (a[i] == d) d1++, h = i;
        else if (a[i] == d - 1) d2++;
    }
    for(int i = 1, x, y; i < n; i++) {
        scanf("%d%d", &x, &y);
        add(x, y); add(y, x);
    }
    if (d1 == 1 & sum(h, d - 1) == d2) return printf("%d", d), 0;
    for(int i = head[h]; i; i = e[i].next)
        if (sum(e[i].t, d) == d1)
            return printf("%d", d + 1), 0;
    return printf("%d", d + 2), 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e6+10;
int Head[N],tot;
struct Node{
	int next,to;
}edge[N];
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=Head[x];
	Head[x]=tot;
}
int val[N],num[N];
vector<int>ve1[N];
vector<int>ve2[N];
int main(){
	int n,Max=-1;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		int x;
		scanf("%d",&x);
		if(x>0){
			val[i]=x;Max=max(Max,x);
			ve1[x].push_back(i);
		}
		else{
			val[i]=x;Max=max(Max,x);
			ve2[-x].push_back(i);
		}
	}
	for(int i=1;i<n;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		Add(x,y);Add(y,x);
	}
	if(Max>0){
		if(ve1[Max].size()==1){
			int t=0,u=ve1[Max][0];
			for(int i=Head[u];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) t++;
			}
			if(!ve1[Max-1].size()||t==ve1[Max-1].size()){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max+1);
				return 0;
			}
		}
		else{
			for(int i=1;i<=n;++i){
				int cnt=0;
				for(int j=Head[i];j;j=edge[j].next){
					int v=edge[j].to;
					if(val[v]==Max){
						cnt++;
					}
				}
				if(val[i]!=Max&&cnt==ve1[Max].size()){
					printf("%d\n",Max+1);
					return 0;
				}
				if(val[i]==Max&&cnt==ve1[Max].size()-1){
					printf("%d\n",Max+1);
					return 0;
				}
			}
		}
	}
	else{
		if(ve2[-Max].size()==1){
			int t=0,u=ve2[-Max][0];
			for(int i=Head[u];i;i=edge[i].next){
				int v=edge[i].to;
				if(val[v]==Max-1) t++;
			}
			if(!ve2[-Max+1].size()||t==ve2[-Max+1].size()){
				printf("%d\n",Max);
				return 0;
			}
			else{
				printf("%d\n",Max-1);
				return 0;
			}
		}
		else{
			for(int i=1;i<=n;++i){
				int cnt=0;
				for(int j=Head[i];j;j=edge[j].next){
					int v=edge[j].to;
					if(val[v]==Max){
						cnt++;
					}
				}
				if(val[i]!=Max&&cnt==ve1[-Max].size()){
					printf("%d\n",Max+1);
					return 0;
				}
				if(val[i]==Max&&cnt==ve1[-Max].size()-1){
					printf("%d\n",Max+1);
					return 0;
				}
			}
		}
	}
	printf("%d\n",Max+2);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct Edge { int to, next; } edges[600010];
int n, tot, ans, maxv = -0x3f3f3f3f, flag, x, y, a[300010], head[300010];
map<int, int> m;
void add(int x,int y) { edges[++tot] = (Edge){y, head[x]},head[x] = tot; }
// void add(int x,int y) {
//     edges[tot] = (Edge){y, (head[x] = ++tot)};
// }
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]), m[a[i]]++, maxv = max(maxv, a[i]);
    ans = maxv + 2;
    for (int i = 1; i < n; i++) scanf("%d%d", &x, &y), add(x,y), add(y,x);
    for (int i = 1; i <= n; i++) {
        flag = 0;
        for (int j = head[i]; j; j = edges[j].next) {
            m[a[edges[j].to]]--;
            if (a[edges[j].to] == maxv) flag = 1;
        }
        if (!m[maxv]) ans = maxv + 1;
        if (maxv == a[i] && m[maxv] == 1) {
            if (m[maxv - 1] || flag) // 其它节点有ans-1的权值,-1+2=+1 或者 子节点中也有最大值,子节点+1后是答案
                ans = maxv + 1;
            else {
                ans = maxv; // 根节点是最大值, 并且子树中没有更大的, 直接break
                break;
            }
        }
        for (int j = head[i]; j; j = edges[j].next) m[a[edges[j].to]]++;
    }
    printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
int n;
vll str;
ll ans;
ll str_max = -1000000000;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll a = 0, b = 0, cnta = 0, cntb = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 1, n + 1){
		if(str[i] == str_max) a++;
		if(str[i] == str_max - 1) b++;
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	ll ans = str_max + 2;
	rep(u, 1, n + 1){
		cnta = 0, cntb = 0;
		if(a == 1 && str[u] == str_max){
			rep(i, 0, graph[u].size()){
				int v = graph[u][i];
				if(str[v] == str_max - 1) cntb++;
			}
			if(cntb == b){
				cout<<str_max;
				return 0;
			}
		}
		cntb = 0;
		if(str[u] == str_max) cnta++;
		if(str[u] == str_max - 1) cntb++;
		rep(i, 0, graph[u].size()){
			int v = graph[u][i];
			if(str[v] == str_max) cnta++;
			if(str[v] == str_max - 1)	cntb++;
		}
		if(cnta == a && cntb == b){
			ans = str_max + 1;
		}
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vb vis;
vvi graph;
ll ans;
int n;
vll str;
vi dist;
void bfs(int s){
	qi q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		vis[u] = true;
		rep(i, 0, graph[u].size()){
			int v = graph[u][i];
			if(vis[v] == false){
				q.push(v);
				dist[v] = dist[u] + 1;
			}
		}
	}
}
int main(){
	cin>>n;
	graph.res(n + 1);
	vis.ass(n + 1, false);
	str.res(n + 1);
	dist.res(n + 1);
	ll str_max = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	int s;
	rep(i, 1, n + 1)	if(str[i] == str_max){	s = i; break; }
	dist[s] = 0;
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	bfs(s);
	ans = str_max;
	rep(i, 1, n + 1){
		if(i != s && str[i] == str_max){
			ans = (dist[i] > 1) ?(str_max + 1) :(str_max + 2);
		}
	}
	cout<<ans;
	ios_base::sync_with_stdio(0), cin.tie(0);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
int n;
vll str;
ll ans;
ll str_max = -1000000000;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll a = 0, b = 0, cnta = 0, cntb = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 1, n + 1){
		if(str[i] == str_max) a++;
		if(str[i] == str_max - 1) b++;
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	ll ans = str_max + 2;
	rep(u, 1, n + 1){
		cnta = 0, cntb = 0;
		if(a == 1 && (str[u] == str_max)){
			rep(i, 0, graph[u].size()){
				int v = graph[u][i];
				if(str[v] == str_max - 1) cntb++;
			}
			if(cntb == b){
				cout<<str_max;
				return 0;
			}
		}
		cntb = 0;
		if(str[u] == str_max) cnta++;
		rep(i, 0, graph[u].size()){
			int v = graph[u][i];
			if(str[v] == str_max) cnta++;
		}
		if(cnta == a){
			ans = str_max + 1;
		}
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
int n;
vll str;
ll ans;
ll str_max = -1000000000;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll a = 0, b = 0, cnta = 0, cntb = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 1, n + 1){
		if(str[i] == str_max) a++;
		if(str[i] == str_max - 1) b++;
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	ll ans = str_max + 2;
	rep(u, 1, n + 1){
		cnta = 0, cntb = 0;
		if((a == 1) && (str[u] == str_max)){
			rep(i, 0, graph[u].size()){
				int v = graph[u][i];
				if(str[v] == str_max - 1) cntb++;
			}
			if(cntb == b){
				cout<<str_max;
				return 0;
			}
		}
		cntb = 0;
		if(str[u] == str_max) cnta++;
		if(str[u] == str_max - 1) cntb++;
		rep(i, 0, graph[u].size()){
			int v = graph[u][i];
			if(str[v] == str_max) cnta++;
			if(str[v] == str_max - 1)	cntb++;
		}
		if((cnta == a) && (cntb == b)){
			ans = str_max + 1;
		}
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
ll ans;
int n;
vll str;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll str_max = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	if(n == 1){
		cout<<str[1];
		return 0;
	}
	vi a;
	rep(i, 1, n + 1){
		if(str[i] == str_max) a.pb(i);
	}
	if(a.size() == 1){
		rep(i, 1, n + 1){
			if(str[i] == str_max - 1){
				int u = a[0], v = i;
				rep(i, 0, graph[u].size()){
					if(graph[u][i] == v){
					cout<<str_max;
					return 0;
					}
				}
				cout<<str_max + 1;
				return 0;
			}
		}
		cout<<str_max;
		return 0;
	}
	if(a.size() > 3){
		cout<<str_max + 2;
		return 0;
	}
	if(a.size() == 2){
		int u = a[0], v = a[1];
		rep(i, 0, graph[u].size()){
			if(graph[u][i] == v){
			cout<<str_max + 1;
			return 0;
			}
		}
		rep(i, 0, graph.size()){
			if(graph[i].size() == 2){
				if( (graph[i][0] == u && graph[i][1] == v) || (graph[i][0] == v && graph[i][1] == v)){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
	}
	if(a.size() == 3){
		int u = a[0], v = a[1], w = a[2];
		if(graph[u].size() == 2){
			if((graph[u][0] == v && graph[u][1] == w) || (graph[u][0] == w || graph[u][1] == v)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[v].size() == 2){
			if((graph[v][0] == u && graph[v][1] == w) || (graph[v][0] == w || graph[v][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[w].size() == 2){
			if((graph[w][0] == u && graph[w][1] == v) || (graph[w][0] == v || graph[w][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
	}
	cout<<str_max + 2;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
int n;
vll str;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll str_max = -1000000000;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	if(n == 1){
		cout<<str[1];
		return 0;
	}
	vi a;
	rep(i, 1, n + 1){
		if(str[i] == str_max) a.pb(i);
	}
	if(a.size() == 1){
		rep(i, 1, n + 1){
			if(str[i] == str_max - 1){
				bool b = false;
				int u = a[0], v = i;
				rep(i, 0, graph[u].size()){
					if(graph[u][i] == v){
						b = true;
						break;
					}
				}if(b == false){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
		cout<<str_max;
		return 0;
	}
	if(a.size() > 3){
		cout<<str_max + 2;
		return 0;
	}
	if(a.size() == 2){
		int u = a[0], v = a[1];
		rep(i, 0, graph[u].size()){
			if(graph[u][i] == v){
			cout<<str_max + 1;
			return 0;
			}
		}
		rep(i, 0, graph.size()){
			if(graph[i].size() == 2){
				if( (graph[i][0] == u && graph[i][1] == v) || (graph[i][0] == v && graph[i][1] == u)){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
	}
	if(a.size() == 3){
		int u = a[0], v = a[1], w = a[2];
		if(graph[u].size() == 2){
			if((graph[u][0] == v && graph[u][1] == w) || (graph[u][0] == w || graph[u][1] == v)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[v].size() == 2){
			if((graph[v][0] == u && graph[v][1] == w) || (graph[v][0] == w || graph[v][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[w].size() == 2){
			if((graph[w][0] == u && graph[w][1] == v) || (graph[w][0] == v || graph[w][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
	}
	cout<<str_max + 2;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
ll ans;
int n;
vll str;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll str_max = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	if(n == 1){
		cout<<str[1];
		return 0;
	}
	vi a;
	rep(i, 1, n + 1){
		if(str[i] == str_max) a.pb(i);
	}
	if(a.size() == 1){
		rep(i, 1, n + 1){
			if(str[i] == str_max - 1){
				int u = a[0], v = i;
				rep(i, 0, graph[u].size()){
					if(graph[u][i] == v){
					cout<<str_max;
					return 0;
					}
				}
				cout<<str_max + 1;
				return 0;
			}
		}
		cout<<str_max;
		return 0;
	}
	if(a.size() > 3){
		cout<<str_max + 2;
		return 0;
	}
	if(a.size() == 2){
		int u = a[0], v = a[1];
		rep(i, 0, graph[u].size()){
			if(graph[u][i] == v){
			cout<<str_max + 1;
			return 0;
			}
		}
		rep(i, 0, graph.size()){
			if(graph[i].size() == 2){
				if( (graph[i][0] == u && graph[i][1] == v) || (graph[i][0] == v && graph[i][1] == v)){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
	}
	if(a.size() == 3){
		int u = a[0], v = a[1], w = a[2];
		if(graph[u].size() == 2){
			if((graph[u][0] == v && graph[u][1] == w) || (graph[u][0] == w || graph[u][1] == v)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[v].size() == 2){
			if((graph[v][0] == u && graph[v][1] == w) || (graph[v][0] == w || graph[v][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[w].size() == 2){
			if((graph[w][0] == u && graph[w][1] == v) || (graph[w][0] == u || graph[w][1] == v)){
				cout<<str_max + 1;
				return 0;
			}
		}
	}
	cout<<str_max + 2;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
ll ans;
int n;
vll str;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll str_max = -1000000000;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	if(n == 1){
		cout<<str[1];
		return 0;
	}
	vi a;
	rep(i, 1, n + 1){
		if(str[i] == str_max) a.pb(i);
	}
	if(a.size() == 1){
		rep(i, 1, n + 1){
			if(str[i] == str_max - 1){
				int u = a[0], v = i;
				rep(i, 0, graph[u].size()){
					if(graph[u][i] == v){
					cout<<str_max;
					return 0;
					}
				}
				cout<<str_max + 1;
				return 0;
			}
		}
		cout<<str_max;
		return 0;
	}
	if(a.size() > 3){
		cout<<str_max + 2;
		return 0;
	}
	if(a.size() == 2){
		int u = a[0], v = a[1];
		rep(i, 0, graph[u].size()){
			if(graph[u][i] == v){
			cout<<str_max + 1;
			return 0;
			}
		}
		rep(i, 0, graph.size()){
			if(graph[i].size() == 2){
				if( (graph[i][0] == u && graph[i][1] == v) || (graph[i][0] == v && graph[i][1] == v)){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
	}
	if(a.size() == 3){
		int u = a[0], v = a[1], w = a[2];
		if(graph[u].size() == 2){
			if((graph[u][0] == v && graph[u][1] == w) || (graph[u][0] == w || graph[u][1] == v)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[v].size() == 2){
			if((graph[v][0] == u && graph[v][1] == w) || (graph[v][0] == w || graph[v][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[w].size() == 2){
			if((graph[w][0] == u && graph[w][1] == v) || (graph[w][0] == v || graph[w][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
	}
	cout<<str_max + 2;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
int n;
vll str;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll str_max = -1000000000;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	if(n == 1){
		cout<<str[1];
		return 0;
	}
	vi a;
	rep(i, 1, n + 1){
		if(str[i] == str_max) a.pb(i);
	}
	if(a.size() == 1){
		rep(i, 1, n + 1){
			if(str[i] == str_max - 1){
				bool b = false;
				int u = a[0], v = i;
				rep(i, 0, graph[u].size()){
					if(graph[u][i] == v){
						b = true;
						break;
					}
				}if(b == false){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
		cout<<str_max;
		return 0;
	}
	if(a.size() > 3){
		cout<<str_max + 2;
		return 0;
	}
	if(a.size() == 2){
		int u = a[0], v = a[1];
		rep(i, 0, graph[u].size()){
			if(graph[u][i] == v){
			cout<<str_max + 1;
			return 0;
			}
		}
		rep(i, 0, graph.size()){
			if(graph[i].size() == 2){
				if( (graph[i][0] == u && graph[i][1] == v) || (graph[i][0] == v && graph[i][1] == u)){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
	}
	if(a.size() == 3){
		int u = a[0], v = a[1], w = a[2];
		if(graph[u].size() == 2){
			if((graph[u][0] == v && graph[u][1] == w) || (graph[u][0] == w && graph[u][1] == v)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[v].size() == 2){
			if((graph[v][0] == u && graph[v][1] == w) || (graph[v][0] == w && graph[v][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
		if(graph[w].size() == 2){
			if((graph[w][0] == u && graph[w][1] == v) || (graph[w][0] == v && graph[w][1] == u)){
				cout<<str_max + 1;
				return 0;
			}
		}
	}
	cout<<str_max + 2;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define repr(i, b, a) for(int i = (b); i>=(a); i--)
#define pb push_back
#define mp make_pair
#define ass assign
#define res resize
#define sort(v) sort((v).begin(), (v).end())
#define ins(s) getline(cin, s)
#define flush cin.ignore(4096, '\n')
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef vector<pair<int, int> > vpii;
typedef vector<bool> vb;
typedef queue<int> qi;
typedef long long ll;
typedef vector<long long> vll;
ll mod = 1000 * 1000 * 1000 + 7;
vvi graph;
ll ans;
int n;
vll str;
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin>>n;
	graph.res(n + 1);
	str.res(n + 1);
	ll str_max = 0;
	rep(i, 1, n + 1){
		cin>>str[i];
		str_max = max(str_max, str[i]);
	}
	rep(i, 0, n - 1){
		int u, v;
		cin>>u>>v;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	if(n == 1){
		cout<<str[1];
		return 0;
	}
	vi a;
	rep(i, 1, n + 1){
		if(str[i] == str_max) a.pb(i);
	}
	if(a.size() == 1){
		rep(i, 1, n + 1){
			if(str[i] == str_max - 1){
				int u = a[0], v = i;
				if(!(graph[u][0] == i || graph[u][1] == i)){
					cout<<str_max + 1;
					return 0;
				}
			}
		}
		cout<<str_max;
		return 0;
	}
	if(a.size() > 3){
		cout<<str_max + 2;
		return 0;
	}
	if(a.size() == 2){
		int u = a[0], v = a[1];
		if(graph[u][0] == v || graph[u][1] == v){
			cout<<str_max + 1;
			return 0;
		}
	}
	if(a.size() == 3){
		int u = a[0], v = a[1], w = a[2];
		if((graph[u][0] == v || graph[u][1] == v) && (graph[u][0] == w || graph[u][1] == w)){
			cout<<str_max + 1;
			return 0;
		}
		if((graph[v][0] == u || graph[v][1] == u) && (graph[v][0] == w || graph[v][1] == w)){
			cout<<str_max + 1;
			return 0;
		}
		if((graph[w][0] == v || graph[w][1] == v) && (graph[w][0] == u || graph[w][1] == u)){
			cout<<str_max + 1;
			return 0;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N=500005;
int head[N],to[N<<1],nxt[N<<1];
long long sec[N],maxlinked[N],no=0;
bool vis[N];
long long ans=-1;
int n;
long long mx=-(1e10);
int startnode;
void dfs(int idx){
	vis[idx]=1;
	ans=max(ans,sec[idx]);
	for(int i=head[idx];i!=-1;i=nxt[i]){
		int nx=to[i];
		if(!vis[nx]){
			sec[nx]++;
			if(idx!=startnode) sec[nx]++;
			dfs(nx);
		}
	}
}

void link(int a,int b){
	nxt[no]=head[a];
	to[no]=b;
	head[a]=no++;
	if(b==mx) maxlinked[a]++;
}
int main() {
	memset(head,-1,sizeof head);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>sec[i];
		mx=max(mx,sec[i]);
	}
	int x,y;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		link(x,y);
		link(y,x);
	}
	int mxli=-1,sn=0;
	for(int i=1;i<=n;i++){
		if(sec[i]==mx){
			if(maxlinked[i]>mxli){
				sn=i;
				mxli=maxlinked[i];
			}
		}
	}
	ans=mx;
	startnode=sn;
	dfs(sn);
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N=500005;
int head[N],to[N<<1],nxt[N<<1];
long long sec[N],maxlinked[N],no=0;
bool vis[N];
long long ans=-1;
int n;
long long mx=-(1e10);
int startnode;
void dfs(int idx){
	vis[idx]=1;
	ans=max(ans,sec[idx]);
	for(int i=head[idx];i!=-1;i=nxt[i]){
		int nx=to[i];
		if(!vis[nx]){
			sec[nx]++;
			if(idx!=startnode) sec[nx]++;
			dfs(nx);
		}
	}
}

void link(int a,int b){
	nxt[no]=head[a];
	to[no]=b;
	head[a]=no++;
	if(b==mx) maxlinked[a]++;
}
int main() {
	memset(head,-1,sizeof head);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>sec[i];
		mx=max(mx,sec[i]);
	}
	int x,y;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		link(x,y);
		link(y,x);
	}
	int mxli=-1,sn=0;

	for(int i=1;i<=n;i++){
			if(sec[i]==mx){
				for(int k=head[i];k!=-1;k=nxt[k]){
					maxlinked[i]+=max(maxlinked[to[k]]-1,0ll);
				}
			}
		}

	for(int i=1;i<=n;i++){
		if(sec[i]==mx){
			if(maxlinked[i]>mxli){
				sn=i;
				mxli=maxlinked[i];
			}
		}
	}

	ans=mx;
	startnode=sn;
	dfs(sn);
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N=500005;
int head[N],to[N<<1],nxt[N<<1];
int sec[N],maxlinked[N],no=0;
bool vis[N];
int ans=-1;
int n;
int mx=-(1e9+5);
int startnode;
void dfs(int idx){
	vis[idx]=1;
	ans=max(ans,sec[idx]);
	for(int i=head[idx];i!=-1;i=nxt[i]){
		int nx=to[i];
		if(!vis[nx]){
			sec[nx]++;
			if(idx!=startnode) sec[nx]++;
			dfs(nx);
		}
	}
}

void link(int a,int b){
	nxt[no]=head[a];
	to[no]=b;
	head[a]=no++;
	if(b==mx) maxlinked[a]++;
}
int main() {
	memset(head,-1,sizeof head);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>sec[i];
		mx=max(mx,sec[i]);
	}
	int x,y;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		link(x,y);
		link(y,x);
	}
	int mxli=-1,sn=0;
	for(int i=1;i<=n;i++){
		if(sec[i]==mx){
			if(maxlinked[i]>mxli){
				sn=i;
				mxli=maxlinked[i];
			}
		}
	}
	ans=mx;
	startnode=sn;
	dfs(sn);
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int head[N], to[N << 1], nxt[N << 1];
int sec[N], maxlinked[N], no = 0;
bool vis[N];
int ans = 1e9+5;
int n;
int mx = -(1e9 + 5);

map<int,int> mp;

void getmax(int idx){
	map<int,int> m;
	m=mp;
	m[sec[idx]]--;
	int v=sec[idx];
	for(int i=head[idx];i!=-1;i=nxt[i]){
		v=max(v,sec[to[i]]+1);
		m[sec[to[i]]]--;
	}
	map<int,int>::const_iterator j=m.end();
	j--;
	while(j->second<=0 ) j--;
	v=max(v,j->first+2);
	ans=min(ans,v);
	/*cout<<idx<<" "<<j->first<<"\n";
	j=m.begin();
	while(j!=m.end()){
		cout<<j->first<<" "<<j->second<<"\n";
		j++;
	}
	cout<<"-----";
	*/
}

void link(int a, int b) {
	nxt[no] = head[a];
	to[no] = b;
	head[a] = no++;
	if (b == mx)
		maxlinked[a]++;
}
int main() {
	memset(head, -1, sizeof head);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> sec[i];
		mp[sec[i]]++;
		mx=max(mx,sec[i]);
	}
	int x, y;
	for (int i = 1; i < n; i++) {
		cin >> x >> y;
		link(x, y);
		link(y, x);
	}
	//int mxli = -1, sn = 0;
	for(int i=1;i<=n;i++) if(sec[i]==mx) getmax(i);
	cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
//int head[N], to[N << 1], nxt[N << 1];
int sec[N], maxlink[N], maxlink1[N], no = 0;

int ans = 1e9 + 5;
int n;
int mx = -(1e9 + 5);

/*
 void link(int a, int b) {
 nxt[no] = head[a];
 to[no] = b;
 head[a] = no++;
 if (b == mx)
 maxlinked[a]++;
 }
 */
int main() {
	//memset(head, -1, sizeof head);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> sec[i];

		mx = max(mx, sec[i]);
	}
	int x, y;
	for (int i = 1; i < n; i++) {
		cin >> x >> y;
		if (sec[x] == mx)
			maxlink[y]++;
		if (sec[y] == mx)
			maxlink[x]++;
		if (sec[x]+1 == mx)
			maxlink1[y]++;
		if (sec[y]+1 == mx)
			maxlink1[x]++;

	}
	int a=0,b=0;
	for(int i=1;i<=n;i++){
		if(sec[i]==mx) a++;
		if(sec[i]+1==mx) b++;
	}
	//int mxli = -1, sn = 0;
	for (int i = 1; i <= n; i++){
		int aa=a,bb=b;
		if(sec[i]==mx) aa--;
		if(sec[i]+1==mx) bb--;
		int v=mx;
		if(maxlink[i]>0 || bb-maxlink1[i]>0) v=mx+1;
		if(aa-maxlink[i]>0) v=mx+2;

		ans=min(ans,v);
	}
	cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int head[N], to[N << 1], nxt[N << 1];
int sec[N], maxlinked[N], no = 0;
bool vis[N];
int ans = 1e9+5;
int n;
int mx = -(1e9 + 5);

map<int,int> mp;

void getmax(int idx){
	map<int,int> m;
	m=mp;
	m[sec[idx]]--;
	int v=sec[idx];
	for(int i=head[idx];i!=-1;i=nxt[i]){
		v=max(v,sec[to[i]]+1);
		m[sec[to[i]]]--;
	}
	map<int,int>::const_iterator j=m.end();
	j--;
	while(j->second<=0 ) j--;
	v=max(v,j->first+2);
	ans=min(ans,v);
	/*cout<<idx<<" "<<j->first<<"\n";
	j=m.begin();
	while(j!=m.end()){
		cout<<j->first<<" "<<j->second<<"\n";
		j++;
	}
	cout<<"-----";
	*/
}

void link(int a, int b) {
	nxt[no] = head[a];
	to[no] = b;
	head[a] = no++;
	if (b == mx)
		maxlinked[a]++;
}
int main() {
	memset(head, -1, sizeof head);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> sec[i];
		mp[sec[i]]++;
	}
	int x, y;
	for (int i = 1; i < n; i++) {
		cin >> x >> y;
		link(x, y);
		link(y, x);
	}
	//int mxli = -1, sn = 0;
	for(int i=1;i<=n;i++) getmax(i);
	cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int head[N], to[N << 1], nxt[N << 1];
long long sec[N], maxlinked[N], no = 0;
bool vis[N];
long long ans = -1;
int n;
long long mx = -(1e9 + 5);

void dfs(int idx) {
	vis[idx] = 1;
	ans = max(ans, sec[idx]);
	for (int i = head[idx]; i != -1; i = nxt[i]) {
		int nx = to[i];
		if (!vis[nx]) {
			sec[nx]++;
			dfs(nx);
		}
	}
}

void link(int a, int b) {
	nxt[no] = head[a];
	to[no] = b;
	head[a] = no++;
	if (b == mx)
		maxlinked[a]++;
}
int main() {
	memset(head, -1, sizeof head);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> sec[i];
		mx = max(mx, sec[i]);
	}
	int x, y;
	for (int i = 1; i < n; i++) {
		cin >> x >> y;
		link(x, y);
		link(y, x);
	}
	int mxli = -1, sn = 0;
	for (int i = 1; i <= n; i++) {
		if (sec[i] == mx) {
			for (int k = head[i]; k != -1; k = nxt[k]) {
				maxlinked[i] += max(maxlinked[to[k]] - 1, 0ll);
			}
		}
	}

	for (int i = 1; i <= n; i++) {
		if (sec[i] == mx) {
			if (maxlinked[i] > mxli) {
				sn = i;
				mxli = maxlinked[i];
			}
		}
	}
	ans = mx;
	dfs(sn);
	cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N=500005;
int head[N],to[N<<1],nxt[N<<1];
int sec[N],maxlinked[N],no=0;
bool vis[N];
int ans=-1;
int n;
int mx=-(1e9+5);

void dfs(int idx){
	vis[idx]=1;
	ans=max(ans,sec[idx]);
	for(int i=head[idx];i!=-1;i=nxt[i]){
		int nx=to[i];
		if(!vis[nx]){
			sec[nx]++;
			dfs(nx);
		}
	}
}

void link(int a,int b){
	nxt[no]=head[a];
	to[no]=b;
	head[a]=no++;
	if(b==mx) maxlinked[a]++;
}
int main() {
	memset(head,-1,sizeof head);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>sec[i];
		mx=max(mx,sec[i]);
	}
	int x,y;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		link(x,y);
		link(y,x);
	}
	int mxli=-1,sn=0;
	for(int i=1;i<=n;i++){
		if(sec[i]==mx){
			if(maxlinked[i]>mxli){
				sn=i;
				mxli=maxlinked[i];
			}
		}
	}
	ans=mx;
	dfs(sn);
	cout<<ans;
}