import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class Techno19_2F {

	static int MODE = -1;

	static final Comparator<int[]> COMP_ARR = new Comparator<int[]>() {
		public int compare(int[] a1, int[] a2) {
			if (MODE != -1 && (a1.length == 32 || a2.length == 32)) {
				if (a1.length == 32) {
					if (MODE < a2.length) {
						return -1;
					}
					if (MODE > a2.length) {
						return 1;
					}
				} else {
					if (a1.length < MODE) {
						return -1;
					}
					if (a1.length > MODE) {
						return 1;
					}
				}

				for (int i = 0; i < MODE; i++) {
					if (a1[i] < a2[i]) {
						return -1;
					}
					if (a1[i] > a2[i]) {
						return 1;
					}
				}
				return 0;
			} else {
				if (a1.length < a2.length) {
					return -1;
				}
				if (a1.length > a2.length) {
					return 1;
				}

				for (int i = 0; i < a2.length; i++) {
					if (a1[i] < a2[i]) {
						return -1;
					}
					if (a1[i] > a2[i]) {
						return 1;
					}
				}
				return 0;
			}
		}
	};

	static TreeMap<int[], Integer> index = new TreeMap<>(COMP_ARR);
	static int[][] states;

	static ArrayList<int[]> start = new ArrayList<>();

	static int[] numD;

	static int[] pFact = new int[1_000_001];

	static TreeMap<int[], Integer> divCostInd = new TreeMap<>(COMP_ARR);

	public static void main(String[] args) throws IOException {
		cGen = new int[23];
		numD = new int[6000];
		states = new int[6000][];
		genAll(0, 23, 23, 1);

		aList = new ArrayList[6000];
		for (int i = 0; i < 6000; i++) {
			aList[i] = new ArrayList<>();
		}
		fAList();

		divCost = new int[400][301];
		for (int[] a : divCost) {
			Arrays.fill(a, Integer.MAX_VALUE / 2);
		}
		cost = new int[index.size()];

		Arrays.fill(pFact, 1);
		for (int i = 2; i <= 1_000_000; i++) {
			if (pFact[i] == 1) {
				for (int m = i; m <= 1_000_000; m += i) {
					pFact[m] = i;
				}
			}
		}

		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

		int nT = Integer.parseInt(reader.readLine());

		while (nT-- > 0) {
			StringTokenizer inputData = new StringTokenizer(reader.readLine());
			int a = Integer.parseInt(inputData.nextToken());
			int b = Integer.parseInt(inputData.nextToken());

			int[] aA = toArray(a);
			int[] bA = toArray(b);

			Integer aRes = divCostInd.get(aA);
			if (aRes == null) {
				aRes = divCostInd.size();
				bfs(aA, divCostInd.size());
				divCostInd.put(aA, divCostInd.size());
			}
			Integer bRes = divCostInd.get(bA);
			if (bRes == null) {
				bRes = divCostInd.size();
				bfs(bA, divCostInd.size());
				divCostInd.put(bA, divCostInd.size());
			}

			int minA = Integer.MAX_VALUE / 4;
			for (int nD = 1; nD <= 300; nD++) {
				minA = Math.min(minA, divCost[aRes][nD] + divCost[bRes][nD]);
			}
			printer.println(minA);
		}
		printer.close();
	}

	static int[] toArray(int a) {
		ArrayList<Integer> cnts = new ArrayList<Integer>();
		int last = -1;
		int cCnt = 0;

		while (a > 1) {
			int cPFact = pFact[a];
			if (cPFact == last) {
				cCnt++;
			} else {
				if (cCnt != 0) {
					cnts.add(cCnt);
				}
				last = cPFact;
				cCnt = 1;
			}
			a /= pFact[a];
		}
		if (cCnt != 0) {
			cnts.add(cCnt);
		}
		Collections.sort(cnts, Comparator.reverseOrder());
		int[] res = new int[cnts.size()];
		for (int i = 0; i < cnts.size(); i++) {
			res[i] = cnts.get(i);
		}
		return res;
	}

	static int[] cost;

	static int[][] divCost;

	static void bfs(int[] sState, int searchI) {
		int sInd = index.get(sState);
		ArrayDeque<Integer> queue = new ArrayDeque<>();

		queue.add(index.get(sState));

		Arrays.fill(cost, -1);
		cost[sInd] = 0;

		while (!queue.isEmpty()) {
			int cStInd = queue.remove();
			for (int nStInd : aList[cStInd]) {
				if (cost[nStInd] == -1) {
					cost[nStInd] = cost[cStInd] + 1;
					queue.add(nStInd);
				}
			}
		}

		for (Entry<int[], Integer> cE : index.entrySet()) {
			int cNumD = numD[cE.getValue()];
			if (cNumD <= 300) {
				divCost[searchI][cNumD] = Math.min(divCost[searchI][cNumD], cost[cE.getValue()]);
			}
		}
	}

	static ArrayList<Integer>[] aList;

	static void fAList() {
		int[] cState = new int[32];
		for (Entry<int[], Integer> cE : index.entrySet()) {
			int[] oState = cE.getKey();
			int cStInd = cE.getValue();

			int cLen = states[cStInd].length;
			for (int i = 0; i < cLen; i++) {
				cState[i] = oState[i];
			}
			MODE = cLen;

			for (int i = 0; i < cLen; i++) {
				if (i == 0 || cState[i - 1] > cState[i]) {
					cState[i]++;
					Integer nStInd = index.get(cState);
					cState[i]--;

					if (nStInd == null) {
						continue;
					}
					aList[cStInd].add(nStInd);
				}

				if (i == cLen - 1 && cState[i] == 1) {
					MODE--;
					Integer nStInd = index.get(cState);
					MODE++;
					if (nStInd == null) {
						continue;
					}
					aList[cStInd].add(nStInd);
				} else if (i == cLen - 1 || cState[i] > cState[i + 1]) {
					cState[i]--;
					Integer nStInd = index.get(cState);
					cState[i]++;
					if (nStInd == null) {
						continue;
					}
					aList[cStInd].add(nStInd);
				}
			}
			cState[cLen] = 1;

			MODE++;
			Integer nStInd = index.get(cState);
			MODE--;
			if (nStInd == null) {
				continue;
			}
			aList[cStInd].add(nStInd);
		}
	}

	static int[] cGen;

	static void genAll(int i, int max, int rem, int cProd) {
		numD[index.size()] = cProd;

		int[] cKey = Arrays.copyOf(cGen, i);
		states[index.size()] = cKey;
		index.put(cKey, index.size());

		if (rem > 0) {
			for (int nV = Math.min(max, rem); nV >= 1; nV--) {
				cGen[i] = nV;
				genAll(i + 1, nV, rem - nV, cProd * (nV + 1));
			}
		}
	}
}

