#include <algorithm>
#include <cstring>
#include <cassert>
#include <deque>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <random>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>

#ifndef ICPC_GEN_HELPER
#define ICPC_GEN_HELPER

#define SEED_FLAG "--seed"
#define MAX_UINT uint64_t

namespace icpc_gen_helper {

// Call this function to init the helper namespace
void Init(int argc, char **argv);

// Returns the string following the given parameter
// Use like this: getParam("-o")
char *getParam(const std::string &param);
char *getParam(const char *param);

// Attemps to parse the string following a given parameter
// If the parameter is not set, returns default
template <typename T>
T getParam(const std::string &param, const T &def);
template <typename T>
T getParam(const char *param, const T &def);


// Returns true if a certain string appears in the
// call parameters
// Use like this: hasFlag("-f");
bool hasFlag(const std::string &flag);
bool hasFlag(const char *flag);

// Returns a uniform number between [low, high]
// T may be an integral or a floating point type
template <typename T>
T uniform_number(T low, T high);

// Shuffles the contents of a STL container
template<class Container>
void doShuffle(Container &container);

// Shuffles the contents between two iterators
template<class RandomAccessIterator>
void doShuffle(RandomAccessIterator begin, RandomAccessIterator &end);

// Forward declaration of an internal class; do not worry about that
template<typename INTEGER>
class RandomSelectionRange;

// Creates a unique mapping of int -> int in range [low, high]
// Creates it lazily, that means it does not create the mapping
// up front, but whenever needed
template <typename INT>
class LazyMapping {
	static_assert(std::is_integral<INT>::value);
	public:
	LazyMapping(INT low, INT high);

	LazyMapping(const LazyMapping &) = delete;
	LazyMapping &operator=(const LazyMapping &) = delete;
	LazyMapping(LazyMapping &&) = default;
	LazyMapping &operator=(LazyMapping &&) = default;

	// Returns the mapping of i
	// returns i if i is not in range
	INT operator[] (INT i);

	// If the LazyMapping object is valid
	inline bool isValid() { return _mapping_generator.isValid(); }

private:
	// callback for whenever a new element needs to be mapped
	static void _callback( void *, const INT&);
	// member to hold current callback index
	INT _clbk_idx;

	std::unordered_map<INT, INT> _mapping;
	RandomSelectionRange<INT> _mapping_generator;
};

// The most flexible way to generate unique random numbers
// Allows manually selecting the next element in the sequence
// as well as generating x numbers that are not drawn yet in
// an arbitrary range [low, high]. Range does not need to be the
// same for every call, i.e. 
// generate(0,10,2); generate(-12,3,5);
// is allowed and works.
// Each generate call has worst case complexity of
// O(m log m) with m being the number of total elements; already chosen
// and to generate
template<typename INT>
class RandomGeneration {
public:
	// Make sure to only allow integer types
	static_assert(std::is_integral<INT>::value);

	using const_iterator = typename std::deque<INT>::const_iterator;

	// default CTOR
	RandomGeneration();
	// calls generateSelection in CTOR
	RandomGeneration(INT low, INT high, MAX_UINT k);

	~RandomGeneration() {}

	RandomGeneration(const RandomGeneration &) = delete;
	RandomGeneration &operator=(const RandomGeneration &) = delete;
	RandomGeneration(RandomGeneration &&) = default;
	RandomGeneration &operator=(RandomGeneration &&) = default;

	// Select a specific element
	// Returns true on success; false if element is already selected
	bool select(INT element);

	// Selects k random, unselected elements or all unselected elements
	// in range [low, high] (whichever is less)
	// Returns the number of selected elements
	MAX_UINT generateSelection(INT low, INT high, MAX_UINT k);

	// Returns true if element is already selected; false otherwise
	bool isSelected(INT element);

	// Iterators over the selected elements
	// Only const_iterators as these must not be changed
	inline const_iterator begin() { return cbegin(); }
	inline const_iterator end() { return cend(); }
	inline const_iterator cbegin() { return _selected_elements.cbegin(); }
	inline const_iterator cend() { return _selected_elements.cend(); }
	

private:
	// callback if an element is selected
	static void _callback( void *gen, const INT &sel) { 
		if(gen)
			static_cast<RandomGeneration*>(gen)->_selected_elements.push_back(sel); 
	};


	std::deque<INT> _selected_elements;
	typename std::map<INT, RandomSelectionRange<INT>> _ranges;
};

// Fastest way to quickly generate unique elements in [low; high]
// algorithm by Robert Floyd
// WARNING: Different orderings of the elements do not have the same
// probability! Shuffle the output for that!
// Or use RandomGeneration for a more flexible drawing of numbers
template <typename INT>
class FastUniqueGeneration {
	static_assert(std::is_integral<INT>::value);
public:
	using const_iterator = typename std::unordered_set<INT>::const_iterator;

