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.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

import java.util.*;

public class Main {

    static class Pair{
        public int x;
        public int y;
        public Pair(int x,int y) {
            this.x=x;
            this.y=y;
        }
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof Pair) {
                Pair other = (Pair) obj;
                return other.x==this.x && other.y==this.y;
            }
            return false;
        }
        @Override
        public int hashCode() {
            return Objects.hash(this.x,this.y);
        }
    }

    static int n;
    static int m;
    static int[][] a;
    static int ans_1;
    static int ans_2;

    public static boolean isOK(int mid) {
        boolean flag = false;
        int tmp_1 = 0;
        int tmp_2 = 0;
        HashSet<Pair> set = new HashSet<Pair>();
        int[] arr = new int[(1<<m)];
        Arrays.fill(arr, -1);
        loop:for (int i=0;i<n;i++) {
            int tmp = 0;
            for (int j=0;j<m;j++) {
                if (a[i][j]>=mid) {
                    tmp += (1<<j);
                }
            }
            Pair pair = new Pair(i, tmp);
            set.add(pair);
            arr[tmp] = i;
            // ArrayList<Pair> list = new ArrayList<Pair>(set);
            // for (Pair val : list) {
            // for (Pair val : set) {
            //     if ((tmp|val.y)==((1<<m)-1)) {
            //         flag = true;
            //         // ans_1 = i;
            //         // ans_2 = val.x;
            //         tmp_1 = i;
            //         tmp_2 = val.x;
            //         break loop;
            //     }
            // }
        }

        for (int i=0;i<(1<<m);i++) {
            for (int j=0;j<(1<<m);j++) {
                if (arr[i]!=-1 && arr[j]!=-1 && (i|j)==((1<<m)-1)) {
                    flag = true;
                    tmp_1 = arr[i];
                    tmp_2 = arr[j];
                }
            }
        }

        if (flag) {
            ans_1 = tmp_1;
            ans_2 = tmp_2;
            return true;
        }
        else return false;
    }

    public static int binary_search() {
        int left = 2_000_000_000;
        int right = 0;

        while (Math.abs(right - left) > 1) {
            int mid = left + (right - left) / 2;

            if (isOK(mid)) right = mid;
            else left = mid;
        }
        return right;
    }

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        n = in.nextInt();
        m = in.nextInt();
        a = new int[n][m];
        for (int i=0;i<n;i++) {
            for (int j=0;j<m;j++) {
                a[i][j] = in.nextInt();
            }
        }

        binary_search();
        out.println((ans_1+1)+" "+(ans_2+1));
        out.close();
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

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

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

    }
}