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.util.*;
import java.io.*;
import java.lang.*;
public class EdA {

	public static void main(String[] args) throws java.lang.Exception{
		int num = 998244353;

		// TODO Auto-generated method stub
 		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
 		PrintWriter out = new PrintWriter(System.out);
 		StringTokenizer st = new StringTokenizer(bf.readLine());
 		int n = Integer.parseInt(st.nextToken());
 		int m = Integer.parseInt(st.nextToken());
 		int prod = 1;
 		int[][] matrix = new int[n][m];
 		for(int j = 0;j<n;j++){
 			StringTokenizer st1 = new StringTokenizer(bf.readLine());
 			prod = 1;
 			for(int k = 0;k<m;k++){
 				matrix[j][k] = Integer.parseInt(st1.nextToken());
 				prod*=2;
 			}
 		}
 		Map<ArrayList<Integer>, Boolean> map = new HashMap<ArrayList<Integer>, Boolean>();
 		for(int j = 0;j< prod*prod;j++){
 			String temp = Integer.toBinaryString(j);
 			ArrayList<Integer> inp = new ArrayList<Integer>();
 			for(int k = 0;k<2*m-temp.length();k++){
 				inp.add(0);
 			}
 			for(int k = 0;k<temp.length();k++){
 				inp.add(Integer.parseInt(temp.charAt(k) + ""));
 			}
 			boolean and = true;
 			for(int k = 0;k<m;k++)
 				and = and && !(inp.get(k) == 0 && inp.get(k+m) == 0);
 			map.put(inp,  and);
 		}
 		int l = 0;
 		int r = 1000000000;
 		int c1 = 0;
 		int c2 = 0;
 		while(l < r){
 			int mid = (l+r+1)/2;
 			Map<ArrayList<Integer>, Integer> mp = new HashMap<ArrayList<Integer>, Integer>();
 			ArrayList<ArrayList<Integer>> array = new ArrayList<ArrayList<Integer>>();
 			for(int j = 0;j<n;j++){
 				ArrayList<Integer> temp = new ArrayList<Integer>();
 				for(int k = 0;k<m;k++){
 					temp.add(matrix[j][k] >=mid ? 1 : 0);
 				}
 				if (!mp.containsKey(temp)){
 					mp.put(temp,  j);
 					array.add(temp);
 				}
 			}
 			int truecount = 0;
 			for(int j = 0;j<array.size();j++){
 				for(int k=j;k<array.size();k++){
 					c1 = mp.get(array.get(j));
 					c2 = mp.get(array.get(k));
 					ArrayList<Integer> temp = new ArrayList<Integer>();
 					for(int ts = 0;ts<array.get(j).size();ts++)
 						temp.add(array.get(j).get(ts));
 					for(int ts = 0;ts<array.get(k).size();ts++)
 						temp.add(array.get(k).get(ts));
 					if (map.get(temp)){
 						truecount++;
 					}
 				}
 			}
 			
 			if (truecount > 0)
 				l = mid;
 			else
 				r = mid-1;
 			
 		} 
 		
 		
 		int mid = (l+r+1)/2;
			Map<ArrayList<Integer>, Integer> mp = new HashMap<ArrayList<Integer>, Integer>();
			ArrayList<ArrayList<Integer>> array = new ArrayList<ArrayList<Integer>>();
			for(int j = 0;j<n;j++){
				ArrayList<Integer> temp = new ArrayList<Integer>();
				for(int k = 0;k<m;k++){
					temp.add(matrix[j][k] >=mid ? 1 : 0);
				}
				if (!mp.containsKey(temp)){
					mp.put(temp,  j);
					array.add(temp);
				}
			}
			for(int j = 0;j<array.size();j++){
				for(int k=j;k<array.size();k++){
					
					ArrayList<Integer> temp = new ArrayList<Integer>();
					for(int ts = 0;ts<array.get(j).size();ts++)
						temp.add(array.get(j).get(ts));
					for(int ts = 0;ts<array.get(k).size();ts++)
						temp.add(array.get(k).get(ts));
					if (map.get(temp)){
						c1 = mp.get(array.get(j));
						c2 = mp.get(array.get(k));
					}
					
				}
			}
 		
 		
 		out.println((c1+1) + " " + (c2+1));
	 		
 		out.close();
 		
 		
 		
 	}
}

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