#include #include using namespace std; // #include // using namespace boost::multiprecision; using lnt = long long; using Real = long double; #define ALL(obj) (obj).begin(),(obj).end() #define RALL(obj) (obj).rbegin(),(obj).rend() #define REP(i, n) for(lnt i=0;i<(n);++i) #define RANGE(i, a, b) for(lnt i=(a);i<(b);++i) #define RREP(i, n) for(lnt i=(n)-1;i>= 0;--i) #define ln '\n' #define pb push_back #define eb emplace_back #define pque priority_queue #define umap unordered_map #define uset unordered_set #define dcout cout< inline T GCD(T a,T b){T c;while(b!=0){c=a%b;a=b;b=c;}return a;} template inline T LCM(T a,T b){T c=GCD(a,b);a/=c;return a*b;} template inline T nCr(T a,T b){T i,r=1;for(i=1;i<=b;i++){r*=(a+1-i);r/=i;}return r;} template inline T nHr(T a,T b){return nCr(a+b-1,b);} template inline bool chmax(T& a,T b){if(a inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;} using pint = pair; using plnt = pair; using vint = vector; using vlnt = vector; constexpr lnt MOD = 1e9+7; int main(){ summon_tourist; int N, T; cin >> N >> T; vector A(N, vint(N)); REP(i, N) REP(j, N) cin >> A[i][j]; auto st = chrono::steady_clock::now(); const double LIMIT = 1.90; int bs = min(3, (int)sqrt(T)); int mi, mj; int mx = -1; REP(i, N-bs+1) REP(j, N-bs+1) { int sum = 0; RANGE(k, i, i+bs) RANGE(l, j, j+bs) sum += A[k][l]; if(chmax(mx, sum)) { mi = i; mj = j; } } const int dd[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); vector cand; REP(i, N) REP(j, N) cand.emplace_back(A[i][j], i * N + j); sort(RALL(cand)); int TOP = min(50, (int)cand.size()); vector best_path; long long best_total = -1; auto attempt = [&](int si, int sj){ vector path; vector> vis(N, vector(N, false)); path.emplace_back(si, sj); vis[si][sj] = true; for(int step = 1; step < T; ++step){ int ci = path.back().first, cj = path.back().second; vector> nxt; for(int d = 0; d < 4; ++d){ int ni = ci + dd[d][0], nj = cj + dd[d][1]; if(ni < 0 || ni >= N || nj < 0 || nj >= N) continue; if(vis[ni][nj]) continue; nxt.push_back({A[ni][nj], {ni, nj}}); } if(nxt.empty()) break; sort(RALL(nxt)); int pick = 0; if((int)nxt.size() >= 2 && (rng() & 1)) pick = 1; if((int)nxt.size() >= 3 && (rng() % 3 == 0)) pick = 2; auto [ni, nj] = nxt[pick].second; path.emplace_back(ni, nj); vis[ni][nj] = true; } long long total = 0; for(auto [i, j] : path) total += A[i][j]; if(chmax(best_total, total)) best_path = move(path); }; while(true){ auto now = chrono::steady_clock::now(); if(chrono::duration(now - st).count() > LIMIT) break; int idx = rng() % TOP; int id = cand[idx].second; attempt(id / N, id % N); if((rng() & 7) == 0){ int idx2 = rng() % TOP; int id2 = cand[idx2].second; attempt(id2 / N, id2 % N); } } cout << best_total << ln; cout << best_path.size() << ln; for(auto [i, j] : best_path) cout << i << ' ' << j << ln; }