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.util.PriorityQueue;
import java.util.AbstractQueue;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.AbstractCollection;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author ijxjdjd
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Minimax solver = new Minimax();
        solver.solve(1, in, out);
        out.close();
    }

    static class Minimax {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int m = in.nextInt();
            HashSet<Pair> smallestId = new HashSet<>();
            int[] save = new int[N];
            int[][] arr = new int[N][m];
            PriorityQueue<Index> queue = new PriorityQueue<>(new Comparator<Index>() {

                public int compare(Index index, Index t1) {
                    return Integer.compare(t1.val, index.val);
                }
            });
            for (int i = 0; i < (1 << m); i++) {
                smallestId.add(new Pair(0, i));
            }
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < m; j++) {
                    arr[i][j] = in.nextInt();
                    queue.add(new Index(i, j, arr[i][j]));
                }
            }
            int mask = (1 << (m)) - 1;
            int a = -1;
            int b = -1;
            ans:
            while (!queue.isEmpty()) {
                Index next = queue.remove();
                smallestId.remove(new Pair(save[next.r], -1));
                save[next.r] += (1 << (next.c));
                smallestId.add(new Pair(save[next.r], next.r));
                for (Pair msk : smallestId) {
                    if ((msk.mask | save[next.r]) == mask) {
                        a = next.r + 1;
                        b = msk.val + 1;
                        break ans;
                    }
                }
            }
            out.println(a + " " + b);
        }

        class Index {
            int r;
            int c;
            int val;

            Index(int r, int c, int val) {
                this.r = r;
                this.c = c;
                this.val = val;
            }

        }

        class Pair {
            int mask;
            int val;

            Pair(int msk, int i) {
                this.mask = msk;
                this.val = i;
            }

            public int hashCode() {
                return mask;
            }

            public boolean equals(Object o) {
                return ((Pair) (o)).mask == mask;
            }

        }

    }

    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());
        }

    }
}