#include <iostream>

template<class A, class B>
struct P;

template<class... Ts>
struct L {using type=L;};

template<class T, class... Ts>
using mul = L<P<T, Ts>...>;

template<class...>
struct cat;
template<class...Ts>
using cat_t=typename cat<Ts...>::type;

template<class... Ts>
struct cat<L<Ts...>>:
	L<Ts...> 
{};

template<class... As, class... Bs>
struct cat<L<As...>, L<Bs...>>:
	L<As...,Bs...>
{};

template<class A, class B, class... Ts>
struct cat<A, B, Ts...>:
	cat< cat_t<A,B>, Ts... >
{};

template<class A, class B>
struct join;

template<class... As, class... Bs>
struct join<L<As...>, L<Bs...>>:
	cat<mul<As, Bs...>...>
{};
template<class A, class B>
using join_t=typename join<A,B>::type;

int main() {
	// your code goes here
	return 0;
}