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:
//package main;
import java.io.*;
import java.util.*;
import java.lang.*;
import java.math.*;
public class Submission {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter (System.out);
        //BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
        StringTokenizer st = new StringTokenizer(reader.readLine()," ");
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int[][] thing = new int[n][m];
        HashMap<Integer,Set<Integer>> adders = new HashMap<>();
        for (int i=0;i<(int)Math.pow(2, m);i++) {
        	adders.put(i,new HashSet<>());
        	String s = Integer.toBinaryString(i+(int)Math.pow(2, m));
        	for (int j=0;j<(int)Math.pow(2, m);j++) {
        		int fail=0;
            	String t = Integer.toBinaryString(j+(int)Math.pow(2, m));
        		for (int k=1;k<m+1;k++) {
        			if (s.charAt(k)=='0'&&t.charAt(k)=='0') {
        				fail++;
        				break;
        			}
        		}
        		if (fail==0) adders.get(i).add(j);
        	}
        }
        for (int i=0;i<n;i++) {
        	st = new StringTokenizer(reader.readLine()," ");
        	for (int j=0;j<m;j++) thing[i][j]=Integer.parseInt(st.nextToken());
        }
        int answer = 0;
        int ans1=0;
        int ans2=0;
        for (int i=29;i>=0;i--) {
        	int test = answer+(int)Math.pow(2, i);
        	int[] win = new int[(int)Math.pow(2,m)];
        	for (int j=0;j<(int)Math.pow(2,m);j++) win[j]=-1;
        	for (int j=0;j<n;j++) {
        		int newThing=0;
        		for (int k=0;k<m;k++) {
        			if (thing[j][k]>=test) newThing+=(int)Math.pow(2,k);
        		}
        		//out.println((j+1)+" "+newThing+" "+test);
        		win[newThing]=j;
        	}
        	int winner=0;
        	for (int j=0;j<(int)Math.pow(2,m);j++) {
        		if (win[j]>=0) {
        			for (int k : adders.get(j)) {
        				if (win[k]>=0) {
        					ans1=win[j];
        					ans2=win[k];
        					winner++;
        					break;
        				}
        			}
        			if (winner>0) break;
        		}
        	}
        	if (winner>0) answer=test;
        }
        out.println((ans1+1)+" "+(ans2+1));
        reader.close();
        out.close();
    }
}