#define tl template
#define tn typename
#define st struct
#define cl class
#define us using
template<tn A> st Typ { using type = A; };
tl<tn T> using GetT = tn T::type;
tl<tn F, tn ...As> us apply = tn F::tl apply<As...>;
tl<tn, tn, tn ...> st LoopElements;
tl<tn, tn> st Loop;
tl<tn, tn, tn> st VLoop_i;
tl<tn Sq, tn MF> us VLoop = VLoop_i<GetT<Sq>, Sq, MF>;
//
// TY
//
template<tn T> struct Ty {
template<T ...> struct Pack : Typ<T> {};
tl<tn ...> st Concat_i; tl<tn ...P> us Concat = GetT<Concat_i<P...>>;
tl<T, int64_t> st Seq_i; tl<T f, T t> us Seq = GetT<Seq_i<f, ((int64_t)(t - f))>>; tl<int64_t, tn> st add;
template<tl<T ...> tn C, T ...vs, tl<T ...> tn D, T ...ws, tn ...R> st Concat_i<C<vs...>, D<ws...>, R...> : Typ<Concat<C<vs..., ws...>, R...> >{};
template<tl<T ...> tn C, T ...vs> st Concat_i<C<vs...>> : Typ<C<vs...> >{};
template<int64_t x, T ...vs> struct add<x, Pack<vs...>> : Typ<Pack<((T)(vs + x))...>> {};
template<T f, int64_t c> class Seq_i {
using A = tn Seq_i<f, c/2>::type;
using B = tn add<c/2, A>::type;
using C = tn Seq_i<f + c / 2 * 2, c & 1>::type;
public:
using type = Concat<A, B, C>;
};
tl<T f> st Seq_i<f, 0> : Typ<Pack<>> {};
tl<T f> st Seq_i<f, 1> : Typ<Pack<f>> {};
tl<T f> st Seq_i<f, -1> : Typ<Pack<f>> {};
};
//
// LOOP
template<size_t i, tn F, tn T> struct LoopElement { LoopElement() { apply<F, T>(); }; };
template<size_t ...is, tn F, tn ...P> struct LoopElements<Ty<size_t>::Pack<is...>, F, P...> : LoopElement<is, F, P>... {};
template<tn F, tl<tn ...> cl C, tn ...P> struct Loop<F, C<P...>> : LoopElements<Ty<size_t>::Seq<0, sizeof...(P)>, F, P...> {};
template<tn T, tl<T ...> cl ST, T ...vs, tn MF> struct VLoop_i<T, ST<vs...>, MF> : LoopElements<Ty<size_t>::Seq<0, sizeof...(vs)>, MF, Val<T, vs>...> {};