/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Ido Kessler
 */

#include <iostream>

#include <fstream>
#include <vector>
#include <queue>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <functional>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <bitset>
#include <iomanip>
#include <cstdint>
#include <cassert>

#include <tuple>
#include <math.h>

using ll = long long int;
using vi = std::vector<int>;
using vvi = std::vector<vi>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using pi = std::pair<int, int>;
using vpi = std::vector<pi>;

#define all(x) (x).begin(), (x).end()
#define fori(i, n) for(int i = 0; i < n; i++)
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#define repr(i, s, e) for(int i = (s); i >= (e); --i)
#define pb push_back

template<typename T> void mk_unique(T& l) { if (!std::is_sorted(all(l))) std::sort(all(l)); auto it = std::unique(l.begin(), l.end()); auto d = std::distance(l.begin(), it); l.resize(d); }
template<typename T> T &smax(T& l, const T&r) { if(l<r) l=r; return l; }
template<typename T> T &smin(T& l, const T&r) { if(l>r) l=r; return l; }

constexpr int MOD = 998244353;//1000000007;


namespace io{
class input_reader{
void throw_error(){throw std::runtime_error("No more inputs while reading number");}
template<typename T>
inline void readIntegerValue(T&f){bool positive=true;f=0;char c;
if(!in.get(c))throw_error();
while(c<'0'||c>'9'){if(c=='-')positive=false;if(!in.get(c))throw_error();}
while(c>='0'&&c<='9'){f=(f<<3)+(f<<1)+(c&15);if(!in.get(c))break;}
if(!positive)f*=-1;}
public:
std::istream&in;
explicit input_reader(std::istream&in):in(in){}
inline void read(int&f){readIntegerValue(f);}
inline void read(short&f){readIntegerValue(f);}
inline void read(long int&f){readIntegerValue(f);}
inline void read(long long int&f){readIntegerValue(f);}
inline void read(unsigned int&f){readIntegerValue(f);}
inline void read(unsigned short&f){readIntegerValue(f);}
inline void read(unsigned long int&f){readIntegerValue(f);}
inline void read(unsigned long long int&f){readIntegerValue(f);}
template<typename T>inline void read(std::vector<T>&f){for(auto&i:f)read(i);}
template<typename T,int N>inline void read(std::array<T,N>&res){for(auto&i:res)read(i);}
template<typename T1,typename T2>inline void read(std::pair<T1,T2>&p){read(p.first,p.second);}
template<typename T>inline void read(T&f){in>>f;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t),read(args...);}
template<typename T>inline void readArray(int n,T*res){while(n--)read(*(res++));}
template<typename T>inline input_reader&operator>>(T&t){return read(t),*this;}
};
}

namespace io{
class output_writer{
std::ostream&out;
template<typename T>inline void printIntegerHelper(T x){if(x>=10)printIntegerHelper(x/10);out.put(x%10+48);}
template<typename T>inline void printInteger(T x){if(x<0)out.put('-'),x=-x;printIntegerHelper(x);}
template<typename T>inline void printArray(T&ar){bool first=true;for(auto&t:ar)print((first)? first=false,"":" ",t);}
public:
explicit output_writer(std::ostream&out):out(out){}
inline void flush(){out.flush();}
inline void print(){}
inline void print(char x){out.put(x);}
inline void print(short x){printInteger(x);}
inline void print(int x){printInteger(x);}
inline void print(long int x){printInteger(x);}
inline void print(long long int x){printInteger(x);}
inline void print(unsigned short x){printInteger(x);}
inline void print(unsigned int x){printInteger(x);}
inline void print(unsigned long int x){printInteger(x);}
inline void print(unsigned long long int x){printInteger(x);}
template<typename T1>inline void print(const T1&t1){out<<t1;}
template<typename T1>inline void print(const std::vector<T1>&t1){printArray(t1);}
template<typename T1,int N>inline void print(const std::array<T1,N>&t1){printArray(t1);}
template<typename T1,int N,int M>inline void print(const std::array<std::array<T1,M>,N>&t1){for(auto&t:t1)println(t);}
template<typename T1>inline void print(const std::vector<std::vector<T1>>&t1){bool first=true;for(auto&t:t1)print((first)? first=false,"":"\n",t);}
template<typename T,typename...Args>inline void print(const T&t,Args...args){print(t),print(args...);}
template<typename...Args>inline void println(Args...args){print(args...),print('\n');}
template<typename T>output_writer&operator<<(const T&t){return print(t),*this;}
};
}

