#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// quick sieve primes below n
int sieve(int n,int**p,int*l){
 if(n<2) return -1;
 else if(n==2){
  *l=1;
  *p=(int*)malloc(*l*sizeof(int));
  (*p)[0]=2;
  return 0;
 }
 int tmpl=(n+1-3+1)/2;
 int *s=(int*)malloc(tmpl*sizeof(int));
 double mr=sqrt(n);
 int i=0,m=3,j,h=(n+1)/2-1;
 for(;i<tmpl;i++) s[i]=3+2*i;
 i=0;
 while(m<=mr){
  if(s[i]){
   j=(m*m-3)/2;
   s[j]=0;
   while(j<h){
    s[j]=0;
    j+=m;
   }
  }
  i++;
  m=2*i+3;
 }
 h=1;
 for(i=0;i<tmpl;i++) if(s[i]) h++;
 *p=(int*)malloc(h*sizeof(int));
 (*p)[0]=2;
 h=1;
 for(i=0;i<tmpl;i++)
  if(s[i]) (*p)[h++]=s[i];
 free(s);
 *l=h;
 return 0;
}

// test for primality
int ispr(int n){
 double m=1+sqrt(n);
 if(n%2==0) return 0;
 int d=3;
 while(d<m){
  if(n%d==0)return 0;
  d+=2;
 }
 return 1;
}

int digits(int n){
 return (int)(1+floor(log(n)/log(10)));
}
 
int pow_10[]={1,10,100,1000,10000};

// test if n can form prime with numbers from l
int test(int*l,int ll,int n){
 int i=0,y,yd,nd=digits(n);
 for(;i<ll;i++){
  y=l[i];
  yd=digits(y);
  if(!(ispr(y*pow_10[nd]+n)&&ispr(n*pow_10[yd]+y)))
   return 0;
 }
 return 1;
}

int main() {
 int *pr=NULL,N=0;
 sieve(10000,&pr,&N);
#define K 5
 int l[K];
 int i=0,c[K]={0},cf[K]={N-K+1,N-K+2,N-K+3,N-K+4,N-K+5};
 for(i=1;i<K;i++)c[i]=-1;
 i=c[0]=0;

 while(1){
  // jump out of the loop?
  if(!(c[i]<cf[i])){
   if(i==0){
    break;
   }
   c[i]=-1;
   i-=1;
   c[i]+=1;
   continue;
  }
  // init loop?
  if(c[i]==-1){
   c[i]=c[i-1]+1;
  }
  l[i]=pr[c[i]];
  // start new loop
  if(i==0 || test(l,i,pr[c[i]])){
   i+=1;
   if(i==K){
    // most inner loop body
    printf("%d %d %d %d %d (%d)\n",l[0],l[1],l[2],l[3],l[4],l[0]+l[1]+l[2]+l[3]+l[4]);
    break;
   }
  }else{
   c[i]+=1;
  }
 }

 free(pr);
 return 0;
}
