import java.io.*;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Queue;

public class E3 {
	InputStream is;
	FastWriter out;
	String INPUT = "";

	void solve()
	{
		for(int T = ni();T > 0;T--)go();
	}

	int[] lpf = enumLowestPrimeFactors(10000000);

	void go()
	{
		int n = ni(), K = ni();
		int[] a = na(n);
		for(int i = 0;i < n;i++){
			a[i] = factorFast(a[i], lpf);
		}
		a = shrink(a);

		int[][] dp = new int[K+1][n+1];
		for(int i = 0;i <= K;i++){
			Arrays.fill(dp[i], 999999999);
		}
		for(int i = 0;i <= K;i++)dp[i][0] = 0;

		int[] prev = makePrev(a, n+1);

		int[] imos = new int[n+5];
		int[] pp = new int[K+1];
		int[] vs = new int[K+1];
		for(int i = 0;i < n;i++){
			int p = prev[i];
			imos[p+1]--;

			for(int j = 0;j <= K;j++){
				vs[j]++;
				if(pp[j] >= p+1){
					vs[j]--;
				}
				while(vs[j] > j){
					pp[j]++;
					vs[j] += imos[pp[j]];
				}
				for(int k = 0;k+j <= K;k++){
					dp[k+j][i+1] = Math.min(dp[k+j][i+1], dp[k][pp[j]] + 1);
				}
			}
		}
		out.println(dp[K][n]);
	}

	public static int[] shrink(int[] a) {
		int n = a.length;
		long[] b = new long[n];
		for (int i = 0; i < n; i++) b[i] = (long) a[i] << 32 | i;
		Arrays.sort(b);
		int[] ret = new int[n];
		int p = 0;
		for (int i = 0; i < n; i++) {
			if (i > 0 && (b[i] ^ b[i - 1]) >> 32 != 0) p++;
			ret[(int) b[i]] = p;
		}
		return ret;
	}

	public static int[] makePrev(int[] a, int sup)
	{
		int n = a.length;
		int[] mnext = new int[sup];
		Arrays.fill(mnext, -1);
		int[] next = new int[n];
		for(int i = 0;i < n;i++){
			next[i] = mnext[a[i]];
			mnext[a[i]] = i;
		}
		return next;
	}

	public static int factorFast(int n, int[] lpf)
	{
		int ret = 1;
		int e = 0;
		int last = -1;
		while(lpf[n] > 0) {
			int p = lpf[n];
			if (last != p) {
				if (last > 0 && e % 2 == 1) {
					ret = ret * last;
				}

				last = p;
				e = 1;
			} else {
				e++;
			}
			n /= p;
		}

		if(last > 0 && e % 2 == 1){
			ret *= last;
		}
		return ret;
	}