inline ll pow_mod(ll a,ll b,const ll MOD){ll res=1;for(ll i=1;b;b^=b&i,i<<=1,a=(a*a)%MOD)if(b&i)res=(res*a)%MOD;return res;}
inline ll mod_inv(const ll a,const ll MOD){return pow_mod(a,MOD-2,MOD);}
template<typename T>inline T gcd(T a,T b){T t;while(a!=0)t=a,a=b%a,b=t;return b;}
template<typename T>T lcm(const T &a,const T &b) {assert(a!=0&&b!=0);return a/gcd(a,b)*b;}
namespace math {
template<class T> int gMOD(T v){v%=MOD;if(v<0)v+=MOD;return (int)v;};
class mod_int{
using mi=mod_int;
int v;
public:
mod_int(int v):v(gMOD(v)){}
mod_int(unsigned int v):v(gMOD(v)){}
mod_int(long long int v):v(gMOD(v)){}
mod_int(unsigned long long int v):v(gMOD(v)){}
mod_int(long int v):v(gMOD(v)){}
mod_int(unsigned long int v):v(gMOD(v)){}
mod_int()=default;
mod_int(const mi& o)=default;
mod_int(mi&& o)=default;
inline mi& operator=(const mi& o)=default;
inline mi& operator=(mi&& o)=default;
inline mi& operator++(){if(v==MOD-1)v=0;else v++;return*this;}
inline mi& operator--(){if(v==0)v=MOD-1;else v--;return*this;}
inline mi operator++(int){mi t=*this;++(*this);return t;}
inline mi operator--(int){mi t=*this;--(*this);return t;}
inline bool friend operator==(const mi&lhs,const mi&rhs){return lhs.v==rhs.v;}
inline bool friend operator!=(const mi&lhs,const mi&rhs){return lhs.v!=rhs.v;}
template<typename T> inline bool friend operator==(const mi&lhs,const T&rhs){return lhs==mi(rhs);}
template<typename T> inline bool friend operator!=(const mi&lhs,const T&rhs){return lhs!=mi(rhs);}
inline mi friend operator-(const mi&lhs,const mi&rhs){mi res;res.v=lhs.v-rhs.v;if(res.v<0)res.v+=MOD;return res;}
inline mi friend operator+(const mi&lhs,const mi&rhs){mi res;res.v=lhs.v+rhs.v-MOD;if(res.v<0)res.v+=MOD;return res;}
inline mi friend operator*(const mi&lhs,const mi&rhs){return{((((long long int)lhs.v)*rhs.v))};}
inline mi friend operator/(const mi&lhs,const mi&rhs){return lhs*rhs.inv();}
template <typename T> inline mi friend operator-(const mi&lhs,const T&rhs){return lhs-mi(rhs);}
template <typename T> inline mi friend operator+(const mi&lhs,const T&rhs){return lhs+mi(rhs);}
template <typename T> inline mi friend operator*(const mi&lhs,const T&rhs){return lhs*mi(rhs);}
template <typename T> inline mi friend operator/(const mi&lhs,const T&rhs){return lhs/mi(rhs);}
template <typename T> inline mi& operator-=(const T&rhs){return*this=*this-rhs;}
template <typename T> inline mi& operator+=(const T&rhs){return*this=*this+rhs;}
template <typename T> inline mi& operator*=(const T&rhs){return*this=*this*rhs;}
template <typename T> inline mi& operator/=(const T&rhs){return*this=*this/rhs;}
inline mi inv()const{return pow(MOD-2);}
inline mi pow(long long int pw)const{mi res,val;res.v=1,val.v=v;while(pw){if(pw&1)res*=val;val*=val;pw>>=1;}return res;}
inline operator int()const {return v;}
inline friend std::istream& operator>>(std::istream& in,mi&rhs){long long int v;in>>v;rhs={v};return in;}
inline friend std::ostream& operator<<(std::ostream& out,mi&rhs){out<<rhs.v;return out;}
};
}
namespace math {
mod_int factorial(unsigned int n) {
static std::vector<mod_int> mem;static mod_int last;
if (mem.empty()) last = {1}, mem.push_back(last);
while (!(n < mem.size())) mem.push_back(mem.back() * last++);
return mem[n];
}
mod_int n_choose_k(int n, int k){
mod_int res =  factorial(n);mod_int res2 = (factorial(k) * factorial(n-k));
return res/res2;
}
}




