Bizon the Champion isn't just charming, he also is very smart.

While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted an n × m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?

Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.

Input

The single line contains integers n, m and k (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m).

Output

Print the k-th largest number in a n × m multiplication table.

Examples

Input

2 2 2


Output

2


Input

2 3 4


Output

3


Input

1 10 5


Output

5

Note

A 2 × 3 multiplication table looks like this:
    
    
      
    1 2 3  
    2 4 6  
      
    
import java.util.*;
import java.io.*;

public class Main {
	static final int M = 1000000007;

	static class FastScanner {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

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

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

		long[] readArrayLong(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		int[] readArrayInt(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		long nextLong() {
			return Long.parseLong(next());
		}
		double nextDouble() {return Double.parseDouble(next());}
	}

	// sorting template
	static void sortLong(long[] a) {
		ArrayList<Long> l = new ArrayList<>();
		for (long i : a)
			l.add(i);
		Collections.sort(l);
		for (int i = 0; i < a.length; i++)
			a[i] = l.get(i);
	}

	static void sortInt(int[] a) {
		ArrayList<Integer> l = new ArrayList<>();
		for (int i : a)
			l.add(i);
		Collections.sort(l);
		for (int i = 0; i < a.length; i++)
			a[i] = l.get(i);
	}

	static class Graph {
		private ArrayList<Integer> adj[];
		public String s;
		public String dpch;

		Graph(int n) {
			adj = new ArrayList[n + 1];
			for (int i = 1; i <= n; i++) {
				adj[i] = new ArrayList<>();
			}
		}

		void addEdges(int u, int v) {
			adj[u].add(v);
			adj[v].add(u);
		}

		void dfs(int v, boolean[] vis) {
			vis[v] = true;
			for (int u : adj[v]) {
				if (!vis[u]) {
					dfs(u, vis);
				}
			}
		}

		int bfs(int v, boolean[] vis, int[] ans) {
			int sum = 0;
			Queue<Integer> q = new LinkedList<>();
			q.add(v);
			vis[v] = true;
			ans[v] = 0;
			while (q.size() > 0) {
				int node = q.poll();
				for (int u : adj[node]) {
					if (!vis[u]) {
						vis[u] = true;
						ans[u] = ans[node] + 1;
						q.add(u);
					}
				}
			}
			return sum;
		}
	}

	static class Pair<F, S> {
		F first;
		S second;

		Pair(F first, S second) {
			this.first = first;
			this.second = second;
		}

		public F getFirst() {
			return this.first;
		}

		public S getSecond() {
			return this.second;
		}
		// Sort on basis of first term, reverse p1.first and p2.first to sort in desc
		// Collections.sort(a, (p1, p2) -> (p1.first - p2.first));

		// Sort on the basis of second term, reverse p1.second and p2.second to sort
		// in
		// desc
		// Collections.sort(a, (p1, p2) -> (p1.second - p2.second));
	}

	static int __gcd(int a, int b) {
		if (b == 0)
			return a;
		return __gcd(b, a % b);
	}

	public static int subtree, maxNode, maxDist;
	public static int[] dist;
	public static int[] connected;

	public static void main(String[] args) throws IOException {
		FastScanner fs = new FastScanner();
		int t = 1;
		StringBuffer res = new StringBuffer();
		for (int tt = 1; tt <= t; tt++) {
			long n = fs.nextLong();
			long m = fs.nextLong();
			long k = fs.nextLong();
			long left = 1, right = n*m;
			while (left < right) {
				long mid = left + (right - left) / 2;
				if (condition(mid,n,m,k)) {
					right = mid;
				} else {
					left = mid + 1;
				}
			}
			res.append(left);
		}
		System.out.println(res);
	}
	private static boolean condition(long mid, long n, long m, long k) {
		long count = 0;
		for(long i=1;i<=m;i++){
			count += Math.min(mid, i*n)/i;
			if(count>=k) return true;
		}
		return count>=k;
	}
}