	FastUniqueGeneration(INT low, INT high, MAX_UINT k);
	~FastUniqueGeneration() {}

	inline const_iterator begin() const { return cbegin(); };
	inline const_iterator end() const { return cend(); };
	inline const_iterator cbegin() const { return _selected_elements.cbegin(); }
	inline const_iterator cend() const { return _selected_elements.cend(); }

	private:
	std::unordered_set<INT> _selected_elements;
};


/****************************************************************************/



std::mt19937_64 _rng;
char **_argv;
int _argc;

inline char *getParam(const char *param) {
	for(int i = 1; i < _argc - 1; ++i) {
		if(strcmp(param, _argv[i]) == 0) return _argv[i + 1];
	}
	return nullptr;
}

inline char *getParam(const std::string &param) {
	return getParam(param.c_str());
}

template <typename T>
inline T getParam(const std::string &param, const T &def) {
	return getParam(param.c_str(), def);
}

template <typename T>
inline T getParam(const char *param, const T &def) {
	const char * s = getParam(param);
	if(!s)
		return def;
	static_assert(std::is_signed<T>::value || std::is_unsigned<T>::value , "Type not supported");
	if constexpr(std::is_signed<T>::value) {
		return std::stoll(s);
	} else if constexpr(std::is_unsigned<T>::value) {
		return std::stoull(s);
	}

	return def;
}

inline bool hasFlag(const char *flag) {
	for(int i = 1; i < _argc; ++i) {
		if(strcmp(flag, _argv[i]) == 0) return true;
	}
	return false;
}

inline bool hasFlag(const std::string &flag) {
	return hasFlag(flag.c_str());
}

void Init(int argc, char** argv) {
	_argc = argc;
	_argv = argv;
	const char *seed = getParam(SEED_FLAG);
	if(seed == nullptr) return;
	_rng.seed(std::stoull(seed));
}

// Generate a random integer or float in [low, high].
template <typename T>
T uniform_number(T low, T high) {
	assert(low <= high);
	if constexpr(std::is_integral<T>::value)
		return std::uniform_int_distribution<T>(low, high)(_rng);
	else
		return std::uniform_real_distribution<T>(low, high)(_rng);
}

template<class Container>
void doShuffle(Container &container) {
	doShuffle(container.begin(), container.end());
}

// Shuffles the contents between two iterators
template<class RandomAccessIterator>
void doShuffle(RandomAccessIterator begin, RandomAccessIterator end) {
	std::shuffle(begin, end, _rng);
}

template<typename INT>
RandomGeneration<INT>::RandomGeneration() {
	_ranges.insert( { std::numeric_limits<INT>::min(),
										RandomSelectionRange(
												std::numeric_limits<INT>::min(),
												std::numeric_limits<INT>::max())
										});
}

template<typename INT>
RandomGeneration<INT>::RandomGeneration(INT low, INT high, MAX_UINT k) : RandomGeneration() {
	generateSelection(low, high, k);
}

template<typename INT>
bool RandomGeneration<INT>::select(INT element) {
	auto upper_b = _ranges.upper_bound(element);
	return (--upper_b)->second.select(element, this, _callback) == 1;
}

template<typename INT>
bool RandomGeneration<INT>::isSelected(INT element) {
	auto upper_b = _ranges.upper_bound(element);
	return (--upper_b)->second.isSelected(element);
}

template <typename INT>
LazyMapping<INT>::LazyMapping(INT low, INT high) : _mapping_generator(low, high) { }

template <typename INT>
INT LazyMapping<INT>::operator[](INT i) {
	if(!isValid())
		return i;
	auto it = _mapping.find(i);
	if(it != _mapping.end())
		return it->second;

	if(i < _mapping_generator.getStart() || _mapping_generator.getEnd() < i)
		return i;
	_clbk_idx = i;
	_mapping_generator.draw(this, _callback);
	return _mapping[i];
}

template<typename INT>
void LazyMapping<INT>::_callback( void *obj, const INT &integer) {
	if(obj) {
		LazyMapping *lzy_obj = static_cast<LazyMapping *>(obj);
		lzy_obj->_mapping[lzy_obj->_clbk_idx] = integer;
	}
}

template<typename INT>
MAX_UINT RandomGeneration<INT>::generateSelection(INT low, INT high, MAX_UINT k) {
	if(k == 0)
		return 0;
	// Cut the range
	auto low_b = _ranges.upper_bound(low);
	--low_b;
	// If the range does not start at low, create a new range
	if(low_b->first < low) {
		_ranges.insert({low, low_b->second.split(low)});
	}

	auto high_b = _ranges.upper_bound(high);
	--high_b;
	// If the range does not end at high, create a new range
	if(high_b->second.getEnd() > high)
		_ranges.insert({high + 1, high_b->second.split(high + 1)});

	low_b = _ranges.find(low);
	high_b = _ranges.find(high + 1);
	assert(low_b != _ranges.end() && high_b != _ranges.end() && "Split failed");

	MAX_UINT rem_elements = 0;
	for(auto it = low_b; it != high_b; ++it) {
		rem_elements += it->second.unselectedSize();
	}

	k = std::min(k, rem_elements);

	FastUniqueGeneration drawn(static_cast<MAX_UINT>(0), rem_elements, k);
	std::vector<MAX_UINT> sorted_drawn;
	sorted_drawn.reserve(k);
	for(const MAX_UINT elem : drawn) {
		sorted_drawn.push_back(elem);
	}
	std::sort(sorted_drawn.begin(), sorted_drawn.end(), std::less<MAX_UINT>());

	// Assign the drawn elements to the ranges
	MAX_UINT next_rem_elements_stop = 0;
	auto sort_it = sorted_drawn.begin();
	for(auto it = low_b; it != high_b; ++it) {
		next_rem_elements_stop += it->second.unselectedSize();
		MAX_UINT generate_in_this_range = 0;
		while(sort_it != sorted_drawn.end() && *sort_it <= next_rem_elements_stop) {
			++generate_in_this_range;
			++sort_it;
		}
		it->second.generate(generate_in_this_range, this, _callback);
	}

	// shuffle
	doShuffle(_selected_elements.end() - k, _selected_elements.end());
	
	return k;
}


template<typename INTEGER>
class RandomSelectionRange {
	static_assert(std::is_integral<INTEGER>::value);
public:
	class const_iterator;