template<typename P, typename CMP=std::less<P>, int B = 2>
class priority_queue_with_changes {
using K = int;
const CMP cmp = CMP();
public:
priority_queue_with_changes(int n) : index(n), pq(1) { assert(B > 1); }

struct state {K key;P priority;};
private:std::vector<int> index;std::vector<state> pq;
inline bool compare_indices(int i, int j) const { return cmp(pq[i].priority, pq[j].priority); }
void heap_up(int i) {const auto pme = pq[i];while (i >> B != 0) {__builtin_prefetch(&(*pq.begin()) + (i >> (B * 4)));
const auto pnxt = pq[i >> B];if (cmp(pnxt.priority, pme.priority)) {pq[i] = pnxt, index[pnxt.key] = i;i >>= B;
} else break;}pq[i] = pme, index[pme.key] = i;}

void heap_down(unsigned int i) {const auto pme = pq[i];const size_t len = pq.size();while ((i << B) < len) {
__builtin_prefetch(&(*pq.begin()) + (((size_t) i) << (4 * B)));auto p = pq[i << B];int inxt = i << B;
for (size_t j = 1; j < 1 << B && (i << B) + j < len; j++) {auto p1 = pq[(i << B) + j];
if (cmp(p.priority, p1.priority)) p = p1, inxt = (i << B) + j;}if (cmp(pme.priority, p.priority)) {
pq[i] = p, index[p.key] = i, i = inxt;} else break;}pq[i] = pme, index[pme.key] = i;}

public:bool was_poped(K key) const { return index[key] < 0; }
void push(K key, P priority) {int &i = index[key];if (i > 0) {P before = pq[i].priority;pq[i].priority = priority;
if (cmp(before, priority)) heap_up(i); else heap_down(i);}
else {i = pq.size();pq.push_back({key, priority});heap_up(i);}}

private:size_t get_index_of_max() const {size_t res = 1;for (size_t i = 2; i < (1 << B) && i < pq.size(); ++i)
if (cmp(pq[res].priority, pq[i].priority))res = i;
return res;}

public:const state &top() const {assert(!this->empty());return pq[get_index_of_max()];}
void pop() {assert(!this->empty());int i = get_index_of_max();K key = pq[i].key;index[key] = -1;
if (i == pq.size() - 1) pq.pop_back();else {pq[i] = pq.back(), index[pq[i].key] = i, pq.pop_back();heap_down(i);}}

class changable_entry {priority_queue_with_changes &pq;K k;public:
changable_entry(priority_queue_with_changes &pq_, K k_) : pq(pq_), k(k_) {}
operator P() {assert(pq.index[k] > 0);return pq.pq[pq.index[k]].priority;}
changable_entry &operator=(P p_) {pq.push(k, p_);return *this;}};

int count(K k) const { return index[k] > 0; }
changable_entry operator[](const K &k) { return changable_entry(*this, k); }
bool empty() const { return pq.size() == 1; }
};
//#include "points_query/point_query.hpp"
//#include "numeric/numeric.hpp"
//#include "hashes/hashes.hpp"
//#include "graphs/graphs.hpp"
//#include "geometry/geometry.hpp"
//#include "extension_operations/extensions.hpp"




namespace range_update {

	/*
	 * op : T(T &previous, T current)
	 * */
	template<typename T, typename Operator>
	class ranges_array {
		struct T_in_use {
			T t;
			bool in_use = false;
		};
		const Operator op;
		mutable std::vector<T_in_use> vec;
		const int n;

		void update_index(int index, const T &val) const {
			if (vec[index].in_use) {
				vec[index].t = op(vec[index].t, val);
			} else vec[index].t = val;
			vec[index].in_use = true;
		}

