import java.util.*; import java.io.*; import java.math.*; import java.util.stream.*; import java.util.function.*; import java.security.SecureRandom; class Main implements Runnable { // 二分探索で、ある値(X)における.a,b,LCM(a,b)で割り切れる数(Y) -> X - Y == Kになる値を求めれば良いのかな? // あれ、lcmってO(logN)だっけ.そうだと信じる. void solve() { int T = in.nextInt(); while(T-->0) { long A = in.nextLong() , B = in.nextLong() , K = in.nextLong(); long lcm = LCM(A , B); long l = 0 , r = (long) 1e19; while(r - l > 1) { long X = (r + l) / 2 ; long Kth = X - (((X / A) + (X / B)) - (X / lcm)); if(Kth < K) l = X ; if(Kth >= K) r = X ; } out.println(r); } } public static void main(String ... args) { new Thread(null, new Main(), "", Runtime.getRuntime().maxMemory()).start(); } public void run() { solve(); out.flush(); } //ペア record IP(int fi , int se) { public String toString() { return fi +" "+ se ;} } record LP(long fi , long se) { public String toString() { return fi +" "+ se ;} } record SP(String fi , String se) { public String toString() { return fi +" "+se; } } //距離 double MAN(LP p1 , LP p2) { return Math.abs(p1.fi - p2.fi) + Math.abs(p1.se - p2.se) ; } double EUC(LP p1 , LP p2) { return Math.sqrt((p1.fi - p2.fi) * (p1.fi - p2.fi) + (p1.se - p2.se) * (p1.se - p2.se)); } //階乗 long REC(long a) { return a == 1 ? 1 : a * REC(a - 1); } //合計 int SUM(int ... a) { int sum = 0 ; for(int p : a) sum += p ; return sum ;} long SUM(long ... a) { long sum = 0 ; for(long p : a) sum += p ; return sum ;} //最大 int MAX(int ... a) { int max = -1 ; for(int p : a) max = Math.max(max , p); return max; } long MAX(long ... a) { long max = -1 ; for(long p : a) max = Math.max(max , p); return max; } //最小 int MIN(int ... a) { int min = Integer.MAX_VALUE ; for(int p : a) min = Math.min(min , p); return min; } long MIN(long ... a) { long min = Long.MAX_VALUE ; for(long p : a) min = Math.min(min , p); return min; } //冪乗 int POW(int a , int b) { return (int) Math.pow(a , b) ; } long POW(long a , long b) { return (long) Math.pow(a , b) ; } //最小公倍数 int LCM(int a, int b) { return a / GCD(a, b) * b; } long LCM(long a, long b) { return a / GCD(a, b) * b; } int LCM(int ... a) { int lcm = 1 ; for(int p : a) lcm = LCM(lcm , p) ; return lcm ; } long LCM(long ... a) { long lcm = 1 ; for(long p : a) lcm = LCM(lcm , p) ; return lcm ; } BigInteger LCM(BigInteger x, BigInteger y) { return x.multiply(y).divide(Objects.nonNull(GCD(x, y)) ? GCD(x, y) : BigInteger.ONE); } BigInteger LCM(BigInteger ... arr) { return Stream.of(arr).reduce((x, y) -> LCM(x, y)).orElse(BigInteger.ONE); } //最大公約数 int GCD(int a, int b) { return b == 0 ? a: GCD(b, a % b); } long GCD(long a, long b) { return b == 0 ? a: GCD(b, a % b); } int GCD(int ... a) { int gcd = 0 ; for(int p : a) gcd = GCD(gcd , p) ; return gcd ; } long GCD(long ... a) { long gcd = 0L ; for(long p : a) gcd = GCD(gcd , p) ; return gcd ; } BigInteger GCD(BigInteger x, BigInteger y) { return (Objects.nonNull(x) ? x : BigInteger.ONE).gcd(y); } BigInteger GCD(BigInteger ... arr) { return Stream.of(arr).reduce(BigInteger::gcd).orElse(BigInteger.ZERO); } //反転 String REVERSE(String a) { return new StringBuilder(a).reverse().toString(); } int [] REVERSE(int [] a) { int [] r = new int[a.length] ; int idx = a.length ; for(int p : a) r[--idx] = p ; return r ; } long [] REVERSE(long [] a) { long [] r = new long[a.length] ; int idx = a.length ; for(long p : a) r[--idx] = p ; return r ; } //配列 void FILL(int [] a , int v) { Arrays.fill(a , v); } void FILL(long [] a , long v) { Arrays.fill(a , v); } void FILL(char [] a , char v) { Arrays.fill(a , v); } void FILL(int [][] a , int v) { for(int [] aa : a) FILL(aa , v) ; } void FILL(long [][] a , long v) { for(long [] aa : a) FILL(aa , v) ; } void FILL(char [][] a , char v) { for(char [] aa : a) FILL(aa , v) ; } void FILL(int [][][] a , int v) { for(int [][] aa : a) FILL(aa , v); } void FILL(long [][][] a , long v) { for(long [][] aa : a) FILL(aa , v); } int [] COPY(int [] a) { return Arrays.copyOf(a , a.length); } long [] COPY(long [] a) { return Arrays.copyOf(a , a.length); } char [] COPY(char [] a) { return Arrays.copyOf(a , a.length); } //スワップ String SWAP(String s , int l , int r) { StringBuilder m = new StringBuilder(s) ;m.setCharAt(l, s.charAt(r)); m.setCharAt(r, s.charAt(l)); return m.toString(); } int [] SWAP(int [] a , int l , int r) { int tmp = a[l] ; a[l] = a[r] ; a[r] = tmp ; return a ; } long [] SWAP(long [] a , int l , int r) { long tmp = a[l] ; a[l] = a[r] ; a[r] = tmp ; return a ; } //ペア配列入力 IP [] IPA(int n) { IP [] a = new IP[n]; for(int i = 0 ; i < n ; i ++ ) a[i] = new IP(in.nextInt() , in.nextInt()); return a ; } LP [] LPA(int n) { LP [] a = new LP[n]; for(int i = 0 ; i < n ; i ++ ) a[i] = new LP(in.nextLong() , in.nextLong()); return a ; } //進数 String BIN(long a , int len) { String b = Long.toBinaryString(a); while(b.length() < len) b = "0" + b ; return b ; } //デバッグ void DEBUG(int [] a) { out.println(Arrays.toString(a)); fl();} void DEBUG(long [] a) { out.println(Arrays.toString(a)); fl();} void DEBUG(double [] a) { out.println(Arrays.toString(a)); fl();} void DEBUG(String [] a) { out.println(Arrays.toString(a)); fl();} void DEBUG(char [] a) { out.println(Arrays.toString(a)); fl();} void DEBUG(boolean [] a) { char [] c = CV(a); DEBUG(c); fl();} void DEBUG(int [][] a) { for(int i = 0 ; i < a.length ; i ++ ) out.println(Arrays.toString(a[i])); fl();} void DEBUG(long [][] a) { for(int i = 0 ; i < a.length ; i ++ ) out.println(Arrays.toString(a[i])); fl();} void DEBUG(double [][] a) { for(int i = 0 ; i < a.length ; i ++ ) out.println(Arrays.toString(a[i])); fl();} void DEBUG(String [][] a) { for(int i = 0 ; i < a.length ; i ++ ) out.println(Arrays.toString(a[i])); fl();} void DEBUG(char [][] a) { for(int i = 0 ; i < a.length ; i ++ ) out.println(Arrays.toString(a[i])); fl();} void DEBUG(boolean [][] a) { char [][] c = new char [a.length][a[0].length] ; for(int i = 0 ; i < a.length ; i ++ ) c[i] = CV(a[i]) ; DEBUG(c); fl();} private char [] CV(boolean [] a) { char [] c = new char[a.length] ; for(int i = 0 ; i < a.length ; i ++ ) c[i] = a[i] ? 'O' : 'X' ; return c ; } private void fl() { out.flush(); } //変換 List TOLIST(int [] a) { var List = Arrays.stream(a).boxed().collect(Collectors.toList()); return List; } List TOLIST(long [] a) { var List = Arrays.stream(a).boxed().collect(Collectors.toList()); return List; } Set TOSET(int [] a) { var List = Arrays.stream(a).boxed().collect(Collectors.toSet()); return List; } Set TOSET(long [] a) { var List = Arrays.stream(a).boxed().collect(Collectors.toSet()); return List; } //分布 int [] COUNT(int [] a) { int [] A = new int[a.length] ; for(int v : a) ++A[v] ; return A ; } Map COUNT(long [] a) { Map C = new HashMap<>(); for(long v : a) C.put(v , C.getOrDefault(v , 0) + 1) ; return C ; } //グラフ入力 List [] GRAPH(int n) { List [] G = new ArrayList[n]; for(int i = 0 ; i < n ; i ++ ) G[i] = new ArrayList<>(); return G ; } //個数(二分探索) > int LOW_(List A , T key) { return upperbound(A, key); } > int LOW(List A , T key) { return lowerbound(A, key); } > int HIGH_(List A , T key) { return A.size() - lowerbound(A, key); } > int HIGH(List A , T key) { return A.size() - upperbound(A, key); } > int lowerbound(List A, T key) {int left = 0;int right = A.size();while (left < right) {int mid = (left + right) / 2;if (A.get(mid).compareTo(key) < 0) left = mid + 1;else right = mid;}return right;} > int upperbound(List A, T key) { int left = 0;int right = A.size();while (left < right) {int mid = (left + right) / 2;if (A.get(mid).compareTo(key) <= 0) left = mid + 1;else right = mid;}return right;} //定数.. PrintWriter out = new PrintWriter(System.out); In in = new In(); final long MOD7 = 1000000007; final long MOD9 = 998244353; final int inf = (1 << 30); final long lnf = (1L << 60); final String yes = "Yes"; final String no = "No" ; final char [] dir = {'U','R','D','L'}; final int [] dy4 = {-1,0,1,0}; final int [] dx4 = {0,1,0,-1}; final int [] dy8 = {-1,-1,-1,0,1,1,1,0}; final int [] dx8 = {-1,0,1,1,1,0,-1,-1}; } class CC { TreeSet order ; Map comp ; int count ; CC(List L) { this.order = new TreeSet<>(L) ; this.comp = new HashMap<>(); this.count = 0 ; for(T v : order) comp.put(v , count++); } int get(T value) { return comp.get(value); } } class In { private final InputStream in = System.in; private final byte[] buffer = new byte[1024]; private Scanner sc = new Scanner(System.in); private int ptr = 0; private int buflen = 0; private boolean hasNextByte() { if (ptr < buflen) { return true; }else{ ptr = 0; try { buflen = in.read(buffer); } catch (IOException e) { e.printStackTrace(); } if (buflen <= 0) { return false; } } return true; } private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1; } private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126; } private boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) { ptr++; } return hasNextByte(); } String next() { if (!hasNext()) throw new NoSuchElementException(); StringBuilder sb = new StringBuilder(); int b = readByte(); while(isPrintableChar(b)) { sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } long nextLong() { if (!hasNext()) throw new NoSuchElementException(); long n = 0; boolean minus = false; int b = readByte(); if (b == '-') { minus = true; b = readByte(); } if (b < '0' || '9' < b) { throw new NumberFormatException(); } while(true){ if ('0' <= b && b <= '9') { n *= 10; n += b - '0'; }else if(b == -1 || !isPrintableChar(b)){ return minus ? -n : n; }else{ throw new NumberFormatException(); } b = readByte(); } } int nextInt() { long nl = nextLong(); if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException(); return (int) nl; } double nextDouble() { return Double.parseDouble(next()); } char nextChar() { return next().charAt(0); } int [] IntArray(int n) { final int [] Array = new int [n]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = nextInt(); } return Array; } int [][] IntArray(int n , int m) { final int [][] Array = new int [n][m]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = IntArray(m); } return Array; } long [] LongArray(int n) { final long [] Array = new long [n]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = nextLong(); } return Array; } long [][] LongArray(int n , int m) { final long [][] Array = new long [n][m]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = LongArray(m); } return Array; } String [] StringArray(int n) { final String [] Array = new String [n]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = next(); } return Array; } char [] CharArray(int n) { final char [] Array = new char[n]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = next().charAt(0); } return Array; } char [][] CharArray(int n , int m) { final char [][] Array = new char [n][m]; for(int i = 0 ; i < n ; i ++ ) { Array[i] = next().toCharArray(); } return Array; } char [][] CharArray2(int n , int m) { final char [][] Array = new char [n][m]; for(int i = 0 ; i < n ; i ++ ) { for(int j = 0 ; j < m ; j ++ ) { Array[i][j] = next().charAt(0); } } return Array; } BigInteger nextBigInteger() { return sc.nextBigInteger(); } }