#include using namespace std; #define pb push_back const int maxim = 1e6 + 1000; const int maxN = 1010; mt19937 rng(time(0)); int a[maxN][maxN]; int n, m, k; int h[maxim]; vector> ans, currentAns, currentAns1; map mp; int ob[maxN][maxN]; int bit[maxim]; long long bestAns = 0; int dx[4] = {1, -1, 0, 0}; int dy[4]= {0, 0, -1, 1}; int maxi; int neg[maxN][maxN]; int firstTime; pair pr[maxN][maxN]; int furX, furY; int maxLen; clock_t begin_t; bool inside(int x, int y) { return (x>=1 && x<=n && y>=1 && y<=m); } int isShitty(int xi, int yi) { return neg[xi][yi]; } int get(int poz) { int ans = 0; for (int i = poz; i>0; i-=i&(-i)) ans=max(bit[i], ans); return ans; } void update(int poz, int val) { for (int i = poz; i< n*m; i+=i&(-i)) bit[i]= max(bit[i], val); } void reset() { for (int i = 1; i> ¤tAns) { long long ans = 1; int t = 2; while(t--) { int cur = 0; for (auto i: currentAns) h[++cur] = a[i.first][i.second]; ans*=calc_lis(h, currentAns.size()); for (int i=1; i> ¤tAns) { ans.clear(); for (auto i:currentAns) ans.pb(i); } void remove_nei(int x, int y) { for (int w = 0; w < 4; w++) if (inside(x+dx[w], y + dy[w]) && !ob[x+dx[w]][y+dy[w]]) neg[x + dx[w]][y + dy[w]]--; } void greedy_dfs(int xi, int yi, int type,vector> ¤tAns) { int steps = k - 1; currentAns.pb({xi,yi}); ob[xi][yi] = 1; if (!firstTime) remove_nei(xi, yi); while(steps--) { int value = 0; int pozX = 0; int pozY = 0; for (int i=0; i<4; i++) if (inside(xi+dx[i], yi+dy[i]) && !ob[xi+dx[i]][yi+dy[i]] && !isShitty(xi+dx[i], yi+dy[i])) { if (type && (!value || (a[xi+dx[i]][yi + dy[i]]>a[xi][yi] && value>a[xi+dx[i]][yi + dy[i]]))) { pozX = xi + dx[i]; pozY = yi + dy[i]; value = a[xi+dx[i]][yi + dy[i]]; } else if (!type && (!value || (a[xi+dx[i]][yi + dy[i]]a[xi][yi] && value>a[xi+dx[i]][yi + dy[i]]))) { pozX = xi + dx[i]; pozY = yi + dy[i]; value = a[xi+dx[i]][yi + dy[i]]; } else if (!type && (!value || (a[xi+dx[i]][yi + dy[i]]> resV; resV.clear(); for (int i = currentAns1.size()-1 ; i>=0; i--) resV.pb(currentAns1[i]); for (int i = 1 ; i bestAns) { bestAns = value; change_res(resV); } } } void dfs(int x, int y, int prX, int prY, int len) { ob[x][y] = 1; pr[x][y] = {prX,prY}; remove_nei(x,y); len++; if (len>maxLen) { maxLen = len; furX = x; furY = y; } for (int i=1;i<=5;i++) { int fr = rng()%4; int sc = rng()%4; swap(dx[fr], dx[sc]); swap(dy[fr], dy[sc]); } for (int i=0; i<4; i++) if (inside(x+dx[i], y+dy[i]) && !ob[x+dx[i]][y+dy[i]] && !isShitty(x+dx[i], y+dy[i])) dfs(x + dx[i], y + dy[i], x, y, len); for (int i=0; i<4; i++) if (inside(x+dx[i], y+dy[i]) && !ob[x+dx[i]][y+dy[i]]) dfs(x + dx[i], y + dy[i], x, y, len); } void solve2() //just long path { while(clock()- begin_t<= CLOCKS_PER_SEC *4.4) { reset(); int xi = 0; int yi = 0; maxLen = 0; while(!a[xi][yi]) { xi = rng()%n + 1; yi = rng()%m + 1; } dfs(xi,yi, -1,-1, 0); int steps = 0; while(pr[furX][furY].first!=-1 && steps bestAns) { bestAns = value; change_res(currentAns); } } } void solve() { solve1(); solve2(); } int main() { read_data(); compress_data(); solve(); print_data(); return 0; }