		void update_index_down(int index) const {
			if (vec[index].in_use) {
				update_index(index * 2, vec[index].t);
				update_index(index * 2 + 1, vec[index].t);
				vec[index].in_use = false;
			}
		}

		void update_range(int index, int index_l, int index_r, int l, int r, const T &val) {
			if (l == index_l && r == index_r) {
				update_index(index, val);
			} else {
				update_index_down(index);
				int index_m = (index_l + index_r) / 2;
				if (l <= index_m)
					update_range(index * 2, index_l, index_m, l, std::min(r, index_m), val);
				if (r > index_m)
					update_range(index * 2 + 1, index_m + 1, index_r, std::max(l, index_m + 1), r, val);
			}
		}


		static size_t calc_vec_size(int index, int l, int r) {
			if (l == r) return (size_t) index + 1;
			auto res = std::max(calc_vec_size(index * 2, l, (l + r) / 2),
								calc_vec_size(index * 2 + 1, 1 + (l + r) / 2, r));
			return res;
		}

		void set_values(const std::vector<T> &v, int index, int l, int r) {
			if (l == r)
				vec[index] = {v[l], true};
			else {
				set_values(v, index * 2, l, (l + r) / 2);
				set_values(v, index * 2 + 1, 1 + (l + r) / 2, r);
			}
		}

	public:

		ranges_array(int n, Operator op) : n(n), op(op), vec(calc_vec_size(1, 0, n - 1)) {}

		explicit ranges_array(int n) : ranges_array(n, Operator()) {}

		ranges_array(const std::vector<T> &v, Operator op) : ranges_array(v.size(), op) {
			set_values(v, 1, 0, n - 1);
		}

		explicit ranges_array(const std::vector<T> &v) : ranges_array(v, Operator()) {}

		void update_range(int l, int r, const T &val) {
			assert(l <= r);
			update_range(1, 0, n - 1, l, r, val);
		}
//
//		class updatable_instance {
//			ranges_array<T, Operator> &rq;
//			const int index;
//		public:
//			updatable_instance(ranges_array<T, Operator> &rq, const int index) : rq(rq), index(index) {}
//
//			updatable_instance &operator=(const T &val) {
//				rq.update_range(index, index, val);
//				return *this;
//			}
//		};
//
//		updatable_instance operator[](int i) { return updatable_instance(*this, i); }

		T operator[](int i) const {
			int index = 1;
			int l1 = 0;
			int r1 = n - 1;
			while (i != l1 || i != r1) {
				update_index_down(index);
				int m = (l1 + r1) / 2;
				if (i <= m)
					index *= 2, r1 = m;
				else
					index = index * 2 + 1, l1 = m + 1;
			}
			return vec[index].t;
		}
	};

	template<typename T>
	class sum_range_update : public ranges_array<T, std::function<T(T, T)>> {
	public:
		explicit sum_range_update(const std::vector<T> &v) :
				ranges_array<T, std::function<T(T, T)>>(v, [](const T &u, const T &v) { return u + v; }) {}

		explicit sum_range_update(int n) :
				ranges_array<T, std::function<T(T, T)>>(n, [](const T &u, const T &v) { return u + v; }) {}

		explicit sum_range_update(int n, const T &val) : sum_range_update(std::vector<T>(n, val)) {}
	};


	template<typename T>
	class set_range_update : public ranges_array<T, std::function<T(T, T)>> {
	public:
		explicit set_range_update(const std::vector<T> &v) :
				ranges_array<T, std::function<T(T, T)>>(v, [](const T &u, const T &v) { return v; }) {}

		explicit set_range_update(int n) :
				ranges_array<T, std::function<T(T, T)>>(n, [](const T &u, const T &v) { return v; }) {}

		explicit set_range_update(int n, const T &val) : set_range_update(std::vector<T>(n, val)) {}
	};
}





namespace range_query {


	// What is REPEAT_MATTER:
	// 	Version is used for operator op for which:
	// 		l<=m1<=m2<=r:
	// 		F(l,r) != op(F(l,m2),F(m1,r))
	//	means that repeating element effect the op.
	template<typename T, typename Operator, bool REPEAT_MATTER = false>
	class sparse_table {
		const Operator op;
		std::vector<std::vector<T>> vec;

