// Arup Guha
// 4/4/2020
// Solution to 2020 Code Jam Qualification Round Question E: Indicium
// Written in Contest

import java.util.*;

public class e {

	public static int n;
	public static int trace;
	public static int[][] g;
	public static boolean[][] used;
	public static int[] nums;
	
	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int nC = stdin.nextInt();
		
		// Process cases.
		for (int loop=1; loop<=nC; loop++) {
		
			// Set up the grid.
			n = stdin.nextInt();
			trace = stdin.nextInt();
			g = new int[n][n];
			for (int i=0; i<n; i++) Arrays.fill(g[i], -1);
			
			// used[i][j] represents if number i has taken column j already.
			used = new boolean[n][n];
			
			// nums store how many of each number we still need to place.
			nums = new int[n];
			Arrays.fill(nums, n);
			
			// We know we can do it.
			if (possible()) {
				
				// I greedily fill the diagonal.
				fillDiag();
				
				// I sort the numbers 1 to n from which ones have been placed most to least.
				pair[] list = new pair[n];
				for (int i=0; i<n; i++)
					list[i] = new pair(i, nums[i]);
				Arrays.sort(list);
				
				// Add ALL copies of the number list[i].
				for (int i=0; i<n; i++) {
					
					// Number which we are adding.
					int myNum = list[i].id;
					
					// Flow graph -> mapping numbers to columns for row i.
					Dinic fGraph = new Dinic(2*n);
					
					// Columns that need to be filled.
					for (int j=0; j<n; j++) {
						if (g[j][j] == myNum) continue;
						fGraph.add(j+n,2*n+1,1,0);
						fGraph.add(2*n,j,1,0);
					}
					
					// Go through each number.
					for (int j=0; j<n; j++) {
						for (int k=0; k<n; k++) {
							if (g[j][k] != -1) continue;
								
							// We could put myNum in row j, col k
							fGraph.add(j, k+n, 1, 0);
							
						}
					}
					
					// I know it'll work so that's why I call this junk.
					int junk = fGraph.flow();
					
					// This is the matching.
					ArrayList<int[]> add = fGraph.getFlows();
					
					// Fill it in.
					for (int j=0; j<add.size(); j++) {
						int[] item = add.get(j);
						int row = item[0];
						int col = item[1];
						g[row][col] = myNum;
					}
					
				}
				
				// Ta da!
				System.out.println("Case #"+loop+": POSSIBLE");
				for (int i=0; i<n; i++) {
					System.out.print(g[i][0]+1);
					for (int j=1; j<n; j++)
						System.out.print(" "+(g[i][j]+1));
					System.out.println();
				}
			}
			
			// Can't do it.
			else {
				System.out.println("Case #"+loop+": IMPOSSIBLE");
			}
		}
	}
	
	// Returns true if we can do it.
	public static boolean possible() {
		
		// Obvious cases (maybe not allowed in the input but I forgot about that.)
		if (trace < n) return false;
		if (trace > n*n) return false;
		
		// Can't put n-1 of the same number in a diagonal, so these cases don't work,
		if (trace == n+1) return false;
		if (trace == n*n-1) return false;
		
		// Same reason these cases don't work.
		if (n == 3 && (trace == 5 || trace == 7)) return false;
		
		// We are good...
		return true;
	}
	

	// Greedily fills diagonal.
	public static void fillDiag() {
		
		int avg = trace/n-1;
		int left = trace%n;
		
		// Just use the average value and add extra as needed.
		for (int i=0; i<n; i++) g[i][i] = avg;
		for (int i=1; i<=left; i++) g[n-i][n-i]++;
		
		// Can't have n-1 of the same number so adjust but keep the sum the same.
		if (left == n-1) {
			g[1][1]--;
			g[n-1][n-1]++;
		}
		
		// Same here.
		else if (left == 1) {
			g[0][0]--;
			g[n-2][n-2]++;
		}
	
		// Mark each combo (number, column) which is used.
		for (int i=0; i<n; i++) {
			used[g[i][i]][i] = true;
			nums[g[i][i]]--;
		}
	}
}

// Just to sort pairs by frequency.
class pair implements Comparable<pair> {
	
	public int id;
	public int freq;
	
	public pair(int i, int f) {
		id = i;
		freq = f;
	}
	
	public int compareTo(pair other) {
		if (freq != other.freq) return freq - other.freq;
		return id - other.id;
	}
}

/*** UCF team Dinic's ***/
class Edge {
	int v1, v2, cap, flow;
	Edge rev;
	Edge(int V1, int V2, int Cap, int Flow) {
		v1 = V1; v2 = V2; cap = Cap; flow = Flow;
	}
}

class Dinic {

	ArrayDeque<Integer> q;
	ArrayList<Edge>[] adj;
	int n, s, t, oo = (int)1E9;
	boolean[] blocked;
	int[] dist;

	public Dinic (int N) {
		n = N; s = n++; t = n++;
		blocked = new boolean[n];
		dist = new int[n];
		q = new ArrayDeque<Integer>();
		adj = new ArrayList[n];
		for(int i = 0; i < n; ++i)
			adj[i] = new ArrayList<Edge>();
	}

	void add(int v1, int v2, int cap, int flow) {
		Edge e = new Edge(v1, v2, cap, flow);
		Edge rev = new Edge(v2, v1, 0, 0);
		adj[v1].add(rev.rev = e);
		adj[v2].add(e.rev = rev);
	}
	
	ArrayList<int[]> getFlows() {
		
		ArrayList<int[]> res = new ArrayList<int[]>();
		for (int i=0; i<(n-2)/2; i++) {
			for (Edge e: adj[i]) {
				if (e.flow == 1) {
					int[] tmp = new int[2];
					tmp[0] = e.v1; tmp[1] = e.v2-(n-2)/2;
					res.add(tmp);
				}
			}
		}
		return res;
	}

	boolean bfs() {
		q.clear();
		Arrays.fill(dist, -1);
		dist[t] = 0;
		q.add(t);
			
		while(!q.isEmpty()) {
			int node = q.poll();
			if(node == s) 
				return true;
			for(Edge e : adj[node]) {
				if(e.rev.cap > e.rev.flow && dist[e.v2] == -1) {
					dist[e.v2] = dist[node] + 1;
					q.add(e.v2);
				}
			}
		}
		return dist[s] != -1;
	}
		
	int dfs(int pos, int min) {
		if(pos == t) 
			return min;
		int flow = 0;
		for(Edge e : adj[pos]) {
			int cur = 0;
			if(!blocked[e.v2] && dist[e.v2] == dist[pos]-1 && e.cap - e.flow > 0) {
				cur = dfs(e.v2, Math.min(min-flow, e.cap - e.flow));
				e.flow += cur;
				e.rev.flow = -e.flow;
				flow += cur;
			}
			if(flow == min)
				return flow;
		}
		blocked[pos] = flow != min;
		return flow;
	}
	
	int flow() {
		clear();
		int ret = 0;
		while(bfs()) {
			Arrays.fill(blocked, false);
			ret += dfs(s, oo);
		}
		return ret;
	}
	
	void clear() {
		for(ArrayList<Edge> edges : adj)
			for(Edge e : edges)
				e.flow = 0;
	}
}