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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;


public class Cf1288D {

    
     public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer(br.readLine());
        int N=Integer.parseInt(st.nextToken());
        int M=Integer.parseInt(st.nextToken());
        int[][] arr=new int[N][M];
         for (int i = 0; i < N; i++) {
              st=new StringTokenizer(br.readLine());
              for (int j = 0; j < M; j++) {
                 arr[i][j]=Integer.parseInt(st.nextToken());
             }
         }
        int l=0; int r=1000000000;
        HashMap<Integer, Integer> hmpi = new HashMap<>();
        HashMap<Integer, Integer> hmpj = new HashMap<>();
        int num=0;
        while(l<r){
            int mid=(l+r+1)/2;
            String[] str=new String[N];
            int[] map=new int[1<<M];
            boolean[] b=new boolean[1<<M];
            
            for (int i = 0; i < N; i++) {
                num=0;
                for (int j = 0; j < M; j++) {
                    if(arr[i][j]>=mid){
                        num+=(1<<(M-j-1));
                    }
                }
                
                b[num]=true;
                map[num]=i;
            }
            aa:
            for (int i = 0; i < (1<<M); i++) {
                for (int j = i; j < (1<<M); j++) {
                    if(b[i] && b[j] && (i | j)==((1<<M)-1)){
                        if(l==r-1){
                            System.out.println((map[i]+1)+" "+(map[j]+1)); return;
                        }
                        l=mid;
                        hmpi.put(mid, map[i]+1);
                        hmpj.put(mid, map[j]+1);
                        //System.out.println(i+" "+j+" "+(map[i]+1)+" "+(map[j]+1)+" "+l+" "+r);
                        break aa;
                    }
                }
            }
            if(l<mid){//Fail, mid don't need consideration
                r=mid-1;
                if(l==r){
                    if(hmpi.get(l)==null){
                        System.out.println("1 1");
                    }else{
                        System.out.println(hmpi.get(l)+" "+hmpj.get(l));
                    }
                }
            }
            
        }
        
    }
    
}