		static int largest_bit(int x) { return 31 - __builtin_clz(x); }

	public:
		sparse_table(std::vector<T> v, Operator op) : op(op) {
			vec.push_back(v);
			const int n = v.size();
			int currentLevelWindow = 1;
			while (currentLevelWindow * 2 <= n) {
				for (int i = 0; i + currentLevelWindow * 2 <= n; ++i) {
					v[i] = op(v[i], v[i + currentLevelWindow]);
				}
				currentLevelWindow <<= 1;
				vec.emplace_back(v.begin(), v.begin() + (n - currentLevelWindow) + 1);
			}
		}

		explicit sparse_table(const std::vector<T> &v) : sparse_table(v, Operator()) {}

		T query(int l, int r) const {
			assert(l <= r);
			if (!REPEAT_MATTER) {
				int len = r - l + 1;
				int level = 0;
				while ((1 << (level + 1)) <= len) level++;
				int level_window = 1 << level;
				r = r - level_window + 1;
				return op(vec[level][l], vec[level][r]);
			} else {
				int dif = r - l + 1;
				int i = largest_bit(dif);
				T res = vec[i][l];
				l += 1 << i;
				dif -= 1 << i;
				i = largest_bit(dif);
				for (; dif; i = largest_bit(dif)) {
					res = op(res, vec[i][l]);
					l += 1 << i;
					dif -= 1 << i;
				}
				return res;
			}
		}
	};


	template<typename T, typename Comparator = std::less<T>>
	class static_min_range_query : public sparse_table<T, std::function<T(T, T)>> {
	public:
		static_min_range_query(const std::vector<T> &v, Comparator comp) :
				sparse_table<T, std::function<T(T, T)>>(v, [=](const T &u, const T &v) {
					return comp(u, v) ? u : v;
				}) {}

		explicit static_min_range_query(const std::vector<T> &v)
				: static_min_range_query(v, Comparator()) {}
	};


	template<typename T, typename Comparator = std::less<T>>
	class static_max_range_query : public sparse_table<T, std::function<T(T, T)>> {
	public:
		static_max_range_query(const std::vector<T> &v, Comparator comp) :
				sparse_table<T, std::function<T(T, T)>>(v, [=](const T &u, const T &v) {
					return comp(u, v) ? v : u;
				}) {}

		explicit static_max_range_query(const std::vector<T> &v)
				: static_max_range_query(v, Comparator()) {}
	};

	template<typename T>
	class static_sum_range_query : public sparse_table<T, std::function<T(T, T)>> {
	public:
		explicit static_sum_range_query(const std::vector<T> &v) :
				sparse_table<T, std::function<T(T, T)>>(v, [](const T &u, const T &v) {
					return v + u;
				}) {}
	};
}




namespace range_query {

	template<typename T, typename Operator = std::function<T(const T &, const T &)>>
	class ranges_array {
		const Operator op;
		std::vector<T> vec;
		const int n;

		inline void update(int i) {
			if (i * 2 + 1 >= vec.size()) vec[i] = vec[i * 2];
			else vec[i] = op(vec[i * 2], vec[i * 2 + 1]);
		}

		inline void updateUp(int i) {
			while (i) {
				T v = vec[i];
				update(i);
//				if (vec[i] == v) break;
				i >>= 1;
			}
		}

		inline void updateRes(bool &first, T &res, const T &t1) const {
			if (first) first = false, res = t1;
			else res = op(res, t1);
		}

	public:
		ranges_array(const std::vector<T> &v, Operator op) : n(v.size()), op(op) {
			vec.resize(2 * n + 1);
			std::copy(v.begin(), v.end(), vec.begin() + n + 1);
			for (int i = n; i > 0; i--) update(i);
		}

		explicit ranges_array(const std::vector<T> &v) : ranges_array(v, Operator()) {}

		ranges_array(int n, Operator op) : n(n), op(op) { vec.resize(2 * n + 1); }

		ranges_array(int n) : ranges_array(n, Operator()) {}

		class updatable_instance {
			T &t;
			ranges_array<T, Operator> &rq;
			const int index;
		public:
			updatable_instance(T &t, ranges_array<T, Operator> &rq, const int index) : t(t), rq(rq), index(index) {}

