import java.util.*; public class Ether { private int[][][][] memo; private int N, M, L, BIG = 1 << 25; private int[] cables, libraries, sumCables, BIGs = {BIG, BIG}; private static int[][][] combinations = new int[1024][10][]; private static int[][] indexs = new int[1024][]; private static int[] bitCount = new int[1024]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(true) { Ether ether = new Ether(); if(!ether.read(sc)) break; ether.solve(); } } private boolean read(Scanner sc){ N = sc.nextInt(); M = sc.nextInt(); L = sc.nextInt(); if(N + M + L == 0) return false; libraries = new int[N]; for(int i = 0; i < N; i++) libraries[i] = sc.nextInt(); cables = new int[M]; for(int i = 0; i < M; i++) cables[i] = sc.nextInt(); sumCables = new int[1 << M]; for(int E = 1, sum = 0; E < (1 << M); E++, sum = 0){ for(int e : indexs[E]) sum += cables[e]; sumCables[E] = sum; } return true; } private void init() { memo = new int[L + 1][1 << N][1 << M][2]; for(int i = 0; i <= L; i++) for(int S = 1, index = 0; S < (1 << N); S++, index = 0) if(bitCount[S] == 1) { for(int E = 1; E < (1 << M); E++) init(i, S, E); } else { int[] dis = new int[bitCount[S]]; for(int k : indexs[S]) dis[index++] = Math.abs(i - libraries[k]); Arrays.sort(dis); for(int E = 1; E + 1 < (1 << M); E++) if(bitCount[E] < bitCount[S]) memo[i][S][E] = BIGs; else init(i, S, E, dis); } } private void init(int index, int S, int E){ int length = Math.abs(index - libraries[indexs[S][0]]), maxSumCable = sumCables[E]; if(maxSumCable < length) { memo[index][S][E] = BIGs; } else if(maxSumCable == length) { memo[index][S][E][0] = bitCount[E]; } else { int hub = BIG, slack = BIG; for(int F = 1; F <= E; F++) if((E|F) == E) { if(hub < bitCount[F]) continue; int sum = sumCables[F]; if(length <= sum) { if(hub == bitCount[F] && slack <= sum - length) continue; hub = bitCount[F]; slack = sum - length; } } memo[index][S][E][0] = hub; memo[index][S][E][1] = slack; } } private void init(int index, int S, int E, int[] dis) { int mask = 1; for(int i = 0, c = bitCount[S] - 1; i < M && c > 0; i++, mask <<= 1) if((E & (1 << i)) != 0) c--; if(dis[dis.length - 1] > sumCables[E & ~(mask - 1)]){ memo[index][S][E] = BIGs; return; } int count = 0, slack = 0; for(int e : indexs[E]) if(count < dis.length && dis[count] <= cables[e]) slack += cables[e] - dis[count++]; if(count == dis.length) { memo[index][S][E][0] = count; memo[index][S][E][1] = slack; } else { memo[index][S][E][0] = -1; memo[index][S][E][1] = -1; } } private boolean solveZeroHab() { for(int i = 0; i < M; i++) if(cables[i] >= libraries[0]) { System.out.println("0 "+(cables[i] - libraries[0])); return true; } return false; } private void solve() { if(N == 1 && solveZeroHab()) return; else if(N >= M) { System.out.println("Impossible"); return; } init(); int minHub = BIG, minSlack = BIG; for(int e = 0, beforeLength = -1; e < M; beforeLength = cables[e], e++) if(beforeLength != cables[e]) for(int i = 0; i <= L && i<= cables[e]; i++) { int[] min = dfs(i, (1 << N) - 1, ((1 << M) - 1) & ~(1 << e)); if(min[0] < minHub || (min[0] == minHub && min[1] + cables[e] - i < minSlack)){ minHub = min[0]; minSlack = min[1] + cables[e] - i; } } System.out.println(minHub == BIG? "Impossible": (minHub - N + 1) + " " + minSlack); } private int[] dfs(int index, int S, int E){ if(memo[index][S][E][0] != -1) return memo[index][S][E]; int minHub = BIG, minSlack = BIG, countS = bitCount[S], counts = bitCount[S] / 2, countE = bitCount[E], before = -1; a : for(int e : indexs[E]) { if(before == cables[e]) continue; else before = cables[e]; int cableLength = cables[e], end = Math.min(L, index + cableLength); for(int j = Math.max(0, index - cableLength); j <= end; j++) if(index != j) { int[] min = dfs(j, S, E & ~(1<= i; j--) for(int F: combinations[E][j]) { int[] min1 = dfs(index, T, F); if(min1[0] >= BIG) continue; int[] min2 = dfs(index, tmpS, E & ~F); if(min2[0] >= BIG) continue; int hub = min1[0] + min2[0], slack = min1[1] + min2[1]; if(hub < minHub || (hub == minHub && slack < minSlack)){ minHub = hub; minSlack = slack; if(minHub == countS + 1 && minSlack == 0) break a; } } memo[index][S][E][0] = minHub; memo[index][S][E][1] = minSlack; return memo[index][S][E]; } static { for(int s = 1; s < 1024; s++) bitCount[s] = Integer.bitCount(s); int[] tmp = {0, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800}; for(int state = 1; state < 1024; state++) { for(int key = 1; key < bitCount[state]; key++) { combinations[state][key] = new int[tmp[bitCount[state]] / tmp[bitCount[state] - key] / tmp[key]]; for(int i = 1, count = 0; i <= state; i++) if((state | i) == state && bitCount[i] == key) combinations[state][key][count++] = i; } indexs[state] = new int[bitCount[state]]; for(int index = 0, count = 0, i = 1; i <= state; i <<= 1, index++) if((state & i) != 0) indexs[state][count++] = index; } indexs[0] = new int[]{}; } }