import java.util.*; import java.io.PrintWriter; import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class Undercover_Underground2 { private static Map, BigInteger> nCrMap = new HashMap, BigInteger>(); // reference: https://en.wikipedia.org/wiki/Binomial_coefficient#Multiplicative_formula // reference: Python code written by Lee Gao private static BigInteger choose(int n, int r) { if(r > n || r < 0) throw new IllegalArgumentException("Need n,r: n >= r && r >= 0"); // check if key is present List tuple = Arrays.asList(n, r); if( nCrMap.containsKey(tuple) ) return nCrMap.get(tuple); // tuple is not present // generate a key List key = Collections.unmodifiableList(Arrays.asList(n, r)); // r must be in [0,n] BigInteger ntok = BigInteger.ONE; BigInteger ktok = BigInteger.ONE; int upperBound = Math.min(r, n-r); for(int t = 1 ; t <= upperBound ; t++) { ntok = ntok.multiply(BigInteger.valueOf(n)); ktok = ktok.multiply(BigInteger.valueOf(t)); n--; } nCrMap.put(key, ntok.divide(ktok)); // tuple is key return nCrMap.get(tuple); } static Map, String> resultMap = new HashMap, String>(); public String answer(int N, int K) { /* for the case where K > N-1 */ // check if key is present in the map List tuple = Arrays.asList(N, K); if( resultMap.containsKey(tuple) ) return resultMap.get(tuple); // maximum number of edges in a simply // connected undirected unweighted graph // with n nodes = |N| * |N-1| / 2 int maxEdges = N * (N-1) / 2; /* for the case where K < N-1 or K > N(N-1)/2 */ if(K < N-1 || K > maxEdges) return BigInteger.ZERO.toString(); /* for the case where K = N-1 */ // Cayley's formula applies [https://en.wikipedia.org/wiki/Cayley's_formula]. // number of trees on n labeled vertices is n^{n-2}. if(K == N-1) { if(N < 2) return BigInteger.valueOf((long)Math.pow(N, N-2)).toString(); // multiply N to itself N-2 times BigInteger val = BigInteger.ONE; int count = 0; while(count++ != N-2) val = val.multiply( BigInteger.valueOf( (long)N ) ); return val.toString(); } /* for the case where K = N(N-1)/2 */ // if K is the maximum possible // number of edges for the number of // nodes, then there is only one way is // to make a graph (connect each node // to all other nodes) if(K == maxEdges) return BigInteger.ONE.toString(); // number of edges left from maxEdges if I take away K-1 edges BigInteger numWays = BigInteger.valueOf(maxEdges - K + 1); // number of graphs possible for each of the numWays edges for a graph that has 1 less edge BigInteger numGraphsWithOneLessEdge = new BigInteger( answer(N, K-1) ); // number of all possible subgraphs with K-1 edges BigInteger subGraphs = answerHelper(N, K-1); // numWays*numGraphsWithOneLessEdge + subGraphs BigInteger result = subGraphs.add(numWays.multiply(numGraphsWithOneLessEdge)); // k copies of g within the multiset result = result.divide(BigInteger.valueOf(K)); // add to cache resultMap.put(Collections.unmodifiableList(Arrays.asList(N, K)), result.toString()); return resultMap.get(tuple); } private BigInteger answerHelper(int N, int K) { BigInteger totalGraphs = BigInteger.ZERO; for(int n = 1 ; n < N ; n++) { BigInteger graphs = BigInteger.ZERO; for(int k = 0 ; k <= K ; k++) { // number of graphs with n nodes and k edges BigInteger num = new BigInteger( answer(n, k) ); // number of graphs with N-n nodes and K-k edges BigInteger num2 = new BigInteger( answer(N-n, K-k) ); graphs = graphs.add( num.multiply(num2) ); } // number of ways to choose n nodes from N nodes BigInteger choose = choose(N, n); // this is repeated for each of the n chosen nodes // and the N-n unchosen nodes choose = choose.multiply(BigInteger.valueOf(n)).multiply(BigInteger.valueOf(N-n)); totalGraphs = totalGraphs.add( choose.multiply(graphs) ); } return totalGraphs.divide(BigInteger.valueOf(2)); } public static void main(String[] args) { Undercover_Underground2 unit = new Undercover_Underground2(); PrintWriter w = new PrintWriter(System.out); Scanner s=new Scanner(System.in); long mod=663224321; int t=s.nextInt(); while(t-->0){ long res=0; int n=s.nextInt(); for(int k = n-1 ; k <= n*(n-1)/2 ; k++) { String ans = unit.answer(n,k); long val=Long.parseLong(ans); //System.out.println(val); res=res%mod+val%mod; //System.out.println("N = " + n + " , K = " + k + " , num = " + ans); } w.println(res); } w.close(); } }