			updatable_instance &operator=(const T &val) {
				t = val;
				rq.updateUp(index);
				return *this;
			}
		};

		updatable_instance operator[](int index) {
			return updatable_instance(vec[n + 1 + index], *this, (n + 1 + index) / 2);
		}

		const T &operator[](int index) const {
			return vec[n + 1 + index];
		}

		T query(int l, int r) const {
			assert(l <= r);
			l += n + 1;
			r += n + 1;
			if (l == r) return vec[l];
			T res;
			bool first = true;

			int li = 0, ri = 64;
			static int ar[64];
			while (l < r) {
				if (l & 1)
					ar[li++] = l++;

				if ((r & 1) == 0)
					ar[--ri] = r--;
				l >>= 1, r >>= 1;
			}
			if (l == r) ar[li++] = l;
			for (int i = 0; i < li; ++i) updateRes(first, res, vec[ar[i]]);
			for (int i = ri; i < 64; ++i) updateRes(first, res, vec[ar[i]]);
			return res;
		}

		T query() {
			return query(0, n - 1);
		}
	};


	template<typename T, typename Comparator = std::less<T>>
	class min_range_query : public ranges_array<T, std::function<T(T, T)>> {
	public:
		min_range_query(const std::vector<T> &v, Comparator comp) :
				ranges_array<T, std::function<T(T, T)>>(v, [=](const T &u, const T &v) {
					return comp(u, v) ? u : v;
				}) {}

		explicit min_range_query(const std::vector<T> &v)
				: min_range_query(v, Comparator()) {}
	};

	template<typename T, typename Comparator = std::less<T>>
	class max_range_query : public ranges_array<T, std::function<T(T, T)>> {
	public:
		max_range_query(const std::vector<T> &v, Comparator comp) :
				ranges_array<T, std::function<T(T, T)>>(v, [=](const T &u, const T &v) {
					return comp(u, v) ? v : u;
				}) {}

		explicit max_range_query(const std::vector<T> &v)
				: max_range_query(v, Comparator()) {}
	};

	template<typename T>
	class sum_range_query : public ranges_array<T, std::function<T(T, T)>> {
	public:
		explicit sum_range_query(const std::vector<T> &v) :
				ranges_array<T, std::function<T(T, T)>>(v, [](const T &u, const T &v) {
					return v + u;
				}) {}
	};
}




namespace range_query {

    template<typename K, typename T, typename Operator = std::function<T(const T &, const T &)>>
    class big_ranges_tree {
        const Operator op;

        class Node {
            const K l, r;
            T val;
            Node *left, *right;
        public:
            Node(K l, K r) : l(l), r(r), val(K()), left(nullptr), right(nullptr) {}

            ~Node() {
                if (left) delete left;
                if (right)delete right;
            }

            void set(const K i, const T v, const Operator &op) {
                const K m = (l + r) / 2;
                if (l == r) val = v;
                else {
                    if (i <= m) {
                        if (left == nullptr) left = new Node(l, m);
                        left->set(i, v, op);
                    } else {
                        if (right == nullptr) right = new Node(m + 1, r);
                        right->set(i, v, op);
                    }
                    update(op);
                }
            }

            void update(const Operator &op) {
                if (left == nullptr) {
                    if (right != nullptr) {
                        val = right->val;
                    }
                } else {
                    if (right == nullptr) val = left->val;
                    else val = op(left->val, right->val);
                }
            }

            T get(K l1, K r1, const Operator &op) const {
                if (l1 < l) l1 = l;
                if (r1 > r) r1 = r;
                if (l1 == l && r1 == r) return val;
                const K m = (l + r) / 2;
                bool left_ok = l1 <= m && left != nullptr;
                bool right_ok = r1 > m && right != nullptr;
                if (left_ok && right_ok) return op(left->get(l1, r1, op), right->get(l1, r1, op));
                if (left_ok) return left->get(l1, r1, op);
                if (right_ok) return right->get(l1, r1, op);
                else return T();
            }
        };

        Node root;

    public:
        big_ranges_tree(K l, K r, Operator op) : root(l, r), op(op) {}

        explicit big_ranges_tree(K l, K r) : big_ranges_tree(l, r, Operator()) {}