	// Select in Range [start, end]
	RandomSelectionRange(INTEGER start, INTEGER end) : _start(start),
																								 _end(end)
	{_reset();}

	~RandomSelectionRange() {}
	RandomSelectionRange(const RandomSelectionRange &) = delete;
	RandomSelectionRange &operator=(const RandomSelectionRange &) = delete;
	RandomSelectionRange(RandomSelectionRange &&) = default;
	RandomSelectionRange &operator=(RandomSelectionRange &&) = default;


	inline int_fast8_t select(INTEGER element) { return select(element, nullptr, _no_callback); }
	inline int_fast8_t select(INTEGER element, void *clbk_obj, void (*callback)(void *, const INTEGER&)) {
		if(!_valid)
			return -1;
		if(element < _start || _end < element)
			return -1;
		if(isSelected(element))
			return 0;
		_selectElem(element, clbk_obj, callback);
		return 1;
	}

	inline bool isSelected(MAX_UINT element) {
		return _elem_to_pos.find(element) != _elem_to_pos.end() &&
								_elem_to_pos[element] < _next_swap;
	}

	// draw one
	inline MAX_UINT draw() { return draw( nullptr, this->_no_callback); }
	inline MAX_UINT draw( void *clbk_obj, void (*callback)(void *, const INTEGER&)) {
		if(!_valid || _next_swap > _end)
			return 0;
		_select(uniform_number<INTEGER>(_next_swap, _end), clbk_obj, callback);
		return 1;
	}

	inline MAX_UINT generate(MAX_UINT k) { return generate(k, nullptr, _no_callback); }
	inline MAX_UINT generate(MAX_UINT k, void *clbk_obj, void (*callback)(void *, const INTEGER&)) {
		if( !_valid)
			return 0;

		k = std::min(k, unselectedSize());

		for(MAX_UINT i = 0; i < k; ++i) {
			_select(uniform_number<INTEGER>(_next_swap, _end), clbk_obj, callback);
		}
		return k;
	}

	// Splits the Selection Range at element. Returns a
	// selection range object with range [element, end]
	// After the call, this object has the range [start, element[
	// Can return an invalid object if ranges result in 0 elements
	// or element itself is out of range
	inline RandomSelectionRange split(INTEGER element) {
		if(!_valid)
			return RandomSelectionRange(element, element);
		if(element - 1 < _start || _end < element)
			return RandomSelectionRange(element, element);

		RandomSelectionRange lower(_start, element - 1);
		RandomSelectionRange upper(element, _end);
		for(const INTEGER &elem : *this ) {
			if(elem < element)
				lower._selectElem(elem);
			else
				upper._selectElem(elem);
		}
		std::swap(*this, lower);
		return upper;
	}

	inline const_iterator begin() { return cbegin(); }
	inline const_iterator end() { return cend(); }

	inline const_iterator cbegin() const {
		return const_iterator(_pos_to_elem.cbegin());
	}

