#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include<iostream>
#define ss second
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define ff first
#define en end
#define be begin
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define ve vector
using namespace __gnu_pbds;
using namespace std;
#define ordered_set tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
long long value(int r,int c);
std::pair<int,int> find_locmin_point(int N,int M){
    int i=1,j=1;
    long long a[N+2][M+2];
    for (int i=0; i<N+2; i++){
        for (int j=0; j<M+2; j++){
            if (i==0) a[i][j]=1e18+2;
            else
            if (j==0) a[i][j]=1e18+2;
            else
            if (i==N+2) a[i][j]=1e18+2;
            else
            if (j==M+2) a[i][j]=1e18+2;
            else a[i][j]=0;
        }
    }
    a[i][j]=value(i,j);
    while (1){
        ve<pair<int,pair<int,int>>>v;
        v.pb({M+1-j,{0,+1}});
        v.pb({j-1,{0,-1}});
        v.pb({N+1-i,{+1,0}});
        v.pb({i-1,{-1,0}});
        sort(v.be(),v.en());
        for (int g=0; g<5; g++){
            if (g==4) return {i,j};
            //cout<<i<<" "<<j<<endl;
            int tx=i+v[g].ss.ff,ty=j+v[g].ss.ss;
            if (a[tx][ty]==0){
                a[tx][ty]=value(tx,ty);
            }
            //cout<<a[tx][ty]<<" "<<a[i][j]<<endl;
            if (a[tx][ty]<a[i][j]) {
                i=tx;
                j=ty;
                break;
            }
      // cout<<i<<" "<<j<<endl;
        }

    }
}
static const int MAXN=500,MAXM=500;
static long long int tab[MAXN][MAXM];
static int n,m;
static void finish (string message) {
    cout << message << endl ;
    exit(0);
}

static int cnt=0;
long long  value (int row, int col) {
    row--; col--;
    if ((row<0)||(row>=n)||(col<0)||(col>=m)) finish("Invalid row or column number in question ("+to_string(row)+","+to_string(col)+")!");
    cnt++;
    if (cnt>n*m) finish("Too many questions!");
   // cout<<tab[row][col]<<" "<<row<<" "<<col<<endl;
    return tab[row][col];
}
extern pair <int, int> find_locmin_point (int, int);

static int drow[]={ -1, -0, +0, +1 };
static int dcol[]={ -0, -1, +1, +0 };
static bool check_saddle (int row, int col) {
    for (int i=0; i<4; i++) {
        int r=row+drow[i],c=col+dcol[i];
        if ((r<0)||(r>=n)||(c<0)||(c>=m)) continue;
        if (tab[r][c]<=tab[row][col]) return false;
    }
    return true;
}
int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m ;
    for (int i=0; i<n; i++) {
        for (int j=0; j<m; j++) {
            cin >> tab[i][j] ;
        }
    }
    auto [r, c]=find_locmin_point(n,m);
    cout<<r<<" "<<c<<endl;
    cout << "Answer cell: (" << r << "," << c << ")\n";
    cout << "Number of value calls: " << cnt << endl ;
    r--; c--;
    if ((r<0)||(r>=n)||(c<0)||(c>=m)) finish("Invalid row or column in answer!");
    if (check_saddle(r,c)==false) finish("Answer is not a local minimum point!");
    finish("Correctly found local minimum point.");
    return 0;
}