	public static int[] enumLowestPrimeFactors(int n)
	{
		int tot = 0;
		int[] lpf = new int[n+1];
		int u = n+32;
		double lu = Math.log(u);
		int[] primes = new int[(int)(u/lu+u/lu/lu*1.5)];
		for(int i = 2;i <= n;i++)lpf[i] = i;
		for(int p = 2;p <= n;p++){
			if(lpf[p] == p)primes[tot++] = p;
			int tmp;
			for(int i = 0;i < tot && primes[i] <= lpf[p] && (tmp = primes[i]*p) <= n;i++){
				lpf[tmp] = primes[i];
			}
		}
		return lpf;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new FastWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E3().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private long[] nal(int n)
	{
		long[] a = new long[n];
		for(int i = 0;i < n;i++)a[i] = nl();
		return a;
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[][] nmi(int n, int m) {
		int[][] map = new int[n][];
		for(int i = 0;i < n;i++)map[i] = na(m);
		return map;
	}

	private int ni() { return (int)nl(); }

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	public static class FastWriter
	{
		private static final int BUF_SIZE = 1<<13;
		private final byte[] buf = new byte[BUF_SIZE];
		private final OutputStream out;
		private int ptr = 0;

		private FastWriter(){out = null;}

		public FastWriter(OutputStream os)
		{
			this.out = os;
		}

		public FastWriter(String path)
		{
			try {
				this.out = new FileOutputStream(path);
			} catch (FileNotFoundException e) {
				throw new RuntimeException("FastWriter");
			}
		}

		public FastWriter write(byte b)
		{
			buf[ptr++] = b;
			if(ptr == BUF_SIZE)innerflush();
			return this;
		}

		public FastWriter write(char c)
		{
			return write((byte)c);
		}

		public FastWriter write(char[] s)
		{
			for(char c : s){
				buf[ptr++] = (byte)c;
				if(ptr == BUF_SIZE)innerflush();
			}
			return this;
		}

		public FastWriter write(String s)
		{
			s.chars().forEach(c -> {
				buf[ptr++] = (byte)c;
				if(ptr == BUF_SIZE)innerflush();
			});
			return this;
		}

		private static int countDigits(int l) {
			if (l >= 1000000000) return 10;
			if (l >= 100000000) return 9;
			if (l >= 10000000) return 8;
			if (l >= 1000000) return 7;
			if (l >= 100000) return 6;
			if (l >= 10000) return 5;
			if (l >= 1000) return 4;
			if (l >= 100) return 3;
			if (l >= 10) return 2;
			return 1;
		}

		public FastWriter write(int x)
		{
			if(x == Integer.MIN_VALUE){
				return write((long)x);
			}
			if(ptr + 12 >= BUF_SIZE)innerflush();
			if(x < 0){
				write((byte)'-');
				x = -x;
			}
			int d = countDigits(x);
			for(int i = ptr + d - 1;i >= ptr;i--){
				buf[i] = (byte)('0'+x%10);
				x /= 10;
			}
			ptr += d;
			return this;
		}

		private static int countDigits(long l) {
			if (l >= 1000000000000000000L) return 19;
			if (l >= 100000000000000000L) return 18;
			if (l >= 10000000000000000L) return 17;
			if (l >= 1000000000000000L) return 16;
			if (l >= 100000000000000L) return 15;
			if (l >= 10000000000000L) return 14;
			if (l >= 1000000000000L) return 13;
			if (l >= 100000000000L) return 12;
			if (l >= 10000000000L) return 11;
			if (l >= 1000000000L) return 10;
			if (l >= 100000000L) return 9;
			if (l >= 10000000L) return 8;
			if (l >= 1000000L) return 7;
			if (l >= 100000L) return 6;
			if (l >= 10000L) return 5;
			if (l >= 1000L) return 4;
			if (l >= 100L) return 3;
			if (l >= 10L) return 2;
			return 1;
		}

		public FastWriter write(long x)
		{
			if(x == Long.MIN_VALUE){
				return write("" + x);
			}
			if(ptr + 21 >= BUF_SIZE)innerflush();
			if(x < 0){
				write((byte)'-');
				x = -x;
			}
			int d = countDigits(x);
			for(int i = ptr + d - 1;i >= ptr;i--){
				buf[i] = (byte)('0'+x%10);
				x /= 10;
			}
			ptr += d;
			return this;
		}

		public FastWriter write(double x, int precision)
		{
			if(x < 0){
				write('-');
				x = -x;
			}
			x += Math.pow(10, -precision)/2;
			//		if(x < 0){ x = 0; }
			write((long)x).write(".");
			x -= (long)x;
			for(int i = 0;i < precision;i++){
				x *= 10;
				write((char)('0'+(int)x));
				x -= (int)x;
			}
			return this;
		}

		public FastWriter writeln(char c){
			return write(c).writeln();
		}

		public FastWriter writeln(int x){
			return write(x).writeln();
		}

		public FastWriter writeln(long x){
			return write(x).writeln();
		}

		public FastWriter writeln(double x, int precision){
			return write(x, precision).writeln();
		}

		public FastWriter write(int... xs)
		{
			boolean first = true;
			for(int x : xs) {
				if (!first) write(' ');
				first = false;
				write(x);
			}
			return this;
		}

		public FastWriter write(long... xs)
		{
			boolean first = true;
			for(long x : xs) {
				if (!first) write(' ');
				first = false;
				write(x);
			}
			return this;
		}

		public FastWriter writeln()
		{
			return write((byte)'\n');
		}

		public FastWriter writeln(int... xs)
		{
			return write(xs).writeln();
		}

		public FastWriter writeln(long... xs)
		{
			return write(xs).writeln();
		}

		public FastWriter writeln(char[] line)
		{
			return write(line).writeln();
		}

		public FastWriter writeln(char[]... map)
		{
			for(char[] line : map)write(line).writeln();
			return this;
		}

		public FastWriter writeln(String s)
		{
			return write(s).writeln();
		}

		private void innerflush()
		{
			try {
				out.write(buf, 0, ptr);
				ptr = 0;
			} catch (IOException e) {
				throw new RuntimeException("innerflush");
			}
		}

		public void flush()
		{
			innerflush();
			try {
				out.flush();
			} catch (IOException e) {
				throw new RuntimeException("flush");
			}
		}

		public FastWriter print(byte b) { return write(b); }
		public FastWriter print(char c) { return write(c); }
		public FastWriter print(char[] s) { return write(s); }
		public FastWriter print(String s) { return write(s); }
		public FastWriter print(int x) { return write(x); }
		public FastWriter print(long x) { return write(x); }
		public FastWriter print(double x, int precision) { return write(x, precision); }
		public FastWriter println(char c){ return writeln(c); }
		public FastWriter println(int x){ return writeln(x); }
		public FastWriter println(long x){ return writeln(x); }
		public FastWriter println(double x, int precision){ return writeln(x, precision); }
		public FastWriter print(int... xs) { return write(xs); }
		public FastWriter print(long... xs) { return write(xs); }
		public FastWriter println(int... xs) { return writeln(xs); }
		public FastWriter println(long... xs) { return writeln(xs); }
		public FastWriter println(char[] line) { return writeln(line); }
		public FastWriter println(char[]... map) { return writeln(map); }
		public FastWriter println(String s) { return writeln(s); }
		public FastWriter println() { return writeln(); }
	}

	public void trnz(int... o)
	{
		for(int i = 0;i < o.length;i++)if(o[i] != 0)System.out.print(i+":"+o[i]+" ");
		System.out.println();
	}

	// print ids which are 1
	public void trt(long... o)
	{
		Queue<Integer> stands = new ArrayDeque<>();
		for(int i = 0;i < o.length;i++){
			for(long x = o[i];x != 0;x &= x-1)stands.add(i<<6|Long.numberOfTrailingZeros(x));
		}
		System.out.println(stands);
	}

	public void tf(boolean... r)
	{
		for(boolean x : r)System.out.print(x?'#':'.');
		System.out.println();
	}

	public void tf(boolean[]... b)
	{
		for(boolean[] r : b) {
			for(boolean x : r)System.out.print(x?'#':'.');
			System.out.println();
		}
		System.out.println();
	}

	public void tf(long[]... b)
	{
		if(INPUT.length() != 0) {
			for (long[] r : b) {
				for (long x : r) {
					for (int i = 0; i < 64; i++) {
						System.out.print(x << ~i < 0 ? '#' : '.');
					}
				}
				System.out.println();
			}
			System.out.println();
		}
	}

	public void tf(long... b)
	{
		if(INPUT.length() != 0) {
			for (long x : b) {
				for (int i = 0; i < 64; i++) {
					System.out.print(x << ~i < 0 ? '#' : '.');
				}
			}
			System.out.println();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;

public class Main {
  public static void main(String[] args) throws IOException {
    InputStreamReader in = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(in);

    int t = Integer.parseInt(br.readLine());

    // get primes up to 10000
    /*
    boolean[] prime = new boolean[10001];
    for (int i = 0; i <= 10000; i++) {
      prime[i] = true;
    }

    for (int p = 2; p * p <= 10000; p++) {
      if (prime[p]) {
        for (int i = p * p; i <= 10000; i += p) {
          prime[i] = false;
        }
      }
    }
    ArrayList<Integer> primes = new ArrayList<>();

    for (int i = 2; i < 10001; i++) {
      if (prime[i]) {
        primes.add(i);
      }
    }
    */
    int A = 10000000;
    int[] convert = new int[A+1];
    for (int a = 1; a <= A; a++) {
      convert[a] = a;
    }
    for (int a = 2; a <= A/a; a++) {
      int sq = a*a;
      for (int b = sq; b <= A; b += sq) {
        while (convert[b] % sq == 0) {
          convert[b] /= sq;
        }
      }
    }

    int[] prevIndex = new int[A+1];
    for (int i = 0; i <= A; i++) {
      prevIndex[i] = -1;
    }

    for (int c = 0; c < t; c++) {
      StringTokenizer st = new StringTokenizer(br.readLine());

      int n = Integer.parseInt(st.nextToken());
      int k = Integer.parseInt(st.nextToken());

      int[] a = new int[n];
      int maxA = 0;

      st = new StringTokenizer(br.readLine());

      for (int i = 0; i < n; i++) {
        /*
        int raw = Integer.parseInt(st.nextToken());

        for (int p : primes) {
          if (p*p > raw) {
            break;
          }
          while (raw % (p*p) == 0) {
            raw /= p*p;
          }
        }
        a[i] = raw;
        */

        a[i] = convert[Integer.parseInt(st.nextToken())];
        maxA = Math.max(maxA, a[i]);
      }

      // hard version has extra here
      // better version O(nk)

      int[] partitions = new int[k+1];
      int[] partIndex = new int[k+1];

      for (int i = 0; i < n; i++) {
        int cur = a[i];
        for (int j = k; j >= 0; j--) {
          if (prevIndex[cur] >= partIndex[j]) {
            partitions[j]++;
            partIndex[j] = i;
          }
          if (j > 0 && (partitions[j-1] < partitions[j] || partitions[j-1] == partitions[j] && partIndex[j-1] > partIndex[j])) {
            partitions[j] = partitions[j-1];
            partIndex[j] = partIndex[j-1];
          }
        }
        prevIndex[cur] = i;
      }

      System.out.println(partitions[k]+1);

      for (int i = 0; i < n; i++) {
        int cur = a[i];
        prevIndex[cur] = -1;
      }

      /* this should work (O(n*k^2))
      int[][] minLeftIndex = new int[n][k+1];

      for (int j = 0; j <= k; j++) {
        HashMap<Integer, Integer> interval = new HashMap<>();
        int leftIndex = 0; // the right index is i in this case
        int removed = 0;

        for (int i = 0; i < n; i++) {
          if (!interval.containsKey(a[i])) {
            interval.put(a[i], 0);
          }
          interval.put(a[i], interval.get(a[i])+1);
          if (interval.get(a[i]) > 1) {
            removed++;
          }
          while (removed > j) {
            interval.put(a[leftIndex], interval.get(a[leftIndex])-1);
            if (interval.get(a[leftIndex]) > 0) {
              removed--;
            }
            leftIndex++;
          }
          minLeftIndex[i][j] = leftIndex;
          //System.out.println(i + " " + j + " " + leftIndex);
        }
      }

      int[][] dp = new int[n][k+1];

      // dp at all i = 0 = 0
      for (int i = 0; i < n; i++) {
        for (int j = 0; j <= k; j++) {
          int min = Integer.MAX_VALUE;
          for (int l = 0; l <= j; l++) {
            if (minLeftIndex[i][l] > 0) {
              min = Math.min(min, dp[minLeftIndex[i][l]-1][j-l] + 1); //
            } else {
              min = 0;
            }

          }
          if (min != Integer.MAX_VALUE) {
            dp[i][j] = min;
          }
        }
      }

      System.out.println(dp[n-1][k]+1);

      */

      // easy solution
      /*
      HashSet<Integer> hs = new HashSet<>();

      int segments = 1;

      for (int i = 0; i < n; i++) {
        if (hs.contains(a[i])) {
          segments++;
          hs.clear();
        }
        hs.add(a[i]);
      }
      System.out.println(segments);
      */
    }
  }
}


/**
 * author: derrick20
 * created: 3/20/21 7:13 PM
 */
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class E2_SquareFreeFast {
    static FastScanner sc = new FastScanner();
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
//        generate();
        int T = sc.nextInt();
        int MAX = (int) 1e7;
        int[] canonical = new int[MAX + 1];
        canonical[1] = 1;
        for (int factor = 2; factor <= MAX; factor++) {
            if (canonical[factor] == 0) {
                for (int mult = factor; mult <= MAX; mult += factor) {
                    int prev = canonical[mult / factor];
                    if (prev % factor == 0) {
                        canonical[mult] = prev / factor;
                    } else {
                        canonical[mult] = prev * factor;
                    }
                }
            }
        }
        int[] last = new int[MAX + 1];
        while (T-->0) {
            int N = sc.nextInt();
            int K = sc.nextInt();
            int[] a = new int[N + 1];
            int[][] dp = new int[2][K + 1];
            int[][] start = new int[2][K + 1];
            int ptr = 0;
            for (int i = 1; i <= N; i++) {
                int nxt = 1 ^ ptr;
                a[i] = canonical[sc.nextInt()];
                for (int k = 0; k <= K; k++) {
                    if (start[ptr][k] > last[a[i]]) {
                        // extend it for free (unique)
                        dp[nxt][k] = dp[ptr][k];
                        start[nxt][k] = start[ptr][k];
                    } else {
                        // start anew
                        dp[nxt][k] = dp[ptr][k] + 1;
                        start[nxt][k] = i;
                    }
                    // Use a change (only if existing segment)
                    if (i > 1 && k > 0 && start[ptr][k - 1] <= last[a[i]]) {
                        // if this cost beats the old cost, or if it has a later start point, it's better.
                        if (dp[ptr][k - 1] < dp[nxt][k] || (dp[ptr][k - 1] == dp[nxt][k] && start[ptr][k - 1] > start[nxt][k])) {
                            dp[nxt][k] = dp[ptr][k - 1];
                            start[nxt][k] = start[ptr][k - 1];
                        }
                    }
                }
//                System.out.println(Arrays.toString(start[nxt]));
//                System.out.println(Arrays.toString(dp[nxt]));
                last[a[i]] = i;
                ptr = nxt;
            }
            for (int v : a) {
                last[v] = 0;
            }
            // always allowed to waste initial changes by starting offset, so mono decr
            out.println(dp[ptr][K]);
        }
        out.close();
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        int nextInt() {
            return (int) nextLong();
        }

        long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        double nextDouble() {
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            double cur = nextLong();
            if (c != '.') {
                return neg ? -cur : cur;
            } else {
                double frac = nextLong() / cnt;
                return neg ? -cur - frac : cur + frac;
            }
        }

        String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }

    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}


import java.util.*;
import java.io.*;

 public class SolutionC{
       public static void main(String[] args) throws Exception{
               Scanner sc=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);
       int t=sc.nextInt();
       int[] arr=new int[10000002];
       for(int i=0;i<arr.length;i++){
           arr[i]=i;
       }
       for(int i=2;i*i<arr.length;i++){
           int b=i*i;
          for(int j=b;j<arr.length;j+=b){
              arr[j]=j/b;
          }
       }
      int[] pp = new int[10000001]; Arrays.fill(pp, -1);
       while(t-->0){

        int n=sc.nextInt();
        int k=sc.nextInt();
        int[] aa=new int[n];
         for(int i=0;i<n;i++){
             int a=sc.nextInt();
             aa[i]=arr[a];
         }

         int[] mp = new int[k + 1];
			int[] ip = new int[k + 1];
			for (int i = 0; i < n; i++) {
				int a = aa[i];
				for (int h = k; h >= 0; h--) {
					if (pp[a] >= ip[h]) {
						mp[h]++;
						ip[h] = i;
					}
					if (h > 0 && (mp[h - 1] < mp[h] || mp[h - 1] == mp[h] && ip[h - 1] > ip[h])) {
						mp[h] = mp[h - 1];
						ip[h] = ip[h - 1];
					}
				}
				pp[a] = i;
			}

        out.println(mp[k]+1);

       for (int i = 0; i < n; i++) {
				pp[aa[i]] = -1;
			}

       }

           out.close();
}

}


import java.util.*;
import java.io.*;
public class EdE {
	static long[] mods = {1000000007, 998244353, 1000000009};
	static long mod = mods[0];
	public static MyScanner sc;
    public static PrintWriter out;
    static ArrayList<Integer> primes;
	public static void main(String[] omkar) throws Exception{
		// TODO Auto-generated method stub
 		sc = new MyScanner();
 		out = new PrintWriter(System.out);
 		int t = sc.nextInt();
 		primes = new ArrayList<>();
 		prime(3165);
 		int[] freq = new int[10000001];
 		while(t--> 0){
 			int n = sc.nextInt();
 			int k = sc.nextInt();
 			int[] arr = readArrayInt(n);
 			for(int j = 0;j<n;j++){
 				arr[j] = factorize(arr[j]);
 			}
 			int[][] left = new int[n][k+1];
 			for(int m = 0;m<=k;m++){
 				int l = 0;
 				int count = 0;
 				for(int i = 0;i<n;i++){
 					if (freq[arr[i]] > 0){
 						count++;
 					}
 					freq[arr[i]]++;
 					while(count > m){
 						freq[arr[l]]--;
 						if (freq[arr[l]] > 0){
 							count--;
 						}
 						l++;
 					}
 					left[i][m] = l;
 				}
 				while(l < n){
 					freq[arr[l]]--;
 					l++;
 				}

 			}
 			long[][] dp = new long[n][k+1];
 			for(int i=0;i<n;i++){
 				Arrays.fill(dp[i],  Integer.MAX_VALUE);
 			}
 			for(int i = 0;i<n;i++){
 				for(int j = 0;j<=k;j++){
 					for(int s = 0;s<=j;s++){
 						if (left[i][s] == 0){
 							dp[i][j] = 1;
 							continue;
 						}
 						dp[i][j] = Math.min(dp[i][j],  dp[left[i][s]-1][j-s]+1);

 					}
 				}

 			}
 			out.println(dp[n-1][k]);

 		}

 		out.close();
 	}
	static class MS{
//      TreeSet<Long> set;
      HashMap<Long, Integer> map;
      public MS() {
//          set = new TreeSet<Long>();
          map = new HashMap<Long, Integer>();
      }
      public void add(long x) {
          if(map.containsKey(x)){
              map.put(x, map.get(x)+1);
          }
          else{
              map.put(x, 1);
//              set.add(x);
          }
      }
      public void remove(long x) {
          if(!map.containsKey(x))
              return;
          if(map.get(x)==1){
              map.remove(x);
//              set.remove(x);
          }
          else
              map.put(x, map.get(x)-1);
      }
//      public long getFirst() {
//          return set.first();
//      }
//      public long getLast() {
//          return set.last();
//      }
      public int size() {
          return map.keySet().size();
      }
      public void removeAll(int x) {
          map.remove(x);
      }
      public int getFreq(long x){
      	if (map.containsKey(x))
      		return map.get(x);
      	return 0;
      }
  }
	public static void prime(int n){
		int[] isPrime = new int[n+1];
		Arrays.fill(isPrime, 1);
		for(long i = 2;i<=n;i++){
			if (isPrime[(int)i] == 1){
				for(long j = i*i;j<=n;j+=i){
					isPrime[(int)j] = 0;
				}
			}
		}
		for(int j = 3;j<=n;j++){
			if (isPrime[j] == 1){
				primes.add(j);
			}
		}
	}
	public static int factorize(long n) {

	 	long prod = 1;
        int count = 0;
        while (n%2 == 0){
            n >>= 1;
            count++;
        }
        if (count > 0 && count%2 == 1)
            prod *= 2L;
        for (long i : primes) {
        	if (i*i > n)
        		break;
            count = 0;
            while (n % i == 0) {
                count++;
                n = n / i;
            }
            if (count > 0 && count%2 == 1)
                prod *= i;
        }
        if (n > 2)
        	prod *= n;
        return (int)prod;
    }
	public static void sort(int[] array){
		ArrayList<Integer> copy = new ArrayList<>();
		for (int i : array)
			copy.add(i);
		Collections.sort(copy);
		for(int i = 0;i<array.length;i++)
			array[i] = copy.get(i);
	}
	static String[] readArrayString(int n){
		String[] array = new String[n];
		for(int j =0 ;j<n;j++)
			array[j] = sc.next();
		return array;
	}
	static int[] readArrayInt(int n){
    	int[] array = new int[n];
    	for(int j = 0;j<n;j++)
    		array[j] = sc.nextInt();
    	return array;
    }
	static int[] readArrayInt1(int n){
		int[] array = new int[n+1];
		for(int j = 1;j<=n;j++){
			array[j] = sc.nextInt();
		}
		return array;
	}
	static long[] readArrayLong(int n){
		long[] array = new long[n];
		for(int j =0 ;j<n;j++)
			array[j] = sc.nextLong();
		return array;
	}
	static double[] readArrayDouble(int n){
		double[] array = new double[n];
		for(int j =0 ;j<n;j++)
			array[j] = sc.nextDouble();
		return array;
	}
	static int minIndex(int[] array){
		int minValue = Integer.MAX_VALUE;
		int minIndex = -1;
		for(int j = 0;j<array.length;j++){
			if (array[j] < minValue){
				minValue = array[j];
				minIndex = j;
			}
		}
		return minIndex;
	}
	static int minIndex(long[] array){
		long minValue = Long.MAX_VALUE;
		int minIndex = -1;
		for(int j = 0;j<array.length;j++){
			if (array[j] < minValue){
				minValue = array[j];
				minIndex = j;
			}
		}
		return minIndex;
	}
	static int minIndex(double[] array){
		double minValue = Double.MAX_VALUE;
		int minIndex = -1;
		for(int j = 0;j<array.length;j++){
			if (array[j] < minValue){
				minValue = array[j];
				minIndex = j;
			}
		}
		return minIndex;
	}
	static long power(long x, long y){
		if (y == 0)
			return 1;
		if (y%2 == 1)
			return (x*power(x, y-1))%mod;
		return power((x*x)%mod, y/2)%mod;
	}
	static void verdict(boolean a){
        out.println(a ? "YES" : "NO");
    }
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;
        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String nextLine() {
            String str = "";
            try{
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}

//StringJoiner sj = new StringJoiner(" ");
//sj.add(strings)
//sj.toString() gives string of those stuff w spaces or whatever that sequence is


import java.io.*;
import java.util.*;

public class CF1497E2 extends PrintWriter {
	CF1497E2() { super(System.out); }
	static class Scanner {
		Scanner(InputStream in) { this.in = in; } InputStream in;
		byte[] bb = new byte[1 << 15]; int i, n;
		byte getc() {
			if (i == n) {
				i = n = 0;
				try { n = in.read(bb); } catch (IOException e) {}
			}
			return i < n ? bb[i++] : 0;
		}
		int nextInt() {
			byte c = 0; while (c <= ' ') c = getc();
			int a = 0; while (c > ' ') { a = a * 10 + c - '0'; c = getc(); }
			return a;
		}
	}
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF1497E2 o = new CF1497E2(); o.main(); o.flush();
	}

	static final int A = 10000000, K = 20;
	int[] cc = new int[A + 1]; {
		boolean[] composite = new boolean[A + 1];
		for (int a = 1; a <= A; a++)
			cc[a] = a;
		for (int a = 2; a <= A; a++) {
			if (composite[a])
				continue;
			for (int b = a + a; b <= A; b += a)
				composite[b] = true;
			if (a <= A / a) {
				int a2 = a * a;
				for (int b = a2; b <= A; b += a2) {
					int c = cc[b];
					while (c % a2 == 0)
						c /= a2;
					cc[b] = c;
				}
			}
		}
	}
	void main() {
		int[] pp = new int[A + 1]; Arrays.fill(pp, -1);
		int t = sc.nextInt();
		while (t-- > 0) {
			int n = sc.nextInt();
			int k = sc.nextInt();
			int[] aa = new int[n];
			for (int i = 0; i < n; i++)
				aa[i] = cc[sc.nextInt()];
			int[] mp = new int[k + 1];
			int[] ip = new int[k + 1];
			for (int i = 0; i < n; i++) {
				int a = aa[i];
				for (int h = k; h >= 0; h--) {
					if (pp[a] >= ip[h]) {
						mp[h]++;
						ip[h] = i;
					}
					if (h > 0 && (mp[h - 1] < mp[h] || mp[h - 1] == mp[h] && ip[h - 1] > ip[h])) {
						mp[h] = mp[h - 1];
						ip[h] = ip[h - 1];
					}
				}
				pp[a] = i;
			}
			println(mp[k] + 1);
			for (int i = 0; i < n; i++) {
				int a = aa[i];
				pp[a] = -1;
			}
		}
	}
}


import java.util.*;
import java.io.*;

public class cf1497_Div2_E2 {
	static int[] spf;

	public static int factor(int n) {
		int val = 1;
		while (n > 1) {
			int cnt = 0;
			int p = spf[n];
			while (n % p == 0) {
				cnt++;
				n /= p;
			}
			if (cnt % 2 == 1)
				val *= p;
		}
		return val;
	}

	public static void main(String args[]) throws IOException {
		FastScanner in = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int t = in.nextInt();
		int max = (int)(1e7) + 1;

		boolean[] prime = new boolean[max + 1];
		Arrays.fill(prime, true);
		prime[0] = prime[1] = false;
		spf = new int[max];
		for (int i = 2; i < max; i++) spf[i] = i;
		for (int i = 2; i * i < max; i++) {
			if (prime[i]) {
				spf[i] = i;
				for (int j = i * i; j < max; j += i) {
					prime[j] = false;
					spf[j] = i;
				}
			}
		}

		int[] cnts = new int[max];

		for ( ; t > 0; t--) {
			int n = in.nextInt();
			int k = in.nextInt();
			int[] vals = new int[n];
			for (int i = 0; i < n; i++)
				vals[i] = factor(in.nextInt());

			// left[i][x] = l where al ... ai such that in x moves it is valid subsequence
			int[][] left = new int[n + 1][k + 1];
			// x y z w a b c

			for (int x = 0; x <= k; x++) {
				int l = n;
				int now = 0;
				for (int i = n - 1; i >= 0; i--) {
					while (l - 1 >= 0 && now + ((cnts[vals[l - 1]] > 0) ? 1 : 0) <= x) {
						l--;
						now += ((cnts[vals[l]] > 0) ? 1 : 0);
						// System.out.println(now);
						cnts[vals[l]]++;
					}
					// System.out.println(i + " " + x + " " + l + " " + now);
					left[i][x] = l;
					if (cnts[vals[i]] > 1) now--;
					cnts[vals[i]]--;
				}
			}

			// for (int[] x: left)
				// System.out.println(Arrays.toString(x));

			int oo = (int)(1e9);

			int[][] dp = new int[n + 1][k + 1];

			for (int i = 1; i <= n; i++)
				Arrays.fill(dp[i], oo);

			for (int i = 1; i <= n; i++) {
				for (int j = 0; j <= k; j++) {
					if (j > 0) dp[i][j] = dp[i][j - 1];
					for (int x = 0; x <= j; x++) {
						int l = left[i - 1][x];
						dp[i][j] = Math.min(dp[i][j], dp[l][j - x] + 1);
					}
				}
			}

			int min = Integer.MAX_VALUE;
			for (int i = 0; i <= k; i++) {
				min = Math.min(min, dp[n][i]);
			}

			out.println(min);
		}

		out.close();
	}

	static class FastScanner {
	    BufferedReader br;
	    StringTokenizer st;

	    public FastScanner(InputStream i) {
	        br = new BufferedReader(new InputStreamReader(i));
	        st = new StringTokenizer("");
	    }

	    public String next() throws IOException {
	        if(st.hasMoreTokens())
	            return st.nextToken();
	        else
	            st = new StringTokenizer(br.readLine());
	        return next();
	    }

	    public int nextInt() throws IOException {
	        return Integer.parseInt(next());
	    }
	    //#
	    public long nextLong() throws IOException {
	        return Long.parseLong(next());
	    }
	    public double nextDouble() throws IOException {
	        return Double.parseDouble(next());
	    }
	    //$
	}
}


//stan hu tao
//join nct ridin by first year culture reps
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.abs;
import static java.lang.System.out;
import java.util.*;
import java.io.*;
import java.math.*;

public class x1497E
{
    static final int MAX = 10000000;
    public static void main(String hi[]) throws Exception
    {
        int[] prime = new int[MAX+1];
        for(int d=2; d <= MAX; d++)
            if(prime[d] == 0)
                for(int v=d; v <= MAX; v+=d)
                    if(prime[v] == 0)
                        prime[v] = d;
        FastScanner infile = new FastScanner();
        int T = infile.nextInt();
        StringBuilder sb = new StringBuilder();
        int[] freq = new int[MAX+1];
        int[] ts = new int[MAX+1];
        int time = 0;
        while(T-->0)
        {
            int N = infile.nextInt();
            int K = infile.nextInt();
            int[] arr = infile.nextInts(N);
            for(int i=0; i < N; i++)
            {
                int key = 1;
                while(arr[i] > 1)
                {
                    int p = prime[arr[i]];
                    int cnt = 0;
                    while(arr[i]%p == 0)
                    {
                        arr[i] /= p;
                        cnt ^= 1;
                    }
                    if(cnt == 1)
                        key *= p;
                }
                arr[i] = key;
            }
            int[][] right = new int[N][K+1];
            for(int k=0; k <= K; k++)
            {
                int dex = 0;
                int cnt = 0;
                for(int i=0; i < N; i++)
                {
                    while(dex < N && cnt <= k)
                    {
                        if(ts[arr[dex]] == time && freq[arr[dex]] >= 1 && cnt+1 > k)
                            break;
                        if(ts[arr[dex]] == time && freq[arr[dex]] >= 1)
                            cnt++;
                        if(ts[arr[dex]] < time)
                        {
                            ts[arr[dex]] = time;
                            freq[arr[dex]] = 0;
                        }
                        freq[arr[dex]]++;
                        dex++;
                    }
                    right[i][k] = dex;
                    if(freq[arr[i]] >= 2)
                        cnt--;
                    freq[arr[i]]--;
                }
                time++;
            }
            int[][] dp = new int[N+1][K+1];
            for(int i=1; i <= N; i++)
                Arrays.fill(dp[i], N);
            for(int i=0; i < N; i++)
                for(int a=0; a <= K; a++)
                {
                    dp[i+1][a] = min(dp[i+1][a], dp[i][a]+1);
                    for(int b=0; b <= K-a; b++)
                        dp[right[i][b]][a+b] = min(dp[right[i][b]][a+b], dp[i][a]+1);
                }
            int res = dp[N][0];
            for(int k=1; k <= K; k++)
                res = min(res, dp[N][k]);
            sb.append(res+"\n");
        }
        System.out.print(sb);
    }
}
class FastScanner
{
    private int BS = 1 << 16;
    private char NC = (char) 0;
    private byte[] buf = new byte[BS];
    private int bId = 0, size = 0;
    private char c = NC;
    private double cnt = 1;
    private BufferedInputStream in;

    public FastScanner() {
        in = new BufferedInputStream(System.in, BS);
    }

    public FastScanner(String s) {
        try {
            in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
        } catch (Exception e) {
            in = new BufferedInputStream(System.in, BS);
        }
    }

    private char getChar() {
        while (bId == size) {
            try {
                size = in.read(buf);
            } catch (Exception e) {
                return NC;
            }
            if (size == -1) return NC;
            bId = 0;
        }
        return (char) buf[bId++];
    }

    public int nextInt() {
        return (int) nextLong();
    }

    public int[] nextInts(int N) {
        int[] res = new int[N];
        for (int i = 0; i < N; i++) {
            res[i] = (int) nextLong();
        }
        return res;
    }

    public long[] nextLongs(int N) {
        long[] res = new long[N];
        for (int i = 0; i < N; i++) {
            res[i] = nextLong();
        }
        return res;
    }

    public long nextLong() {
        cnt = 1;
        boolean neg = false;
        if (c == NC) c = getChar();
        for (; (c < '0' || c > '9'); c = getChar()) {
            if (c == '-') neg = true;
        }
        long res = 0;
        for (; c >= '0' && c <= '9'; c = getChar()) {
            res = (res << 3) + (res << 1) + c - '0';
            cnt *= 10;
        }
        return neg ? -res : res;
    }

    public double nextDouble() {
        double cur = nextLong();
        return c != '.' ? cur : cur + nextLong() / cnt;
    }

    public double[] nextDoubles(int N) {
        double[] res = new double[N];
        for (int i = 0; i < N; i++) {
            res[i] = nextDouble();
        }
        return res;
    }

    public String next() {
        StringBuilder res = new StringBuilder();
        while (c <= 32) c = getChar();
        while (c > 32) {
            res.append(c);
            c = getChar();
        }
        return res.toString();
    }

    public String nextLine() {
        StringBuilder res = new StringBuilder();
        while (c <= 32) c = getChar();
        while (c != '\n') {
            res.append(c);
            c = getChar();
        }
        return res.toString();
    }

    public boolean hasNext() {
        if (c > 32) return true;
        while (true) {
            c = getChar();
            if (c == NC) return false;
            else if (c > 32) return true;
        }
    }
}


import java.util.*;
import java.io.*;

public class Solve{
    public static void main(String[] args) throws Exception{
        Scanner sc=new Scanner(System.in);
        PrintWriter out =new PrintWriter(System.out);
        int size=(int)1e7+1;
        int[] pr=new int[size];
        for(int i=0;i<size;i++){
            pr[i]=i;
        }
        for(int i=2;i*i<size;i++){
           if(pr[i]==i){int val=i*i;
            for(int j=val;j<=size;j+=val){
                 pr[j]=j/val;
            }
           }
        }
        int t=sc.nextInt();
        int[] dp=new int[size];
        Arrays.fill(dp,-1);
        while(t-->0){
            int n=sc.nextInt();
            int k=sc.nextInt();
            int[] ar=new int[n];
            for(int i=0;i<n;i++){
                int a=sc.nextInt();
                ar[i]=pr[a];
            }
            int[] ans=new int[k+1];
            int[] ind=new int[k+1];
            for(int i=0;i<n;i++){
                for(int h=k;h>=0;h--){
                    if(dp[ar[i]]>=ind[h]){
                        ans[h]++;
                        ind[h]=i;
                    }
                    if(h>0 && (ans[h-1]<ans[h] ||(ans[h-1]==ans[h] && ind[h-1]>ind[h])))
                    {
                        ans[h]=ans[h-1];
                        ind[h]=ind[h-1];
                    }
                }
                dp[ar[i]]=i;
            }
            out.println(ans[k]+1);
            for(int i=0;i<n;i++)dp[ar[i]]=-1;
        }
        out.close();
    }
}


/**
 * author: derrick20
 * created: 3/19/21 11:57 PM
 */
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class E2_SquareFreeDivision2 {
    static FastScanner sc = new FastScanner();
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
//        generate();
        int MAX = (int) 1e7;
        int[] spf = new int[MAX + 1];
        for (int i = 2; i <= MAX; i++) {
            if (spf[i] == 0) {
                spf[i] = i;
                for (int j = i + i; j <= MAX; j += i) {
                    if (spf[j] == 0) {
                        spf[j] = i;
                    }
                }
            }
        }
        int[] freq = new int[MAX + 1];
        int T = sc.nextInt();
        while (T-->0) {
            int N = sc.nextInt();
            int K = sc.nextInt();
            int[] a = new int[N + 1];
            for (int i = 1; i <= N; i++) {
                a[i] = sc.nextInt();
                int canonical = 1;
                while (a[i] > 1) {
                    int factor = spf[a[i]];
                    int parity = 0;
                    while (a[i] % factor == 0) {
                        a[i] /= factor;
                        parity ^= 1;
                    }
                    if (parity == 1) {
                        canonical *= factor;
                    }
                }
                a[i] = canonical;
            }
            int[][] transition = new int[K + 1][N + 1];
//            HashMap<Integer, Integer> freq = new HashMap<>();
            for (int k = 0; k <= K; k++) {
                int l = N + 1;
                int duplicates = 0;
                for (int r = N; r >= 1; r--) {
                    while (l - 1 >= 1) {
                        int nextDuplicates = duplicates;
                        if (freq[a[l - 1]] >= 1) {
                            nextDuplicates++;
                        }
                        if (nextDuplicates <= k) {
                            duplicates = nextDuplicates;
                            freq[a[l - 1]]++;
                            l--;
                        } else {
                            break;
                        }
                    }
                    transition[k][r] = l;
                    if (--freq[a[r]] >= 1) {
                        duplicates--;
                    }
                }
            }
            int[][] dp = new int[K + 1][N + 1];
            int oo = (int) 1e9;
            for (int[] row : dp) {
                Arrays.fill(row, oo);
            }
            for (int k = 0; k <= K; k++) {
                dp[k][0] = 0;
            }
            for (int r = 1; r <= N; r++) {
                for (int k = 0; k <= K; k++) {
                    for (int delta = 0; delta <= k; delta++) {
                        dp[k][r] = min(dp[k][r], dp[k - delta][transition[delta][r] - 1] + 1);
                    }
                }
            }
            out.println(dp[K][N]);
        }
        out.close();
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        int nextInt() {
            return (int) nextLong();
        }

        long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        double nextDouble() {
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            double cur = nextLong();
            if (c != '.') {
                return neg ? -cur : cur;
            } else {
                double frac = nextLong() / cnt;
                return neg ? -cur - frac : cur + frac;
            }
        }

        String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }

    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}


import java.io.*;
import java.util.*;

public class Main {

    static final int primeCount = 452;
    static final int[] prime = new int[primeCount];

    static void build_prime() {
        boolean[] notPrime = new boolean[3200];
        for (int i = 2; i < 3200; i++) {
            if (notPrime[i]) continue;
            for (int j = i * i; j < 3200; j += i) {
                notPrime[j] = true;
            }
        }

        int count = 0;
        for (int i = 2; i < 3200; i++) {
            if (notPrime[i]) continue;

            prime[count++] = i;
        }
    }

    private static void run(Reader in, PrintWriter out) throws IOException {
        int n = in.nextInt();
        int m = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = getReal(in.nextInt());
        }

        int[] pre = new int[n];
        for (int i = 0; i < n; i++) pre[i] = -1;

        TreeMap<Integer, Integer> exist = new TreeMap<>();
        for (int i = 0; i < n; i++) {
            Integer result = exist.get(a[i]);
            if (result != null) {
                pre[i] = result;
            }
            exist.put(a[i], i);
        }

        int[][] left = new int[m + 1][n];
        for (int i = 0; i <= m; i++) {
            int start = 0;
            PriorityQueue<Integer> inSame = new PriorityQueue<>();
            for (int j = 0; j < n; j++) {
                if (pre[j] >= start) {
                    inSame.add(pre[j]);

                    if (inSame.size() > i) {
                        start = inSame.poll() + 1;
                    }
                }
                left[i][j] = start;
            }
        }

        int[][] dp = new int[n][m + 1];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= m; j++) {
                if (j == 0) dp[i][0] = Integer.MAX_VALUE;
                else dp[i][j] = dp[i][j - 1];

                for (int k = 0; k <= j; k++) {
                    if (left[k][i] == 0) {
                        dp[i][j] = 1;
                    } else {
                        dp[i][j] = Math.min(dp[i][j], dp[left[k][i] - 1][j - k] + 1);
                    }
                }
            }
        }

        out.println(dp[n - 1][m]);
    }