	inline const_iterator cend() const {
		if(_next_swap == _start)
			return cbegin();
		auto it = _pos_to_elem.find(_next_swap - 1);
		return const_iterator(++it);
	}

	inline INTEGER getStart() const {
		return _start;
	}

	inline INTEGER getEnd() const {
		return _end;
	}

	inline MAX_UINT size() const {
		return _next_swap - _start;
	}

	inline MAX_UINT unselectedSize() const {
		return _end + 1 - _next_swap;
	}


private:
	static void _no_callback(void *, const INTEGER&) {}
	inline void _selectElem(INTEGER element) { _selectElem(element, nullptr, _no_callback); }
	inline void _selectElem(INTEGER element, void *clbk_obj, void (*callback)(void *, const INTEGER&)) {
		auto it = _elem_to_pos.find(element);
		if(it != _elem_to_pos.end()) {
			element = it->second;
		}
		_select(element, clbk_obj, callback);
	}

	inline void _select(INTEGER idx) { _select(idx, nullptr, _no_callback); }
	inline void _select(INTEGER idx, void *clbk_obj, void (*callback)(void *, const INTEGER&)) {
		auto pos_ptr_0 = _pos_to_elem.insert({idx, idx});
		auto num_ptr_0 = _elem_to_pos.insert({(*pos_ptr_0.first).second, idx});
		auto pos_ptr_1 = _pos_to_elem.insert({_next_swap, _next_swap});
		auto num_ptr_1 = _elem_to_pos.insert({(*pos_ptr_1.first).second, _next_swap});

		std::swap((*pos_ptr_0.first).second, (*pos_ptr_1.first).second);
		std::swap((*num_ptr_0.first).second, (*num_ptr_1.first).second);
		callback(clbk_obj, pos_ptr_1.first->second);
		++_next_swap;
	}

	inline void _reset() {
		_next_swap = _start;
		_pos_to_elem.clear();
		_elem_to_pos.clear();
		_valid = _start <= _end;
	}

	INTEGER _start;
	INTEGER _end;
	INTEGER _next_swap;
	std::unordered_map<INTEGER, INTEGER> _pos_to_elem;
	std::unordered_map<INTEGER, INTEGER> _elem_to_pos;
	bool _valid;

public:
	class const_iterator {
	public:
		const_iterator(typename std::unordered_map<INTEGER, INTEGER>::const_iterator it) : _it(it) {}

		using value_type = INTEGER;
		using reference = const INTEGER&;
		using pointer = const INTEGER*;
		using difference_type = std::ptrdiff_t;
		using iterator_category	= std::random_access_iterator_tag;

		inline const_iterator operator++(int) { const_iterator tmp(*this); ++_it; return tmp;}
		inline const_iterator &operator++() {++_it; return *this;}
		inline const_iterator operator--(int) { const_iterator tmp(*this); --_it; return tmp;}
		inline const_iterator &operator--() {--_it; return *this;}

		inline const_iterator operator+ (difference_type n) const { return const_iterator(_it + n); }
		inline const_iterator operator- (difference_type n) const { return const_iterator(_it - n); }
		inline const_iterator &operator+= (difference_type n) { _it += n; return *this; }
		inline const_iterator &operator-= (difference_type n) { _it -= n; return *this; }

		inline difference_type operator- (const const_iterator &other) const { return _it - other._it; }

		inline reference operator *() const { return (*_it).second; }
		inline pointer operator ->() const { return &**this; }
		inline reference operator[] ( difference_type n ) const { return _it[n].second; }

		inline bool operator== (const const_iterator &other) const {
			return _it == other._it;
		}
		inline bool operator!= (const const_iterator &other) const {
			return _it != other._it;
		}
		inline bool operator< (const const_iterator &other) const {
			return _it < other._it;
		}
		inline bool operator<= (const const_iterator &other) const {
			return _it <= other._it;
		}
		inline bool operator> (const const_iterator &other) const {
			return _it > other._it;
		}
		inline bool operator>= (const const_iterator &other) const {
			return _it >= other._it;
		}

	private:
	typename std::unordered_map<INTEGER,INTEGER>::const_iterator _it;
	};
};

template <typename INT>
FastUniqueGeneration<INT>::FastUniqueGeneration(INT low, INT high, MAX_UINT k) {
	if(high < low || k == 0)
		return;
	k = std::min(static_cast<MAX_UINT>(high-low), k - 1) + 1;
	// It is so complicated for the corner case of low = smallest INT and hig = max INT
	// There is no higher number than high!!
	INT j = high - static_cast<INT>(k);
	do {
		++j;
		INT elem = uniform_number(low, j);
		if(_selected_elements.find(elem) == _selected_elements.end())
			_selected_elements.insert(elem);
		else
			_selected_elements.insert(j);
	} while(j < high);
}

};

#endif