//package round517;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class D3 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int[] lpf = enumLowestPrimeFactors(1000000);
		Map<Long, int[]> map = new HashMap<>();
		long[] hs = new long[1000001];
		for(int i = 1;i <= 1000000;i++){
			int[] lu = factorE(i, lpf);
			Arrays.sort(lu);
			hs[i] = (long)Arrays.hashCode(lu);
			map.put(hs[i], lu);
		}

		int K = 8;
		List<List<Set<Long>>> ls = new ArrayList<>();
		List<int[]> vs = new ArrayList<>(map.values());
		int gen = 0;
		Map<Long, Integer> htov = new HashMap<>();
		for(int[] v : vs){
			htov.put((long)Arrays.hashCode(v), gen++);
			cache = new HashSet<>();
			List<Set<Long>> hey = new ArrayList<>();
			for(int t = 0;t <= K;t++)hey.add(new HashSet<>());
			dfs(v, 0, K, hey);
			ls.add(hey);
		}

		int[][] cans = new int[ls.size()][ls.size()];
		for(int i = 0;i < ls.size();i++){
			Arrays.fill(cans[i], -1);
		}

		outer:
		for(int T = ni();T > 0;T--){
			int a = ni(), b = ni();
			int ia = htov.get(hs[a]);
			int ib = htov.get(hs[b]);
			if(cans[ia][ib] != -1){
				out.println(cans[ia][ib]);
				continue;
			}
			for(int d = 0;d <= 16;d++){
				for(int i = 0;i <= d && i <= 8;i++){
					int j = d-i;
					if(j >= 0 && j <= 8){
						if(!Collections.disjoint(ls.get(ia).get(i), ls.get(ib).get(j))){
							cans[ia][ib] = cans[ib][ia] = d;
							out.println(d);
							continue outer;
						}
					}
				}
			}
			throw new RuntimeException();
		}
	}

	Set<Long> cache = new HashSet<>();

	void dfs(int[] a, int dep, int lim, List<Set<Long>> set)
	{
		long h = dep + 114514;
		for(int v : a)h = h * 1000000009 + v;
		if(!cache.add(h)){
			return;
		}

		long x = 1;
		for(int v : a){
			x = x * (v+1);
		}
		set.get(dep).add(x);
		if(dep == lim)return;

		for(int i = 0;i < a.length;i++){
			if(i > 0 && a[i] == a[i-1])continue;
			if(a[i] > 1){
				int[] b = Arrays.copyOf(a, a.length);
				b[i]--;
				Arrays.sort(b);
				dfs(b, dep+1, lim, set);
			}
			{
				int[] b = Arrays.copyOf(a, a.length);
				b[i]++;
				Arrays.sort(b);
				dfs(b, dep+1, lim, set);
			}
			if(a[i] == 1){
				int[] b = Arrays.copyOf(a, a.length-1);
				int p = 0;
				for(int j = 0;j < a.length;j++){
					if(j == i)continue;
					b[p++] = a[j];
				}
				dfs(b, dep+1, lim, set);
			}
		}
		int[] b = Arrays.copyOf(a, a.length+1);
		b[a.length] = 1;
		Arrays.sort(b);
		dfs(b, dep+1, lim, set);
	}

	public static int[] factorE(int n, int[] lpf)
	{
		int[] f = new int[9];
		int q = 0;
		int pre = -1;
		while(lpf[n] > 0){
			int p = lpf[n];
			if(p != pre){
				pre = p;
				f[q++] = 1;
			}else{
				f[q-1]++;
			}
			n /= p;
		}
		if(n > 1){
			// big prime
			return new int[]{1};
		}
		return Arrays.copyOf(f, q);
	}

	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
	{
//		int n = 99999, m = 99999;
//		StringBuilder sb = new StringBuilder();
//		sb.append(n + " ");
//		for (int i = 0; i < n; i++) {
//			sb.append(36 + " " + (3*5*7*11<<9) + "\n");
//		}
//		INPUT = sb.toString();

		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 D3().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)); }
}