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.*;
import java.math.BigInteger;
import java.util.*;

// written by luchy0120

public class Main {
    public static void main(String[] args) throws Exception {
        new Main().run();
    }


    int len;

    void add(int y, int v){
        for(int i=y;i<len;i+=i&(-i)){
            treea[i] += v;
        }
    }

    int equal_bigger(int v){
        int s=0,p=0;
        for(int i=Integer.numberOfTrailingZeros(Integer.highestOneBit(len));i>=0;--i) {
            if(p+(1<<i)< len && s + treea[p+(1<<i)] <v){
                v -= treea[p+(1<<i)];
                p |= 1<<i;
            }
        }
        return p+1;
    }



    void add1(int x, int v){
        for(int i=x;i<treea.length;i+=i&(-i)){
            treea[i] += v;
        }
    }

    int equal_bigger1(int v){
        int s=0,p=0;
        for(int i=Integer.numberOfTrailingZeros(Integer.highestOneBit(treea.length));i>=0;--i) {
            if(p+(1<<i)< treea.length && s + treea[p+(1<<i)] <v){
                v -= treea[p+(1<<i)];
                p |= 1<<i;
            }
        }
        return p+1;
    }

    int treea[];
    void init(int l) {
        for (int j = 1; j < l; ++j) {
            treea[j] += 1;
            int nj  =j + (j&(-j));
            if(nj<l) {
                treea[nj] += treea[j];
            }
        }
    }

    void solve() {

       int n = ni();
       int m = ni();

       long a[][] = new long[n][m];

       for(int i=0;i<n;++i){
           for(int j=0;j<m;++j){
               a[i][j] = nl();
           }
       }
       long dp[] = new long[1<<m];
       Arrays.fill(dp,-1);
       int s[] = new int[1<<m];
       for(int st=0;st<1<<m;++st){
           for(int i=0;i<n;++i){
               long r = 1000000000000L;
               for(int j=0;j<m;++j){
                   if(st<<~j<0){
                       r = Math.min(r, a[i][j]);
                   }
               }
               if(dp[st]<r){
                   dp[st] = r;
                   s[st] = i+1;
               }
           }
       }
       long all = -1;
       int f = -1;
       int se = -1;
        for(int st=0;st<1<<m;++st){
            int o = (1<<m)-1;
            o -= st;

            if(dp[o]==-1||dp[st]==-1) continue;

            long tp = Math.min(dp[o],dp[st]);
            if(tp > all){
                all = tp;
                f = s[o];
                se = s[st];
            }
        }
        println(f+" "+se);


//        int n = ni();
//        int m = ni();
//        int q = ni();
//
//
//        int id = 0;
//        int qs[][] = new int[q][3];
//        for(int i=0;i<q;++i){
//            qs[i][0] = ni();
//            qs[i][1] = i;
//            qs[i][2] = ni();
//        }
//        Arrays.sort(qs, new Comparator<int[]>() {
//            @Override
//            public int compare(int[] aa, int[] bb) {
//                if(aa[0]!=bb[0]){
//                    return aa[0]-bb[0];
//                }
//                return aa[1] - bb[1];
//            }
//        });
//
//        int qry[] = new int[q];
//
//        len = m+q;
//
//        for(int i=0;i<q;++i){
//            if(i==0||qs[i][0]!=qs[i-1][0]){
//                treea = new int[len];
//                init(len);
//            }
//            int yy = qs[i][2];
//            if(yy==m) continue;
//            if(yy<=m-1) {
//                int pos = equal_bigger(yy);
//                qry[qs[i][1]] = pos;
//                add(pos, -1);
//            }
//        }
//        len = n+q+1;
//        treea = new int[len];
//        for(int j=1;j<len;++j){
//            //add1(j,1);
//            treea[j] += 1;
//            int nj = j + (j&(-j));
//            if(nj<len) {
//                treea[nj] += treea[j];
//            }
//        }
//        List<Long> li[] = new List[n+1];
//
//        for(int i=1;i<=n;++i){
//            li[i] = new ArrayList<>();
//        }
//
//        List<Long> li1 = new ArrayList<>();
//
//        Arrays.sort(qs, new Comparator<int[]>() {
//            @Override
//            public int compare(int[] aa, int[] bb) {
//                return aa[1] - bb[1];
//            }
//        });
//
//
//        for(int i=0;i<q;++i){
//            int xx = qs[i][0];
//            int yy = qs[i][2];
//
//            if(yy<=m-1) {
//                int pos = qry[i];
//                if (pos <= m - 1) {
//                    long ans = (xx - 1) * (long)m + pos;
//                    println(ans);
//                    li1.add(ans);
//                } else {
//                    long ans = li[xx].get(pos-m);
//                    println(ans);
//                    li1.add(ans);
//                }
//                pos = equal_bigger1(xx);
//                if (pos <= n) {
//                    long ans = pos * (long)m;
//                    li[xx].add(ans);
//                    add1(pos, -1);
//                } else {
//                    long ans = li1.get(pos - (n + 1));
//                    li[xx].add(ans);
//                    add1(pos, -1);
//                }
//            }else{
//                int pos = equal_bigger1(xx);
//                add1(pos, -1);
//                long ans = 0;
//                if (pos <= n) {
//                    ans = (pos) * (long)m;
//                }else{
//                    ans = li1.get(pos - (n + 1));
//                }
//                println(ans);
//                li1.add(ans);
//            }
//
//        }











    }





