/*
题意:
给出车站数N,时刻T,t[i]: i->i+1车站需时间,从1->N方向的m1辆车的发车时间,N->1方向的发车时间,
求从1->N最短时间。
分析:
求最短时间,最终状态是T时刻到达N,dp[T][N];
由于要递推出答案,设dp[i][j]为i时刻,位于车站j到达车站N还需的时间,
每个状态则有三种转移方向:
dp[i][j]=dp[i+1][j] 原地等待下一车
=dp[i+t[j]][j+1] 如果i时刻j站点有向右的车,则搭上向右的车
=dp[i+t[j-1]][j-1] 如果i时刻j站点有向左的车,则搭上向左的车
从后向前递推,答案是dp[0][1]
判断i时刻j站点是否有车还需要预处理一下,用 is_train[i][j][0]记录右向的,is_train[i][j][1]记录左向的。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <limits.h>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
int N,T,m1,m2,t[60],is_train[250][60][2],M1[60],M2[60],dp[250][60];
void read()//读入数据
{
scanf("%d",&T);
for(int i=1;i<=N-1;i++)
scanf("%d",&t[i]);
scanf("%d",&m1);
for(int i=1; i<=m1; i++)
scanf("%d",&M1[i]);
scanf("%d",&m2);
for(int i=1; i<=m2; i++)
scanf("%d",&M2[i]);
}
void pre()//预处理
{
memset(is_train,0,sizeof(is_train));
int i,j;
for(i=1;i<=m1;i++)//对每一辆车
{
int temp=M1[i];
is_train[temp][1][0]=1;
for(j=1;j<N;j++)//记录这辆车到每个站点的时刻,然后记录
{
temp+=t[j];
if(temp<=T)
is_train[temp][j+1][0]=1;
else
break;
}
}
for(i=1;i<=m2;i++)
{
int temp=M2[i];
is_train[temp][N][1]=1;
for(j=N-1;j>=1;j--)
{
temp+=t[j];
if(temp<=T)
is_train[temp][j][1]=1;
else
break;
}
}
}
void solve()//递归
{
for(int i=1; i<=N-1; i++)
{
dp[T][i]=INF;
}
dp[T][N]=0;
int i,j;
for(i=T-1; i>=0; i--)
{
for(j=1; j<=N; j++)
{
dp[i][j]=dp[i+1][j]+1;
if(j<=N-1&&is_train[i][j][0]&&i+t[j]<=T)
dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);
if(j>=2&&is_train[i][j][1]&&i+t[j-1]<=T)
dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]);
}
}
}
int main()
{
//freopen("1025in.txt","r",stdin);
int casee=1;
while((scanf("%d",&N)!=EOF)&&N)
{
read();//读入数据
pre();//预处理
solve();//递归
if(dp[0][1]>=INF)
printf("Case Number %d: impossible\n",casee++);
else
printf("Case Number %d: %d\n",casee++,dp[0][1]);
}
return 0;
}