/*
分析:
最小生成树水题,就当又温习了一遍了,囧~
2012-09-16
*/
#include"stdio.h"
#include"math.h"
#include"string.h"
#include"stdlib.h"
int vi[611];
int prime[2000111];
struct A
{
int a,b;
int len;
}eage[180000];
int tot;
//并查集
int set[611];
void build(int n)
{
int i;
for(i=0;i<n;i++) set[i]=i;
}
int find(int k)
{
if(set[k]==k) return k;
set[k]=find(set[k]);
return set[k];
}
void Union(int f1,int f2)
{
set[f1]=f2;
}
int MIN(int a,int b)
{
return a>b?b:a;
}
int cmp(const void *a,const void *b)
{
struct A *c,*d;
c=(struct A *)a;
d=(struct A *)b;
return c->len-d->len;
}
int main()
{
int T;
int n;
int i,l;
int temp;
int f1,f2;
int cost;
memset(prime,-1,sizeof(prime));
prime[0]=prime[1]=0;
for(i=2;i<=2000000;i++)
{
if(prime[i]==-1)
{
for(temp=2*i;temp<=2000000;temp+=i) prime[temp]=0;
}
}
scanf("%d",&T);
while(T--)
{
//读入
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d",&vi[i]);
//建边
tot=0;
for(i=0;i<n;i++)
for(l=i+1;l<n;l++)
{
if(prime[vi[i]] || prime[vi[l]] || prime[vi[i]+vi[l]])
{
eage[tot].a=i;
eage[tot].b=l;
eage[tot].len=MIN(vi[i],MIN(vi[l],abs(vi[i]-vi[l])));
tot++;
}
}
qsort(eage,tot,sizeof(eage[0]),cmp);
//最小树
cost=0;
build(n);
for(i=0;i<tot;i++)
{
f1=find(eage[i].a);
f2=find(eage[i].b);
if(f1==f2) continue;
cost+=eage[i].len;
Union(f1,f2);
}
//结果
temp=0;
for(i=0;i<n;i++) if(set[i]==i) temp++;
if(temp>1) printf("-1\n");
else printf("%d\n",cost);
}
return 0;
}