//ac!
//这题还要再看,因为是参考了别人代码的
//f[i]=0;//这一句很关键,之前这一句忘记了,结果就怎么也不输出
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int f[25];//标记是否已经进入队列中
int ans[25];//结果序列
int n;
int isprime(int k){
int q=sqrt(k);
for(int j=2;j<=q;j++){
if(k%j==0) return 0;
}
return 1;
}
void dfs(int k,int now){//k是当前深度,now是当前已确定序列的最后一个数
if(k==n){//已经是全部结束了,要输出了
//必须注意的是,头和尾也要验证一下
if(isprime(now+1)){
for(int i=0;i<n;i++){
printf("%d%c",ans[i],i==n-1?'\n':' ');
}
}
}
else{
for(int i=2;i<=n;i++){//对每一个位置进行枚举从2~n的数。而现在在第几个位置通过k来体现
if(!f[i]&&isprime(now+i)){
f[i]=1;
ans[k]=i;//序列中增加一个数
dfs(k+1,i);//当前深度加1
f[i]=0;//这一句很关键,之前这一句忘记了,结果就怎么也不输出
}
}
}
}
int main(){
int ncase=1;
while(scanf("%d",&n)!=EOF){
printf("Case %d:\n",ncase++);
memset(f,0,sizeof(f));
ans[0]=1;//第0层必是1
dfs(1,1);
putchar('\n');
}
return 0;
}
//自己写的,ac
#include<cstdio>
#include<cmath>
using namespace std;
int a[101]={0},v[101]={0};
int n;
bool isprime(int m){
int q=sqrt(m);
for(int i=2;i<=q;i++){
if(m%i==0) return false;//这个地方一开始这么简单的函数写错了!i写成了q
}
return true;
}
void print(){
for(int i=0;i<n;i++){
printf("%d%c",a[i],i==n-1?'\n':' ');
}
}
void DFS(int k,int now){
if(k==n){//当前需要考虑下标为n的数时,就是退出的时候
if(isprime(now+1)) print();
return;
}
else{
//对当前位进行逐一枚举从1~n
for(int i=2;i<=n;i++){
if(!v[i]&&isprime(now+i)){
v[i]=1;
a[k]=i;
DFS(k+1,i);
v[i]=0;//如果没有选这个的话?
}
}
}
return ;
}
int main(){
scanf("%d",&n);
a[0]=1;
DFS(1,1);//当前需要考虑的下标为1的值 第一个数已经确定,现在考虑的层数是1层,0层已经确定了。
return 0;
}