    public static String roundS(double result, int scale){
        String fmt = String.format("%%.%df", scale);
        return String.format(fmt, result);
    }








//    void solve() {
//
//        for(int i=0;i<9;++i) {
//            for (int j = 0; j < 9; ++j) {
//                int v = ni();
//                a[i][j] = v;
//                if(v>0) {
//                    vis_row[i][v] = true;
//                    vis_col[j][v] = true;
//                    vis_room[get_room(i, j)][v] = true;
//                }else{
//                    space++;
//                }
//            }
//        }
//
//
//        prepare = new int[space][2];
//
//        int p = 0;
//
//        for(int i=0;i<9;++i) {
//            for (int j = 0; j < 9; ++j) {
//                if(a[i][j]==0){
//                    prepare[p][0] = i;
//                    prepare[p][1]= j;p++;
//                    List<Integer> temp =new ArrayList<>();
//                    for(int k=1;k<=9;++k){
//                        if(!vis_col[j][k]&&!vis_row[i][k]&&!vis_room[get_room(i,j)][k]){
//                            temp.add(k);
//                        }
//                    }
//                    int sz = temp.size();
//                    val[i][j] = new int[sz];
//                    for(int k=0;k<sz;++k){
//                        val[i][j][k] = temp.get(k);
//                    }
//                }
//            }
//        }
//        Arrays.sort(prepare,(x,y)->{
//           return Integer.compare(val[x[0]][x[1]].length,val[y[0]][y[1]].length);
//        });
//        dfs(0);
//
//
//
//
//
//
//
//
//
//
//    }




    InputStream is;
    PrintWriter out;

    void run() throws Exception {
        is = System.in;
        out = new PrintWriter(System.out);
        solve();
        out.flush();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private char ncc() {
        int b = readByte();
        return (char) b;
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private String nline() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!isSpaceChar(b) || b == ' ') {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[][] nm(int n, int m) {
        char[][] a = new char[n][];
        for (int i = 0; i < n; i++) a[i] = ns(m);
        return a;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private long[] nal(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++) a[i] = nl();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
        }
        ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') num = (num << 3) + (num << 1) + (b - '0');
            else return minus ? -num : num;
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
        }
        ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') num = num * 10 + (b - '0');
            else return minus ? -num : num;
            b = readByte();
        }
    }

    void print(Object obj) {
        out.print(obj);
    }

    void println(Object obj) {
        out.println(obj);
    }

    void println() {
        out.println();
    }

    void printArray(int a[],int from){
        int l = a.length;
        for(int i=from;i<l;++i){
            print(a[i]);
            if(i!=l-1){
                print(" ");
            }
        }
        println();
    }

    void printArray(long a[],int from){
        int l = a.length;
        for(int i=from;i<l;++i){
            print(a[i]);
            if(i!=l-1){
                print(" ");
            }
        }
        println();
    }
}