/*这个汉诺塔的难点在于如何控制,在指定的步数内终止递归调用。纵观汉诺塔的递归方法,我们不难看出,汉诺塔中间很多步其实都是为了移动最后一个盘子,这样就好办了,现在我们只要看在指定的步数内,能不能移动最后一个盘子就可以了。如果能在指定步数内直接移动第n个盘子,那么就相当于,可以把1柱子上n-1个盘移动到2柱子上,第n个盘子移动到3柱子上;如果不能说明第n个盘仍然只能留在1柱子上,继续试探第n-1个盘能否直接移动到柱子3上.........依次类推,很明显的递归题*/
#include <iostream>
#include <cstdio>
using namespace std;
typedef unsigned __int64 LL;
LL a[64];
void hanoi(int n,LL m,LL *x,LL *y,LL *z)
{
int i;
if(m>a[n-1])
{
z[z[0]++]=n;
hanoi(n-1,m-a[n-1],y,x,z);
}
else if(m==a[n-1])
{
z[z[0]++]=n;
for(i=1;i<n;i++) y[y[0]++]=n-i;
}
else
{
x[x[0]++]=n;
hanoi(n-1,m,x,z,y);
}
}
int main ()
{
//freopen("r.txt","r",stdin);
LL x[64],y[64],z[64],n,m;
int i,t,k;
for(a[0]=1,i=1;i<64;i++) a[i]=a[i-1]<<1;
for(scanf("%d",&t),k=0;k<t;k++)
{
x[0]=y[0]=z[0]=1;
scanf("%I64u%I64u",&n,&m);
hanoi(n,m,x,y,z);
printf("%I64u",x[0]-1);
for(i=1;i<x[0];i++) printf(" %I64u",x[i]);
puts("");
printf("%I64u",y[0]-1);
for(i=1;i<y[0];i++) printf(" %I64u",y[i]);
puts("");
printf("%I64u",z[0]-1);
for(i=1;i<z[0];i++) printf(" %I64u",z[i]);
puts("");
}
return 0;
}