B. Prime Ring Plus
因为 define int long long 边数开小 狂wa
我们将原点向 奇数连 2的流量
偶数想 汇点连2的流量
奇数和偶数能凑成质数的话 连 1的流量
跑最大流
如果 两个数之间的流量为0了证明可以在一个环
我们用度数去判断是否有解
#include <bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef pair<int, int> pii;
#define x first
#define y second
#define pb push_back
#define inf 1e18
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fer(i,a,b) for(int i=a;i<=b;i++)
#define der(i,a,b) for(int i=a;i>=b;i--)
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
int qmi( int a, int b ) {
int res = 1;
while( b ) {
if( b & 1 ) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
const int N = 1e6 + 10;
int dr[4][2] = {{ -1, 0}, {1, 0}, {0, -1}, {0, 1}};
int n, k;
const int V = 20010;
const int E = 1e7+10;
int p[N];
int vis[N];
int cnt;
void init( int n = 20001 ) {
for( int i = 2; i <= n; i++ ) {
if( !vis[i] )p[cnt++] = i;
for( int j = 0; j < cnt && i * p[j] <= n; j++ ) {
vis[i * p[j]] = 1;
if( i % p[j] == 0 )break;
}
}
return ;
}
template<typename T>
struct FlowGraph {
int s, t, vtot;
int h[V], idx;
int d[V], cur[V];
int e[E * 2];
int ne[E * 2];
int f[E * 2];
/*struct edge {
int v, nxt;
T f;
} e[E * 2];
void addedge(int u,int v, T f){
e[etot]= {v, head[u], f}; head[u] = etot++;
e[etot]= {u, head[v], 0}; head[v] = etot++;
}*/
void add( int a, int b, int c ) {
e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++;
e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx++;
}
bool bfs() {
for ( int i = 1; i <= vtot; i++ ) {
d[i] = 0;
cur[i] = h[i];
}
queue<int> q;
q.push( s );
d[s] = 1;
while ( !q.empty() ) {
int u = q.front();
q.pop();
for ( int i = h[u]; ~i; i = ne[i] ) {
int v = e[i];
if ( f[i] && !d[v] ) {
d[v] = d[u] + 1;
if ( v == t ) return true;
q.push( v );
}
}
}
return false;
}
/* T dfs(int u, T m) {
if (u == t) return m;
T flow = 0;
for (int i = cur[u]; ~i; cur[u] = i = ne[i]){
int v=e[i];
if (f[i] && d[v] == d[u] + 1) {
T t = dfs(v, min(m-flow, f[i]));
if(!t)d[v]=-1;
f[i] -= t;
f[i ^ 1] += t;
flow+=t;
}
}
return flow;
}*/
T dfs( int u, T m ) {
if ( u == t ) return m;
T flow = 0;
for ( int i = cur[u]; ~i; cur[u] = i = ne[i] )
if ( f[i] && d[e[i]] == d[u] + 1 ) {
T t = dfs( e[i], min( m, f[i] ) );
f[i] -= t;
f[i ^ 1] += t;
m -= t;
flow += t;
if ( !m ) break;
}
if ( !flow ) d[u] = -1;
return flow;
}
T dinic() {
T flow = 0;
while ( bfs() ) flow += dfs( s, numeric_limits<T>::max() );
return flow;
}
void init( int s_, int t_, int vtot_ ) {
s = s_;
t = t_;
vtot = vtot_;
idx = 0;
for ( int i = 1; i <= vtot; i++ ) h[i] = -1;
}
};
FlowGraph<int> G;
vector<array<int, 3>>ve;
int ans;
vector<int>res[N];
vector<int>g[N];
int d[N];
int v[N];
void dfs( int u ) {
v[u] = 1;
res[ans].push_back( u );
for( auto t : g[u] ) {
if( !v[t] )dfs( t );
}
}
int s, t;
void solve() {
cin >> n;
init();
s = n + 1;
t = n + 2;
G.init( s, t, t );
for( int i = 1; i <= n; i++ ) {
if( i & 1 )G.add( s, i, 2 );
else G.add( i, t, 2 );
}
for( int i = 1; i <= n; i += 2 ) {
for( int j = 1; j <= n / 2; j++ ) {
if( !vis[i + 2 * j] ) {
ve.push_back( {i, 2 * j, G.idx} );
G.add( i, 2 * j, 1 );
}
}
}
bool f = 1;
int ttt = G.dinic();
if(ttt!=n)f=0;
for( auto v : ve ) {
if( !G.f[v[2]] ) {
g[v[0]].push_back( v[1] );
g[v[1]].push_back( v[0] );
d[v[0]]++;
d[v[1]]++;
}
}
for( int i = 1; i <= n; i++ ) {
if( d[i] != 2 ) {
f = 0;
break;
}
}
if( !f ) {
cout << -1 << endl;
return ;
}
for( int i = 1; i <= n; i++ ) {
if( !v[i] ) {
ans++;
dfs( i );
}
}
cout << ans << endl;
for( int i = 1; i <= ans; i++ ) {
cout << res[i].size() << " ";
for( auto v : res[i] ) {
cout << v;
if( v == res[i].back() )cout << endl;
else cout<<" ";
// cout<<v<<(v==res[i].back()?'\n':" ");
}
}
}
int main() {
IOS;
int _ = 1;
//cin>>_;
while( _-- )
solve();
}