    static int getReal(int x) {
        int result = 1;
        for (int i = 0; i < primeCount; i++) {
            if (x % prime[i] == 0) {
                int count = 0;
                while (x % prime[i] == 0) {
                    count++;
                    x /= prime[i];
                }
                if (count % 2 == 1) {
                    result *= prime[i];
                }
            }
        }
        result *= x;
        return result;
    }

    public static void main(String[] args) throws IOException {
        Reader in = new Reader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

        build_prime();
        int t = in.nextInt();
        for (int i = 0; i < t; i++) {
            run(in, out);
        }

        out.flush();
        in.close();
        out.close();
    }

    static class Reader {
        BufferedReader reader;
        StringTokenizer st;

        Reader(InputStreamReader stream) {
            reader = new BufferedReader(stream, 32768);
            st = null;
        }

        void close() throws IOException {
            reader.close();
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        String nextLine() throws IOException {
            return reader.readLine();
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

    }
}


import java.io.*;
import java.util.*;

public class Main {

    static final int primeCount = 452;
    static final int[] prime = new int[primeCount];

    static void build_prime() {
        boolean[] notPrime = new boolean[3200];
        for (int i = 2; i < 3200; i++) {
            if (notPrime[i]) continue;
            for (int j = i * i; j < 3200; j += i) {
                notPrime[j] = true;
            }
        }

        int count = 0;
        for (int i = 2; i < 3200; i++) {
            if (notPrime[i]) continue;

            prime[count++] = i;
        }
    }

