#include #include #include #include using namespace std; #define INF (1LL<<60) #define MAXN 333 #define MAXM 3333*666 struct Edge{ int u,v,next; long long cap,cost; }edge[MAXM]; int head[MAXN]; int NV,NE,vs,vt; void addEdge(int u,int v,long long cap,long long cost){ edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost; edge[NE].next=head[u]; head[u]=NE++; edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost; edge[NE].next=head[v]; head[v]=NE++; } bool vis[MAXN]; long long dis[MAXN]; int pre[MAXN]; bool SPFA(){ for(int i=0; i que; que.push(vs); while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap && dis[v]>dis[u]+edge[i].cost){ dis[v]=dis[u]+edge[i].cost; pre[v]=i; if(!vis[v]){ vis[v]=1; que.push(v); } } } vis[u]=0; } return dis[vt]!=INF; } long long MCMF(){ long long res=0; while(SPFA()){ long long flow=INF,cost=0; for(int u=vt; u!=vs; u=edge[pre[u]].u){ flow=min(flow,edge[pre[u]].cap); } for(int u=vt; u!=vs; u=edge[pre[u]].u){ edge[pre[u]].cap-=flow; edge[pre[u]^1].cap+=flow; cost+=flow*edge[pre[u]].cost; } res+=cost; } return res; } long long d[MAXN][MAXN]; long long gcd(long long a,long long b){ if(b==0) return a; return gcd(b,a%b); } bool ok[MAXN][MAXN]; long long key[MAXN],val[MAXN]; int main(){ int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1; i<=n; ++i){ scanf("%lld",key+i); } for(int i=1; i<=n; ++i){ scanf("%lld",val+i); } memset(ok,0,sizeof(ok)); for(int i=1; i<=n; ++i){ for(int j=i+1; j<=n; ++j){ if(gcd(key[i],key[j])==1) continue; ok[i][j]=1; ok[j][i]=1; } } for(int i=1; i<=n; ++i){ for(int j=1; j<=n; ++j){ d[i][j]=-INF; } } for(int len=2; len<=n; ++len){ for(int i=1; i+len-1<=n; ++i){ if(ok[i][i+len-1] && len==2){ d[i][i+len-1]=val[i]+val[i+len-1]; continue; } if(ok[i][i+len-1]) d[i][i+len-1]=max(d[i][i+len-1],val[i]+val[i+len-1]+d[i+1][i+len-1-1]); for(int j=0; j