#include <iostream>
#include<string>
#include<cmath>
#include<map>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<set>
#include<cstdio>
#include<stack>
#include<ctime>
#include<queue>
#include<deque>
#include<bitset>
#include<random>
#include<fstream>
#include<unordered_map>
#include<unordered_set>
using namespace std;
using ll = long long;
using ld = double;
using ull = unsigned long long;
using uint = unsigned int;
using dbl = double;

# define all(x) x.begin(), x.end()
# define rall(x) x.rbegin(), x.rend()

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
//#pragma comment(linker, "/STACK:1000000000")

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}
ll bpow(ll a, ll n) {
    return n == 0 ? 1 : n % 2 ? bpow(a, n - 1) * a : bpow(a * a, n / 2);
}
ll bpowm(ll a, ll n, ll m) {
    return n == 0 ? 1 : n % 2 ? bpowm(a, n - 1, m) * a % m : bpowm(a * a % m, n / 2, m);
}
mt19937 mt(52);
const int N = 500 + 5, inf = 2e9 + 100, mod2 = 1e9 + 7, mod = 998244353, P = 503077;
const ll llinf = 1e18 + 100;

int n, m;
ll b[N][N], a[N][N];

ll value(int i, int j);
/*ll value(int i, int j) {
    return b[i][j];
}*/

ll get(int i, int j) {
    if (a[i][j] == -1) a[i][j] = value(i, j);
    return a[i][j];
}

pair<int, int> rec(int lx, int rx, int ly, int ry, int mnx, int mny) {
    if (lx + 1 == rx || ly + 1 == ry) return {mnx, mny};
    ll mn = get(mnx, mny);
    if (rx - lx > ry - ly) {
        int x = (lx + rx) / 2, mnx2 = -1, mny2 = -1;
        ll mn2 = llinf;
        for (int i = ly + 1; i < ry; ++i) {
            if (get(x, i) < mn2) {
                mn2 = get(x, i);
                mnx2 = x;
                mny2 = i;
            }
        }
        if (mn2 >= mn) {
            if (mnx < x) {
                return rec(lx, x, ly, ry, mnx, mny);
            }
            else {
                return rec(x, rx, ly, ry, mnx, mny);
            }
        }
        else {
            if (get(mnx2 - 1, mny2) < mn2) {
                return rec(lx, x, ly, ry, mnx2, mny2);
            }
            else {
                return rec(x, rx, ly, ry, mnx2, mny2);
            }
        }
    }
    else {
        int y = (ly + ry) / 2, mnx2 = -1, mny2 = -1;
        ll mn2 = llinf;
        for (int i = lx + 1; i < rx; ++i) {
            if (get(i, y) < mn2) {
                mn2 = get(i, y);
                mnx2 = i;
                mny2 = y;
            }
        }
        if (mn2 >= mn) {
            if (mny < y) {
                return rec(lx, rx, ly, y, mnx, mny);
            }
            else {
                return rec(lx, rx, y, ry, mnx, mny);
            }
        }
        else {
            if (get(mnx2, mny2 - 1) < mn2) {
                return rec(lx, rx, ly, y, mnx2, mny2);
            }
            else {
                return rec(lx, rx, y, ry, mnx2, mny2);
            }
        }
    }
}

pair<int, int> find_locmin_point(int _n, int _m) {
    n = _n;
    m = _m;
    for (int i = 0; i <= n + 1; ++i) {
        fill(a[i], a[i] + m + 2, -1);
        a[i][0] = llinf;
        a[i][m + 1] = llinf;
        if (i == 0 || i == n + 1) {
            fill(a[i], a[i] + m + 2, llinf);
        }
    }
    return rec(0, n + 1, 0, m + 1, 0, 1);
}


void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> b[i][j];
        }
    }
    pair<int, int> p = find_locmin_point(n, m);
    cout << p.first << ' ' << p.second;
}

/*signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    //freopen("prediction.in", "r", stdin);
    //freopen("prediction.out", "w", stdout);

    //ld time1 = clock();

    int tt = 1;
    cin >> tt;
    while (tt--) {
        solve();
        cout << '\n';
        cout.flush();
    }

    //ld time2 = clock();
    //cerr << "\n\nTIME: " << (time2 - time1) / CLOCKS_PER_SEC;
    return 0;
}*/
