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

public class Main
{
    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                solve();
            }
        }, "1", 1 << 26).start();
    }
    static void solve () {
        FastReader fr =new FastReader();    PrintWriter op =new PrintWriter(System.out);
        
        int n =fr.nextInt() ,m =fr.nextInt() ,gd[][] =new int[n][m] ,i ,j ,k ,l ,o ,p ,ans[] =new int[2] ;
        HashMap<Integer,Integer> bt =new HashMap<>() ;
        for (i =0 ; i<n ; ++i) {
            for (j =0 ; j<m ; ++j)  gd[i][j] =fr.nextInt() ;
        }
        i =0 ;  j =(int)1e9 ;
        while (i<=j) {
            k =(i+j)/2 ;    bt.clear() ;
            for (l =0 ; l<n ; ++l) {
                o =0 ;
                for (p =0 ; p<m ; ++p) {
                    if (gd[l][p] >= k)  o += (1<<p) ;
                }
                bt.put (o,l) ;
            }
            o =0 ;
ot:         for (int key : bt.keySet()) {
                for (int key_ : bt.keySet()) {
                    o =key|key_ ;   
                    if (o == (1<<m)-1) {
                        ans[0] =bt.get(key)+1 ;   ans[1] =bt.get(key_)+1 ;    break ot ;
                    }
                }
            }
            if (o == (1<<m)-1)    i =k+1 ;
            else    j =k-1 ;
        }
        op.println(ans[0]+" "+ans[1]) ;     op.flush();    op.close();
    }
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br =new BufferedReader(new InputStreamReader(System.in));
        }

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

        String nextLine() {
            String str ="";

            try
            {
                str =br.readLine();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }

            return str;
        }

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

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