Problem: You are given n arrays a_1, a_2, ..., a_n; each array consists of exactly m integers. We denote the y-th element of the x-th array as a_{x, y}.

You have to choose two arrays a_i and a_j (1 ≤ i, j ≤ n, it is possible that i = j). After that, you will obtain a new array b consisting of m integers, such that for every k ∈ [1, m] b_k = max(a_{i, k}, a_{j, k}).

Your goal is to choose i and j so that the value of min _{k = 1}^{m} b_k is maximum possible.

Input

The first line contains two integers n and m (1 ≤ n ≤ 3 ⋅ 10^5, 1 ≤ m ≤ 8) — the number of arrays and the number of elements in each array, respectively.

Then n lines follow, the x-th line contains the array a_x represented by m integers a_{x, 1}, a_{x, 2}, ..., a_{x, m} (0 ≤ a_{x, y} ≤ 10^9).

Output

Print two integers i and j (1 ≤ i, j ≤ n, it is possible that i = j) — the indices of the two arrays you have to choose so that the value of min _{k = 1}^{m} b_k is maximum possible. If there are multiple answers, print any of them.

Example

Input


6 5
5 0 3 1 2
1 8 9 1 3
1 2 3 4 5
9 1 0 3 7
2 3 0 6 3
6 4 1 7 0


Output


1 5

Solution (in JAVA):

Solution:
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

public class D {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int[][]arr = new int[n][m];
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				arr[i][j] = sc.nextInt();
			}
		}
		long a = 0;
		long b = (long)1e9;
		long mid = 0;
		long res = 0;
		while(a<=b){
			mid= (a+b)/2;
			TreeSet<Long>tr = new TreeSet<>();
			for(int i=0;i<n;i++){
				long r = 0;
				for(int j=0;j<m;j++){
					r*=2l;
					if(arr[i][j]>=mid){
						r+=1l;
					}
				}
				tr.add(r);
			}
			//System.out.println(mid  + " " +tr);
			long[] tmp = new long[tr.size()];
			for(int i=0;i<tmp.length;i++){
				tmp[i] = tr.pollFirst();
			}
			boolean f = false;

			for(int i=0;i<tmp.length &&!f;i++){
				for(int j=0;j<tmp.length;j++){
					//System.out.println(">>" + (tmp[i]|tmp[j]));
					if((tmp[i]|tmp[j]) == (1l<<m) -1l) {
						f = true;
						break;
					}
				}
			}
			if(f){
				res = mid;
				a = mid+1;

			}else{
				b = mid-1;
			}
		}
		//pw.print(res);
		TreeSet<Pair> h = new TreeSet<>();
		for(int i=0;i<n;i++){
			long r = 0;
			for(int j=0;j<m;j++){
				r*=2l;
				if(arr[i][j]>=res){
					r+=1l;
				}
			}
			h.add(new Pair(i,r));
		}
		Pair[] result = new Pair[h.size()];
		for(int i=0;i<result.length;i++){
			result[i] = h.pollFirst();
		}
		boolean found = true;
		for(int i=0;i<result.length &found;i++){
			for(int j=0;j<result.length&found;j++){
				if((result[i].bitmask|result[j].bitmask)==(1l<<m) - 1l){
					found = false;
					pw.println((result[i].index+1) + " " + (result[j].index+1));
					break;
				}
			}
		}

		pw.flush();
		pw.close();
	}
	static class Pair implements Comparable<Pair>{
		int index;
		long bitmask;
		public Pair(int index,long bitmask){
			this.index = index;
			this.bitmask = bitmask;
		}
		public int compareTo(Pair p){
			return Long.compare(this.bitmask,p.bitmask);
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(FileReader r) {
			br = new BufferedReader(r);
		}

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

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

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

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

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
	double res = 0, f = 1;
	boolean dec = false, neg = false;
	int start = 0;
	if (x.charAt(0) == '-') {
		neg = true;
		start++;
	}
	for (int i = start; i < x.length(); i++)
		if (x.charAt(i) == '.') {
			res = Long.parseLong(sb.toString());
			sb = new StringBuilder("0");
				dec = true;
			} else {
				sb.append(x.charAt(i));
				if (dec)
					f *= 10;
			}
		res += Long.parseLong(sb.toString()) / f;
		return res * (neg ? -1 : 1);
	}

	public boolean ready() throws IOException {
		return br.ready();

	}
	}
}