        class updatable_instance {
            big_ranges_tree<K, T, Operator> &rq;
            const K index;
        public:
            updatable_instance(big_ranges_tree<K, T, Operator> &rq, const K index) : rq(rq), index(index) {}

            updatable_instance &operator=(const T &val) {
                rq.root.set(index, val, rq.op);
                return *this;
            }
        };

        updatable_instance operator[](const K index) {
            return updatable_instance(*this, index);
        }

        const T &operator[](const K index) const {
            return root.get(index, index, op);
        }

        T query(K l, K r) const {
            assert(l <= r);
            return root.get(l, r, op);
        }

        T query() {
            return root.val;
        }
    };


    template<typename K, typename T, typename Comparator = std::less<T>>
    class min_range_query_tree : public big_ranges_tree<K, T, std::function<T(T, T)>> {
    public:
        min_range_query_tree(K l, K r, Comparator comp) :
                big_ranges_tree<K, T, std::function<T(T, T)>>(l, r, [=](const T &u, const T &v) {
                    return comp(u, v) ? u : v;
                }) {}

        explicit min_range_query_tree(K l, K r)
                : min_range_query_tree(l, r, Comparator()) {}
    };

    template<typename K, typename T, typename Comparator = std::less<T>>
    class max_range_query_tree : public big_ranges_tree<K, T, std::function<T(T, T)>> {
    public:
        max_range_query_tree(const K l, const K r, Comparator comp) :
                big_ranges_tree<K, T, std::function<T(T, T)>>(l, r, [=](const T &u, const T &v) {
                    return comp(u, v) ? v : u;
                }) {}

        explicit max_range_query_tree(const std::vector<T> &v)
                : max_range_query_tree(v, Comparator()) {}
    };

    template<typename K, typename T>
    class sum_range_query_tree : public big_ranges_tree<K, T, std::function<T(T, T)>> {
    public:
        explicit sum_range_query_tree(const K l, const K r) :
                big_ranges_tree<K, T, std::function<T(T, T)>>(l, r, [](const T &u, const T &v) {
                    return v + u;
                }) {}
    };
}



using mi = math::mod_int;
using vmi = std::vector<mi>;
using vvmi = std::vector<std::vector<mi>>;

using namespace std;

class FLISOnTree {
    class Solver {
    public:
        io::input_reader in;
        io::output_writer out;

        Solver(std::istream &in, std::ostream &out) : in(in), out(out) {}

        void print_case_number() {
            static int t = 0;
            // out <<"Case #" << ++t << ": ";
        }

        void solve() {
            print_case_number();
            // <code here>
            int n;
            in >> n;
            vi a(n);
            int maxv = 0;
            {
                vpi aa(n);
                fori(i, n) {
                    aa[i].second = i;
                    in >> aa[i].first;
                }
                sort(all(aa));
                a[aa[0].second] = 0;
                rep(i, 1, n - 1) {
                    if (aa[i].first != aa[i - 1].first) maxv++;
                    a[aa[i].second] = maxv;
                }
            }
            vvi e(n);
            fori(i, n - 1) {
                int u, v;
                in >> u >> v;
                u--, v--;
                e[u].pb(v), e[v].pb(u);
            }

            vi ans(n);
            range_query::max_range_query rq(vi(maxv+1, 0));
            function<void(int, int)> dfs = [&](int i, int p) {
                int prev_val = rq.query(a[i], a[i]);
                int longest_ending_here = 1;
                if (a[i] != 0)
                    longest_ending_here = rq.query(0, a[i] - 1) + 1;
                int longest_until_now = rq.query();
                rq[a[i]] = longest_ending_here;
                ans[i] = max(longest_ending_here, longest_until_now);

                for (int j : e[i]) {
                    if (j != p) {
                        dfs(j, i);
                    }
                }
                rq[a[i]]  = prev_val;
            };
            dfs(0, -1);
            // </code here>
            out.println(ans);
        }
    };

public:
    void solve(std::istream &in, std::ostream &out) {
        Solver(in, out).solve();
    }
};

int main() {
	std::ios_base::sync_with_stdio(false), cin.tie(0);
	FLISOnTree solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}


Measured memory_bytes: 45260