Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). The i-th fox is ai years old.
They will have dinner around some round tables. You want to distribute foxes such that:
- Each fox is sitting at some table.
- Each table has at least 3 foxes sitting around it.
- The sum of ages of any two adjacent foxes around each table should be a prime number.
If k foxes f1, f2, ..., fk are sitting around table in clockwise order, then for 1 ≤ i ≤ k - 1: fi and fi + 1 are adjacent, and f1 and fk are also adjacent.
If it is possible to distribute the foxes in the desired manner, find out a way to do that.
Input
The first line contains single integer n (3 ≤ n ≤ 200): the number of foxes in this party.
The second line contains n integers ai (2 ≤ ai ≤ 104).
Output
If it is impossible to do this, output "Impossible".
Otherwise, in the first line output an integer m (): the number of tables.
Then output m lines, each line should start with an integer k -=– the number of foxes around that table, and then k numbers — indices of fox sitting around that table in clockwise order.
If there are several possible arrangements, output any of them.
Sample Input
4
3 4 8 9
1
4 1 2 4 3
5
2 2 2 2 2
Impossible
12
2 3 4 5 6 7 8 9 10 11 12 13
1
12 1 2 3 6 5 12 9 8 7 10 11 4
24
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
3
6 1 2 3 6 5 4
10 7 8 9 12 15 14 13 16 11 10
8 17 18 23 22 19 20 21 24
建二分图,再用流量为2限制度数,即可用网络流AC。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 const int N=210,M=60010,INF=1000000000; 7 int cnt,fir[N],fron[N],nxt[M],to[M],cap[M]; 8 int dis[N],gap[N],path[N],vis[N],q[N],h,t; 9 int n,m,a[N],tp[N],tot;vector<int>ans[N]; 10 struct Net_Flow{ 11 void Init(){ 12 memset(fir,0,sizeof(fir)); 13 memset(gap,0,sizeof(gap)); 14 memset(dis,0,sizeof(dis)); 15 h=t=cnt=1; 16 } 17 void addedge(int a,int b,int c){ 18 nxt[++cnt]=fir[a];to[fir[a]=cnt]=b;cap[cnt]=c; 19 nxt[++cnt]=fir[b];to[fir[b]=cnt]=a;cap[cnt]=0; 20 } 21 bool BFS(int S,int T){ 22 dis[q[h]=T]=1; 23 while(h<=t){ 24 int x=q[h++]; 25 for(int i=fir[x];i;i=nxt[i]) 26 if(!dis[to[i]])dis[q[++t]=to[i]]=dis[x]+1; 27 } 28 return dis[S]; 29 } 30 int ISAP(int S,int T){ 31 if(!BFS(S,T))return 0; 32 for(int i=S;i<=T;i++)gap[dis[i]]+=1; 33 for(int i=S;i<=T;i++)fron[i]=fir[i]; 34 int ret=0,f,p=S,Min; 35 while(dis[S]<=T+1){ 36 if(p==T){f=INF; 37 while(p!=S){ 38 f=min(f,cap[path[p]]); 39 p=to[path[p]^1]; 40 }ret+=f,p=T; 41 while(p!=S){ 42 cap[path[p]]-=f; 43 cap[path[p]^1]+=f; 44 p=to[path[p]^1]; 45 } 46 } 47 for(int &i=fron[p];i;i=nxt[i]) 48 if(cap[i]&&dis[to[i]]==dis[p]-1){ 49 path[p=to[i]]=i;break; 50 } 51 if(!fron[p]){ 52 if(!--gap[dis[p]])break;Min=T+1; 53 for(int i=fir[p];i;i=nxt[i]) 54 if(cap[i])Min=min(Min,dis[to[i]]); 55 gap[dis[p]=Min+1]+=1;fron[p]=fir[p]; 56 if(p!=S)p=to[path[p]^1]; 57 } 58 } 59 return ret; 60 } 61 void DFS(int x,int id){ 62 vis[x]=1;ans[id].push_back(x); 63 for(int i=fir[x];i;i=nxt[i]){ 64 if(vis[to[i]]||to[i]<1||to[i]>n)continue; 65 if(a[to[i]]%2==0&&cap[i^1]==0)DFS(to[i],id); 66 if(a[to[i]]%2!=0&&cap[i]==0)DFS(to[i],id); 67 } 68 } 69 void Solve(int S,int T){ 70 for(int x=1;x<=n;x++) 71 if(a[x]%2==0&&!vis[x]) 72 DFS(x,++tot); 73 printf("%d ",tot); 74 for(int i=1;i<=tot;i++){ 75 printf("%d ",ans[i].size()); 76 for(int j=0;j<ans[i].size();j++) 77 printf("%d ",ans[i][j]); 78 puts(""); 79 } 80 } 81 }isap; 82 int S,T; 83 bool Check(int x){ 84 for(int i=2;i*i<=x;i++) 85 if(x%i==0)return false; 86 return true; 87 } 88 int main(){ 89 scanf("%d",&n);isap.Init();T=n+1; 90 if(n%2==1){puts("Impossible");return 0;} 91 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 92 for(int i=1;i<=n;i++){ 93 if(a[i]%2==0)isap.addedge(S,i,2); 94 else isap.addedge(i,T,2); 95 } 96 for(int i=1;i<=n;i++)if(a[i]%2==0) 97 for(int j=1;j<=n;j++)if(a[j]%2) 98 if(Check(a[i]+a[j])) 99 isap.addedge(i,j,1); 100 if(isap.ISAP(S,T)!=n){ 101 puts("Impossible"); 102 return 0; 103 } 104 isap.Solve(S,T); 105 return 0; 106 }