    private static void run(Reader in, PrintWriter out) throws IOException {
        int n = in.nextInt();
        int m = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = getReal(in.nextInt());
        }

        int[] pre = new int[n];
        for (int i = 0; i < n; i++) pre[i] = -1;

        TreeMap<Integer, Integer> exist = new TreeMap<>();
        for (int i = 0; i < n; i++) {
            Integer result = exist.get(a[i]);
            if (result != null) {
                pre[i] = result;
            }
            exist.put(a[i], i);
        }

        int[][] left = new int[m + 1][n];
        for (int i = 0; i <= m; i++) {
            int start = 0;
            PriorityQueue<Integer> inSame = new PriorityQueue<>();
            for (int j = 0; j < n; j++) {
                if (pre[j] >= start) {
                    inSame.add(pre[j]);

                    if (inSame.size() > i) {
                        start = inSame.poll() + 1;
                    }
                }
                left[i][j] = start;
            }
        }

        int[][] dp = new int[n][m + 1];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= m; j++) {
                dp[i][j] = Integer.MAX_VALUE;
            }
            for (int j = 0; j <= m; j++) {
                for (int k = 0; k <= j; k++) {
                    if (left[k][i] == 0) {
                        dp[i][j] = 1;
                    } else {
                        dp[i][j] = Math.min(dp[i][j], dp[left[k][i] - 1][j - k] + 1);
                    }
                }
            }
        }

