// Arup Guha
// 5/18/2021
// Solution to 2021 Code Jam Round 2 Problem C: Hidden Pancakes

import java.util.*;

public class Solution {
	
	final public static long MOD = 1000000007L;
	
	public static int n;
	public static int[] showing;
	public static RMQ min;
	public static long[] fact;
	public static long[] invfact;
	
	public static void main(String[] args) {
		
		// Factorials and inverse facts to calculate combinations.
		fact = new long[100001];
		invfact = new long[100001];
		fact[0] = 1;
		invfact[0] = 1;
		for (int i=1; i<fact.length; i++) {
			fact[i] = (fact[i-1]*i)%MOD;
			invfact[i] = pow(fact[i], MOD-2);
		}
	
		Scanner stdin = new Scanner(System.in);
		int nC = stdin.nextInt();
		
		// Process cases.
		for (int loop=1; loop<=nC; loop++) {
			
			n = stdin.nextInt();
			showing = new int[n];
			for (int i=0; i<n; i++)
				showing[i] = stdin.nextInt();
			
			// Screen out impossible cases and then solve the regular cases.
			if (possible())
				System.out.println("Case #"+loop+": "+solve());
			else
				System.out.println("Case #"+loop+": 0");
		}
	}	
	
	// You can't jump by more than 1 ever...
	public static boolean possible() {
		int cur = 0;
		for (int i=0; i<n; i++) {
			if (showing[i] > cur+1) return false;
			cur = showing[i];
		}
		return true;
	}
	
	// Regular fast mod expo. I just use for mod inverse since the mod given is prime.
	public static long pow(long b, long e) {
		if (e == 0) return 1;
		if (e%2 == 0) {
			long tmp = pow(b, e/2);
			return (tmp*tmp)%MOD;
		}
		return (b*pow(b,e-1))%MOD;
	}
	
	// Regular definition of the combination under mod.
	public static long choose(int myN, int myK) {
		long res = (fact[myN]*invfact[myK])%MOD;
		return (res*invfact[myN-myK])%MOD;
	}
	
	// Wrapper method.
	public static long solve() {
		min = new RMQ(showing);
		return go(0, n-1);
	}
	
	// Returns the answer from s to e, inclusive.
	public static long go(int s, int e) {
		
		// This can only be done in one way.
		if (e-s <= 1) return 1;
		
		// The largest pancake in this range MUST be at the rightmost index with a minimum value.
		int minIdx = min.query(s, e);
		
		// We can choose any of the left # of items to be on the left out of the size-1 (all but max pancake)
		// total elements.
		int size = e-s+1;
		int left = minIdx - s;
		long res = choose(size-1, left);
		
		// Then, we multiply this by the # of ways to arrange the left and right of the max pancake, as these are
		// independent cases.
		res = (res*go(s, minIdx-1))%MOD;
		return (res*go(minIdx+1,e))%MOD;
	}
	
}

class RMQ {

	public int[][] vals;
	public int[][] idx;

	// Creates an interval tree from myLow to myHigh, inclusive.
	public RMQ(int[] arr) {

		// Make it big enough,
		int size = 1, levels = 1;
		while (size < arr.length) {
			size = (size<<1);
			levels++;
		}
		
		vals = new int[levels][];
		idx = new int[levels][];
		
		for (int div=0; div<levels; div++) {
			
			// # of values for this level.
			vals[div] = new int[size-(1<<div)+1];
			idx[div] = new int[size-(1<<div)+1];
			
			// First level, just copy...
			if (div == 0) {
				
				for (int i=0; i<arr.length; i++) {
					vals[div][i] = arr[i];
					idx[div][i] = i;
				}
				
				// dummy values. For this question 1 billion was plenty big.
				for (int i=arr.length; i<vals[div].length; i++) {
					vals[div][i] = 1000000000;
					idx[div][i] = i;					
				}
			}
			
			// Build RMQ table from previous level.
			else {
	
				// This is how far over to skip on this level of the rmq table.
				int skip = (1<<(div-1));
				
				// Decide the answer for each slot.
				for (int i=0; i<vals[div].length; i++) {
					
					// Left answer wins, copy it.
					if (vals[div-1][i] < vals[div-1][i+skip]) {
						vals[div][i] = vals[div-1][i];
						idx[div][i] = idx[div-1][i];
					}
					
					// Otherwise, the right answer wins.
					else {
						vals[div][i] = vals[div-1][i+skip];
						idx[div][i] = idx[div-1][i+skip];
					}
				}
			}
		}
	}
	
	// Just for debugging.
	public void print() {
		for (int i=0; i<vals.length; i++) {
			for (int j=0; j<vals[i].length; j++) {
				System.out.print("["+vals[i][j]+", "+idx[i][j]+"], ");
			}
			System.out.println();
		}
	}

	// Returns the result from start to end inclusive.
	public int query(int start, int end) {

		// Safe starting answer.
		int min = vals[0][start], minI = idx[0][start], cur = start;
		
		// Just count down through powers of 2.
		for (int i=vals.length-1; i>=0; i--) {
			
			// Interval doesn't go this far.
			if (cur+(1<<i) > end+1) continue;
			
			// Incorporate this interval into the answer - if a better answer is found, update.
			if (vals[i][cur] <= min) {
				min = vals[i][cur];
				minI = idx[i][cur];
			}
			
			// This is how far we've update our answer to.
			cur += (1<<i);
		}
		
		// I just need the index, but I could return both if I wanted...
		return minI;
	}
}