        out.println(dp[n - 1][m]);
    }

    static int getReal(int x) {
        int result = 1;
        for (int i = 0; i < primeCount; i++) {
            if (x % prime[i] == 0) {
                int count = 0;
                while (x % prime[i] == 0) {
                    count++;
                    x /= prime[i];
                }
                if (count % 2 == 1) {
                    result *= prime[i];
                }
            }
        }
        result *= x;
        return result;
    }

    public static void main(String[] args) throws IOException {
        Reader in = new Reader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

        build_prime();
        int t = in.nextInt();
        for (int i = 0; i < t; i++) {
            run(in, out);
        }

        out.flush();
        in.close();
        out.close();
    }

    static class Reader {
        BufferedReader reader;
        StringTokenizer st;

        Reader(InputStreamReader stream) {
            reader = new BufferedReader(stream, 32768);
            st = null;
        }

        void close() throws IOException {
            reader.close();
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        String nextLine() throws IOException {
            return reader.readLine();
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.stream.IntStream;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.TreeSet;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        SquareFreeDivisionHardVersion solver = new SquareFreeDivisionHardVersion();
        solver.solve(1, in, out);
        out.close();
    }

    static class SquareFreeDivisionHardVersion {
        static final int MAX = 10000001;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int t = in.nextInt();
            int[] d = PrimesAndDivisors.generateDivisors(MAX);
            int[] reduced = new int[MAX];
            for (int i = 1; i < MAX; i++) {
                int val = i;
                reduced[i] = 1;
                while (val != 1) {
                    int prime = d[val], exponent = 0;
                    while (val % prime == 0) {
                        val /= prime;
                        exponent ^= 1;
                    }
                    if (exponent > 0) reduced[i] *= prime;
                }
            }
            int counter = 0;
            int[] seen = new int[MAX];
            for (int jjjj = 0; jjjj < t; jjjj++) {
                int n = in.nextInt(), k = in.nextInt();

                int[] a = in.readIntArray(n);
                for (int x : a) seen[reduced[x]] = -1;
                int[][] dp = new int[n + 1][k + 1];
                TreeSet<Integer> ts = new TreeSet<>();
                int num = 0;
                for (int i = 0; i < n; i++) {
                    int R = reduced[a[i]];
                    if (seen[R] != -1) {
                        ts.add(-seen[R]);
                        if (ts.size() > k + 1) ts.remove(ts.last());
                        num++;
                    }
                    Arrays.fill(dp[i], n + 1);
                    for (int j = num; j <= k; j++) dp[i][j] = 1;
                    seen[R] = i;
                    int u = 0;
                    for (int r : ts) {
                        for (int j = u; j <= k; j++) dp[i][j] = Integer.min(dp[i][j], dp[-r][j - u] + 1);
                        u++;
                    }
//                System.out.println(i + " "  + Arrays.toString(dp[i]));
//                System.out.println("Treeset : " + ts);
                }
                out.println(dp[n - 1][k]);
            }
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class PrimesAndDivisors {
        public static int[] generateDivisors(int n) {
            int[] divisors = IntStream.range(0, n + 1).toArray();
            for (int i = 2; i * i <= n; i++)
                if (divisors[i] == i)
                    for (int j = i * i; j <= n; j += i) divisors[j] = i;
            return divisors;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void println(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
            writer.print('\n');
        }

        public void close() {
            writer.close();
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class SolutionE extends Thread {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                                            InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

    private static final FastReader scanner = new FastReader();
    private static final PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
        new Thread(null, new SolutionE(), "Main", 1 << 26).start();
    }

    static final int[] primeFactors = getSmallestPrimeFactorInIntervalInclusive(10_000_000);

    public void run() {
        int t = scanner.nextInt();
        for (int i = 0; i < t; i++) {
            solve();
        }
        out.close();
    }

    //runs in roughly O(maxN * lg^2(maxN)))
    public static int[] getSmallestPrimeFactorInIntervalInclusive(int maxN) {
        int[] result = new int[maxN + 1];

        result[1] = 1;
        for (int i = 2; i <= maxN; i++) {
            if (result[i] == 0) {
                for (int j = i; j <= maxN; j += i) {
                    result[j] = (result[j / i] % i == 0) ? (result[j/i]/i) : (result[j/i]*i);
                }
            }
        }
        return result;
    }

    private static void solve() {
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = primeFactors[scanner.nextInt()];
        }

        Map<Integer, Integer> lastSeenIndex = new HashMap<>();
        int[] revertPointers = new int[n];
        for (int i = 0; i < n; i++) {
            if (lastSeenIndex.get(a[i]) != null) {
                revertPointers[i] = lastSeenIndex.get(a[i]);
            } else {
                revertPointers[i] = -1;
            }
            lastSeenIndex.put(a[i], i);
        }

        int[][] maxSegment = new int[n][k+1];
        for (int j = 0; j <= k; j++) {
            int pointerLeft = 0;
            int pointerRight = 0;
            boolean[] changed = new boolean[n];
            int amountChanged = 0;
            while (pointerLeft < n) {
                if (pointerRight < n && revertPointers[pointerRight] < pointerLeft) {
                    pointerRight++;
                } else if (pointerRight < n && revertPointers[pointerRight] >= pointerLeft && amountChanged < j) {
                    changed[revertPointers[pointerRight]] = true;
                    pointerRight++;
                    amountChanged++;
                } else {
                    if (changed[pointerLeft]) {
                        amountChanged--;
                    }
                    maxSegment[pointerLeft][j] = pointerRight;
                    pointerLeft++;
                }
            }
        }

        int[][] dp = new int[n+1][k+1];

        for (int j = 0; j <= k; j++) {
            dp[n][j] = 0;
        }

        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j <= k; j++) {
                dp[i][j] = n + 1;
                for (int x = 0; x <= j; x++) {
                    int nextJumpTo = maxSegment[i][x];
                    dp[i][j] = Math.min(dp[i][j], dp[nextJumpTo][j - x] + 1);
                }
            }
        }

        out.println(dp[0][k]);
    }

    //REMINDERS:
    //- CHECK FOR INTEGER-OVERFLOW BEFORE SUBMITTING

    //- CAN U BRUTEFORCE OVER SOMETHING, TO MAKE IT EASIER TO CALCULATE THE SOLUTION
}


/**
 * author: derrick20
 * created: 3/19/21 11:57 PM
 */
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class E2_SquareFreeDivision2 {
    static FastScanner sc = new FastScanner();
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
//        generate();
        int T = sc.nextInt();
        int MAX = (int) 1e7;
        int[] canonical = new int[MAX + 1];
        canonical[1] = 1;
        for (int factor = 2; factor <= MAX; factor++) {
            if (canonical[factor] == 0) {
                for (int mult = factor; mult <= MAX; mult += factor) {
                    int prev = canonical[mult / factor];
                    if (prev % factor == 0) {
                        canonical[mult] = prev / factor;
                    } else {
                        canonical[mult] = prev * factor;
                    }
                }
            }
        }
//        System.out.println(Arrays.toString(canonical));
        int[] freq = new int[MAX + 1];
        while (T-->0) {
            int N = sc.nextInt();
            int K = sc.nextInt();
            int[] a = new int[N + 1];
            for (int i = 1; i <= N; i++) {
                a[i] = canonical[sc.nextInt()];
            }
            int[][] transition = new int[K + 1][N + 1];
//            HashMap<Integer, Integer> freq = new HashMap<>();
            for (int k = 0; k <= K; k++) {
                int l = N + 1;
                int duplicates = 0;
                for (int r = N; r >= 1; r--) {
                    while (l - 1 >= 1) {
                        int nextDuplicates = duplicates;
                        if (freq[a[l - 1]] >= 1) {
                            nextDuplicates++;
                        }
                        if (nextDuplicates <= k) {
                            duplicates = nextDuplicates;
                            freq[a[l - 1]]++;
                            l--;
                        } else {
                            break;
                        }
                    }
                    transition[k][r] = l;
                    if (--freq[a[r]] >= 1) {
                        duplicates--;
                    }
                }
            }
            int[][] dp = new int[K + 1][N + 1];
            int oo = (int) 1e9;
            for (int[] row : dp) {
                Arrays.fill(row, oo);
            }
            for (int k = 0; k <= K; k++) {
                dp[k][0] = 0;
            }
            for (int r = 1; r <= N; r++) {
                for (int k = 0; k <= K; k++) {
                    for (int delta = 0; delta <= k; delta++) {
                        dp[k][r] = min(dp[k][r], dp[k - delta][transition[delta][r] - 1] + 1);
                    }
                }
            }
            out.println(dp[K][N]);
        }
        out.close();
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        int nextInt() {
            return (int) nextLong();
        }

        long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        double nextDouble() {
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            double cur = nextLong();
            if (c != '.') {
                return neg ? -cur : cur;
            } else {
                double frac = nextLong() / cnt;
                return neg ? -cur - frac : cur + frac;
            }
        }

        String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }

    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}


import java.util.*;
import java.io.*;
import java.math.*;
import java.text.*;

public class Main {
    static PrintWriter out;
    static Reader in;
    public static void main(String[] args) throws IOException {
        input_output();
        Main solver = new Main();
        solver.solve();
        out.close();
        out.flush();
    }

    static long INF = (long)1e18;
    static int MAXN = (int)1e7+5;
    static int mod = 998_244_353;
    static int n, m, q, t;
    static double pi = Math.PI;

    void solve() throws IOException{
    	t = in.nextInt();

    	int[] div = new int[MAXN];
    	Arrays.fill(div, 1);
    	for (int i = 2; i < MAXN; i++) {
    		if (div[i] == 1) {
    			for (int j = i; j < MAXN; j+=i) {
    				div[j] = i;
    			}
    		}
    	}

    	while (t --> 0) {
    		n = in.nextInt();
			int k = in.nextInt();

			int[] arr = new int[n+1];
			for (int i = 1; i <= n; i++) {
				arr[i] = in.nextInt();
				int tmp = arr[i], newn = 1;

				while (div[arr[i]] != 1) {
					int elm = div[arr[i]],
						cnt = 0;
					while (div[arr[i]] == elm) {
						cnt++;
						arr[i] /= elm;
					}
					if (cnt%2 == 1) newn *= elm;
				}
				newn *= arr[i];
				arr[i] = newn;
			}

			int[] close = new int[n+1];
			List<Node> list = new ArrayList<>();
			for (int i = 1; i <= n; i++) list.add(new Node(arr[i], i));
			Collections.sort(list);

			for (int i = 0; i < n; i++) {
				if (i == n-1 || list.get(i+1).val != list.get(i).val) {
					close[list.get(i).idx] = -1;
				} else {
					close[list.get(i).idx] = list.get(i+1).idx;
				}
			}

			int[][] next = new int[n+1][k+1];
			List<Integer> upd = new ArrayList<>();
			List<Integer> nupd = new ArrayList<>();
			for (int i = 0; i <= k; i++) next[n][i] = n;
			for (int i = n-1; i >= 1; i--) {
				nupd.clear();
				if (close[i] == -1) {
					for (int j = 0; j <= k; j++) next[i][j] = next[i+1][j];
				} else {
					int tmp = close[i]-1, cnt = 0;
					if (upd.size() == 0 || tmp < upd.get(0)) {
						nupd.add(tmp);
						tmp = -1;
					}
					for (int j = 0; j < upd.size(); j++) {
						if (nupd.size() < k+1 && tmp != -1 && tmp < upd.get(j)) {
							nupd.add(tmp);
							tmp = -1;
						}
						if (nupd.size() < k+1) nupd.add(upd.get(j));
					}
					if (tmp != -1 && nupd.size() < k+1) nupd.add(tmp);

					for (int j = 0; j < nupd.size(); j++)
						next[i][j] = nupd.get(j);
					for (int j = nupd.size(); j <= k; j++)
						next[i][j] = n;

					upd.clear();
					for (int j = 0; j < nupd.size(); j++) upd.add(nupd.get(j));
				}

			}

			int[][] dp = new int[n+1][k+1];
    		for (int i = 1; i <= n; i++)
    			for (int j = 0; j <= k; j++)
    				dp[i][j] = n;
    		for (int i = 0; i < n; i++) {
    			for (int cur = 0; cur <= k; cur++) {
    				for (int ncur = cur; ncur <= k; ncur++) {
    					dp[next[i+1][ncur-cur]][ncur] = Math.min(dp[next[i+1][ncur-cur]][ncur],
    															 dp[i][cur]+1);
    				}
    			}
    		}

    		int ans = n;
    		for (int i = 0; i <= k; i++) ans = Math.min(ans, dp[n][i]);
    		out.println(ans);
    	}
   	}

    //<>

    static class Node implements Comparable<Node> {
    	int val, idx;

    	Node (int val, int idx) {
    		this.val = val;
    		this.idx = idx;
    	}

    	public int compareTo(Node o) {
    		if (this.val != o.val) return this.val - o.val;
    		return this.idx - o.idx;
    	}
    }

    static class Reader {

        private InputStream mIs;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public Reader() {
            this(System.in);
        }

        public Reader(InputStream is) {
            mIs = is;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();

        }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = mIs.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public String nextLine() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

    }
    static void input_output() throws IOException {
        File f = new File("in.txt");
        if(f.exists() && !f.isDirectory()) {
            in = new Reader(new FileInputStream("in.txt"));
        } else in = new Reader();
        f = new File("out.txt");
        if(f.exists() && !f.isDirectory()) {
            out = new PrintWriter(new File("out.txt"));
        } else out = new PrintWriter(System.out);
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.math.*;

/*
 50
873 838 288 87 889 364 720 410 565 651 577 356 740 99 549 592 994 385 777 435 486 118 887 440 749 533 356 790 413 681 267 496 475 317 88 660 374 186 61 437 729 860 880 538 277 301 667 180 60 393

 6
 2 2 3 3 5 5

 4
 2 2 3 3

 */
public class C429 {

	static InputStream is;
	static int[] counts;
	static int[] sufsum;
	static long mod = (long)(1e9+7);
	static long[][] choose;
	static long[][] memo;
	public static void main(String[] args) throws IOException {

		is = System.in;
		int n = ni();
		int[] a = na(n);
		long[] fact = new long[n+2];
		fact[0] = 1;
		for (int i = 1; i < fact.length; i++) {
			fact[i] = (fact[i-1]*i)%mod;
		}

		HashMap<Integer,ArrayList<Integer>> hm = new HashMap<>();
		for (int i = 0; i < a.length; i++) {
			int cp = a[i];
			int sfree = 1;
			for(int p = 2; p*p <= a[i] && cp > 1; p++){
				int count = 0;
				while(cp % p == 0){
					cp /= p;
					count++;
				}
				if(count % 2 == 1) sfree *= p;
			}
			if(cp != 1) sfree *= cp;
			if(!hm.containsKey(sfree)) hm.put(sfree, new ArrayList<Integer>());
			hm.get(sfree).add(a[i]);
		}

		counts = new int[hm.size()];
		int dex = 0;

		//System.out.println(hm);
		long bigmult = 1;
		for(Integer key : hm.keySet()){
			ArrayList<Integer> list = hm.get(key);
			counts[dex++] = list.size();
			bigmult = bigmult*fact[list.size()] % mod;
//			HashMap<Integer,Integer> dups = new HashMap<>();
//			for(int x : list){
//				if(!dups.containsKey(x)){
//					dups.put(x, 0);
//				}
//				dups.put(x, dups.get(x)+1);
//			}

//			for (int k : dups.keySet()) {
//				int amount = dups.get(k);
//				long tomult = new BigInteger(fact[amount]+"").modInverse(new BigInteger(mod+"")).longValue();
//				bigmult*= tomult;
//				bigmult %= mod;
//			}

		}
		Arrays.sort(counts);
		sufsum = new int[counts.length];
		for(int i = counts.length-2; i >= 0; i--){
			sufsum[i] = sufsum[i+1]+counts[i+1];
		}

		choose = new long[2*n+3][2*n+3];
		for(int i = 0; i < choose.length; i++){
			choose[i][0] = 1;
			for(int j = 1; j <=i; j++){
				choose[i][j] = (choose[i-1][j]+choose[i-1][j-1])%mod;
			}
		}

		memo = new long[counts.length][700];
		for (int i = 0; i < memo.length; i++) {
			Arrays.fill(memo[i], -1);
		}
		//System.out.println("bigmult: " + bigmult);
		System.out.println((bigmult*dp(counts.length-2,counts[counts.length-1]-1))%mod);
	}

	static long dp(int dex, int need){
		if(dex == -1){
			if(need == 0) return 1;
			return 0;
		}
		//System.out.println("dex: " + dex + " need " + need);
		if(memo[dex][need] != -1) return memo[dex][need];
		int numspots = sufsum[dex]+1;
		long ret = 0;

		int c = counts[dex];
		for(int numdivs = 1; numdivs <= c; numdivs++) {
			long toadd = 0;

			for(int gotoneed =0; gotoneed <= need && gotoneed <= numdivs; gotoneed++) {
				long temp = choose[need][gotoneed];
				temp *= choose[numspots-need][numdivs-gotoneed];

				//System.out.println("dex: " + dex + " need: "+ need + " numdivs: " + numdivs + " c1: " + choose[need][gotoneed] + " c2 " +  choose[numspots-need][numdivs-gotoneed]);

				temp %= mod;
				temp *= dp(dex-1,need-gotoneed+c-numdivs);
				temp %= mod;

				toadd += temp;
				toadd %= mod;
			}
			toadd *= choose[c-1][numdivs-1];
			toadd %= mod;
			ret += toadd;
			ret %= mod;
		}

		//System.out.println("dex: " + dex + " need: "+ need + " ret: " + ret);

		return  memo[dex][need]=ret;
	}

	private static byte[] inbuf = new byte[1024];
	public static int lenbuf = 0, ptrbuf = 0;

	private static int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private static boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private static int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private static double nd() { return Double.parseDouble(ns()); }
	private static char nc() { return (char)skip(); }

	private static String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private static char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private static char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private static int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private static int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

}


//package round429;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

// 203530
public class C {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		int[] a = na(n);
		for(int i = 0;i < n;i++){
			int v = a[i];
			for(int j = 2;j*j <= v;j++){
				while(v % (j*j) == 0){
					v /= j*j;
				}
			}
			a[i] = v;
		}

		Arrays.sort(a);
		int[] f = new int[n];
		int p = 0;
		for(int i= 0;i < n;i++){
			if(i > 0 && a[i] != a[i-1]){
				p++;
			}
			f[p]++;
		}
		f = Arrays.copyOf(f, p+1);
		int mod = 1000000007;

		int[][] fif = enumFIF(1000, mod);
		long[] res = countSameNeighborsSequence(f, fif, mod);
		long ans = res[0];
		for(int v : f){
			ans = ans * fif[0][v] % mod;
		}

		out.println(ans);
	}

	public static int[][] enumFIF(int n, int mod) {
		int[] f = new int[n + 1];
		int[] invf = new int[n + 1];
		f[0] = 1;
		for (int i = 1; i <= n; i++) {
			f[i] = (int) ((long) f[i - 1] * i % mod);
		}
		long a = f[n];
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		invf[n] = (int) (p < 0 ? p + mod : p);
		for (int i = n - 1; i >= 0; i--) {
			invf[i] = (int) ((long) invf[i + 1] * (i + 1) % mod);
		}
		return new int[][] { f, invf };
	}

	public static long[] countSameNeighborsSequence(int[] a, int[][] fif, int mod)
	{
		int all = 0;
		for(int v : a)all += v;

		int len = 0;
		long[] dp = new long[all+1];
		dp[0] = 1;
		for(int v : a){
			long[][] pre = new long[all+1][v+1];
			for(int j = 0;j <= all;j++)pre[j][0] = dp[j];
			for(int j = 0;j < v;j++){
				for(int k = 0;k <= all;k++){
					for(int L = j;L >= 0;L--){
						if(pre[k][L] == 0)continue;
						int ca = 2*(j-L);
						int ab = len+j+1-k-ca-L;
						if(ab < 0)continue;
						if(k-1 >= 0){
							pre[k-1][L] += pre[k][L]*k; // aca
							pre[k-1][L] %= mod;
						}
						if(L+1 <= v){
							pre[k][L+1] += pre[k][L]*(ca+L);
							pre[k][L+1] %= mod;
						}
						pre[k][L] = pre[k][L]*ab%mod;
					}
				}
			}

			Arrays.fill(dp, 0);
			for(int k = 0;k <= all;k++){
				for(int L = 0;L <= v && k+L <= all;L++){
					dp[k+L] += pre[k][L];
				}
			}
			for(int k = 0;k <= all;k++){
				dp[k] %= mod;
			}
//			for(int k = 0;k <= all;k++){
//				dp[k] = dp[k] % mod * fif[1][v] % mod;
//			}
			len += v;
		}
		long fifs = 1;
		for(int v : a)fifs = fifs * fif[1][v] % mod;
		for(int k = 0;k <= all;k++)dp[k] = dp[k] * fifs % mod;

		return dp;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new C().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;

public class C {

	int removeSq(int x) {
		for (int i = 2; i * i <= x; i++) {
			while (x % (i * i) == 0) {
				x /= i * i;
			}
		}
		return x;
	}

	void submit() {
		int n = nextInt();
		HashMap<Integer, Integer> map = new HashMap<>();
		for (int i = 0; i < n; i++) {
			int x = removeSq(nextInt());
			map.merge(x, 1, Integer::sum);
		}

		int[] a = new int[map.size()];
		int ptr = 0;
		for (Integer x : map.values()) {
			a[ptr++] = x;
		}

		int ret = go(a);
		for (int x : a) {
			ret = (int)((long)ret * fact[x] % P);
		}

		out.println(ret);
	}

	int go(int[] a) {
		int[] dp = new int[a[0]];
		dp[a[0] - 1] = 1;

		int places = a[0] + 1;

		int toInsert = 0;
		for (int x : a) {
			toInsert += x;
		}
		toInsert -= a[0];

		for (int i =1; i < a.length; i++) {

			int here = a[i];
			if (here == 0) {
				continue;
			}

			int[] nxt = new int[dp.length + here];

			for (int wasSame = 0; wasSame < dp.length; wasSame++) {
				if (wasSame > toInsert) {
					continue;
				}
				if (dp[wasSame] == 0) {
					continue;
				}

				int wasDiff = places - wasSame;

				for (int runsSame = 0; runsSame <= wasSame && runsSame <= here; runsSame++) {
					for (int runsDiff = 0; runsDiff <= wasDiff && runsSame + runsDiff <= here; runsDiff++) {
						if (runsSame + runsDiff == 0) {
							continue;
						}
						int delta = (int) ((long) dp[wasSame]
								* ways[wasSame][runsSame] % P * ways[wasDiff][runsDiff]
								% P * ways[here - 1][runsSame + runsDiff - 1] % P);
						if (delta == 0) {
							continue;
						}
						int nxtIdx = (wasSame - runsSame) + (here - runsSame - runsDiff);
						nxt[nxtIdx] += delta;
						if (nxt[nxtIdx] >= P) {
							nxt[nxtIdx] -= P;
						}
					}
				}

			}

			dp = nxt;
			places += here;
			toInsert -= here;
		}

//		System.err.println(Arrays.toString(a) + " " + idx);
//		System.err.println(Arrays.toString(dp));
		return dp[0];
	}

	int[][] ways;
	int[] fact;
	static final int N = 350;
	static final int P = 1_000_000_007;

	void preCalc() {
		ways = new int[N][];
		for (int i = 0; i < N; i++) {
			ways[i] = new int[i + 1];
			ways[i][0] = ways[i][i] = 1;
			for (int j = 1; j < i; j++) {
				ways[i][j] = ways[i - 1][j] + ways[i - 1][j - 1];
				if (ways[i][j] >= P) {
					ways[i][j] -= P;
				}
			}
		}
		fact = new int[N];
		fact[0] = 1;
		for (int i = 1; i < N; i++) {
			fact[i] = (int)((long)fact[i - 1] * i % P);
		}
	}

	void stress() {

	}

	void test() {

	}

	C() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		preCalc();
		submit();
		//stress();
		//test();
		out.close();
	}

	static final Random rng = new Random();

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

	public static void main(String[] args) throws IOException {
		new C();
	}

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}

	long nextLong() {
		return Long.parseLong(nextToken());
	}

	double nextDouble() {
		return Double.parseDouble(nextToken());
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        final int MOD = (int) (1e9 + 7);
        long[][] C;
        long[] fact;

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            precalc(n);
            int[] a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = in.nextInt();
                a[i] = removeSquares(a[i]);
            }
            int[] g = getGroupSizes(a);
            long ans = solve(g);
            for (int x : g) {
                ans = ans * fact[x] % MOD;
            }
            out.println(ans);
        }

        private long solve(int[] a) {
            // For a description, see http://petr-mitrichev.blogspot.com/2017/07/a-week7.html
            long[] d = new long[1];
            d[0] = 1;
            int totalPositions = 1;
            for (int x : a) {
                long[] nd = new long[d.length + x + 1];
                for (int s = 0; s < d.length; s++) {
                    if (d[s] == 0) {
                        continue;
                    }
                    for (int m = 1; m <= x; m++) {
                        for (int p = 0; p <= s && p <= m; p++) {
                            long cur = d[s];
                            cur = cur * C[s][p] % MOD;
                            cur = cur * C[totalPositions - s][m - p] % MOD;
                            cur = cur * f(x, m) % MOD;
                            int ns = s + x - m - p;
                            nd[ns] += cur;
                            if (nd[ns] >= MOD) {
                                nd[ns] -= MOD;
                            }
                        }
                    }
                }
                totalPositions += x;
                d = nd;
            }
            return d[0];
        }

        private long f(int n, int k) {
            if (n < k) {
                return 0;
            }
            n -= k;
            return C[n + k - 1][k - 1];
        }

        private void precalc(int n) {
            fact = new long[n + 1];
            fact[0] = 1;
            for (int i = 1; i < fact.length; i++) {
                fact[i] = i * fact[i - 1] % MOD;
            }

            C = new long[1000][1000];
            C[0][0] = 1;
            for (int i = 1; i < C.length; i++) {
                C[i][0] = 1;
                for (int j = 1; j < C.length; j++) {
                    C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
                    if (C[i][j] >= MOD) {
                        C[i][j] -= MOD;
                    }
                }
            }
        }

        private int[] getGroupSizes(int[] a) {
            Arrays.sort(a);
            List<Integer> res = new ArrayList<>();
            for (int i = 0; i < a.length; ) {
                int j = i;
                while (j < a.length && a[i] == a[j]) {
                    ++j;
                }
                res.add(j - i);
                i = j;
            }
            int[] r = new int[res.size()];
            for (int i = 0; i < r.length; i++) {
                r[i] = res.get(i);
            }
            return r;
        }

        private int removeSquares(int n) {
            int res = 1;
            for (int d = 2; d * d <= n; d++) {
                if (n % d == 0) {
                    int cur = 0;
                    while (n % d == 0) {
                        n /= d;
                        ++cur;
                    }
                    if (cur % 2 == 1) {
                        res *= d;
                    }
                }
            }
            if (n > 1) {
                res *= n;
            }
            return res;
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}