Problem:
問題 I
山
問題文
L 氏はある都市の市長である．L 氏の市長としての手腕はすさまじく時を止め一瞬にして都市中に鉄道網を引いたり，財政の赤字を一夜にして莫大な黒字にしたり，はては巨大な怪獣をどこからともなく呼んでパフォーマンスに使うこともした．
そんな L 氏は土地の隣り合った行または列同士を何度も入れ替えることででこぼこな土地を山形にするという遊びを最近発明した．土地は
H×W
個のブロックに区切られており，ブロック
(y,x)
では海面からの高さが
h
y,x
であると測定されている．入れ替え後のブロック
(y,x)
の高さを
h'
y,x
と書くことにする．この土地が山形であるとは，以下の図のように，あるブロック
(y^*,x^*)
があって，そこを山頂として山頂から離れるに従って高さが単調減少しているものをいう．
h'
y^*-1, x^*-2
<
h'
y^*-1, x^*-1
<
h'
y^*-1, x^*
>
h'
y^*-1, x^*+1
>
h'
y^*-1, x^*+2
∧
∧
∧
∧
∧
h'
y^*, x^*-2
<
h'
y^*, x^*-1
<
h'
y^*, x^*
>
h'
y^*, x^*+1
>
h'
y^*, x^*+2
∨
∨
∨
∨
∨
h'
y^*+1, x^*-2
<
h'
y^*+1, x^*-1
<
h'
y^*+1, x^*
>
h'
y^*+1, x^*+1
>
h'
y^*+1, x^*+2
ところで，L 氏はいくらがんばっても山形にできないような土地が存在する気がした．そこで，前もってコンピュータにその土地が山形にできるかどうかをチェックさせることにした．
入力形式
最初の行に
H
と
W
がスペース区切りで与えられる．
次の
H
行に土地の高さが与えられる．
各行は
W
個の数値からなり，それぞれ対応する場所の高さを表す．
出力形式
土地を山形にできるなら
"YES"
，できないなら
"NO"
を出力せよ．
制約
1 ≤ H,W ≤ 1,000
0 ≤ h
y,x
≤ 10
8
全ての
h
y,x
は相異なる．
入出力例
入力例 1
3 3
1 3 2
7 9 8
4 6 5
出力例 1
YES
入力例 2
以下の例では
2
番目の列と
3
番目の列を入れ替えることにより土地を山形にすることができる．
3 3
9 3 6
8 2 5
7 1 4
出力例 2
YES
入力例 3
1 1
100
出力例 3
YES
入力例 4
3 3
1 3 2
4 6 5
7 8 9
出力例 4
NO
謝辞
この問題は京都市の周りに山が多いことから作られた．よって京都市の周りの山に感謝の意を表する．

Submitted solutions:

code_snippet: // AOJ #2279
// Mountain 2025.2.13

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(bool yes) {
	if (yes) pc('Y'), pc('E'), pc('S');
    else     pc('N'), pc('O');
    pc('\n');
}
 
bool dfsColor(int v, int c, const vector<vector<int>> &g, vector<int>& col) {
    col[v] = c;
    for (int nv : g[v]) {
        if (col[nv] == -1) {
            if (!dfsColor(nv, c^1, g, col)) return false;
        } else if (col[nv] == c) return false;
    }
    return true;
}
 
int main(){
    int H = Cin(), W = Cin();
    vector<vector<int>> A(H, vector<int>(W));
    for (int i=0; i<H; i++){
        for (int j=0; j<W; j++) A[i][j] = Cin();
    }
 
    int candCol = -1;
    for (int i=0; i<H; i++){
        int maxVal = -1, maxIdx = -1;
        for (int j=0; j<W; j++){
            if (A[i][j] > maxVal){
                maxVal = A[i][j];
                maxIdx = j;
            }
        }
        if(i==0) candCol = maxIdx;
        else if(maxIdx != candCol){
            Cout(0);
            return 0;
        }
    }
 
    int candRow = -1;
    for (int j=0; j<W; j++){
        int maxVal = -1, maxIdx = -1;
        for (int i=0; i<H; i++){
            if (A[i][j] > maxVal){
                maxVal = A[i][j];
                maxIdx = i;
            }
        }
        if(j==0) candRow = maxIdx;
        else if(maxIdx != candRow){
            Cout(0);;
            return 0;
        }
    }
 
    for (int i=0; i<H; i++){
        for (int j=0; j<W; j++){
            if(i==candRow && j==candCol) continue;
            if(A[i][j] > A[candRow][candCol]){
                Cout(0);
                return 0;
            }
        }
    }
 
    vector<int> rows;
    for (int i=0; i<H; i++){
        if(i==candRow) continue;
        rows.push_back(i);
    }
    vector<int> cols;
    for (int j=0; j<W; j++){
        if(j==candCol) continue;
        cols.push_back(j);
    }
 
    int rn = rows.size();
    vector<vector<int>> graphRows(rn);
    for (int a = 0; a < rn; a++){
        for (int b = a+1; b < rn; b++){
            int i = rows[a], k = rows[b];
            int sign = 0;
            bool comparable = true;
            for (int c : cols){
                int s = (A[i][c] < A[k][c]) ? 1 : -1;
                if(sign==0) sign = s;
                else {
                    if(s != sign) { comparable = false; break; }
                }
            }
            if(!comparable){
                graphRows[a].push_back(b);
                graphRows[b].push_back(a);
            }
        }
    }
    vector<int> color(rn, -1);
    for (int i=0; i<rn; i++){
        if(color[i] == -1){
            if(!dfsColor(i, 0, graphRows, color)){
                Cout(0);
                return 0;
            }
        }
    }
 
    int cn = cols.size();
    vector<vector<int>> graphCols(cn);
    for (int a = 0; a < cn; a++){
        for (int b = a+1; b < cn; b++){
            int j = cols[a], k = cols[b];
            int sign = 0;
            bool comparable = true;
            for (int i = 0; i < H; i++){
                if(i==candRow) continue;
                int s = (A[i][j] < A[i][k]) ? 1 : -1;
                if(sign==0) { sign = s; }
                else {
                    if(s != sign){ comparable = false; break; }
                }
            }
            if(!comparable){
                graphCols[a].push_back(b);
                graphCols[b].push_back(a);
            }
        }
    }
    vector<int> colorCols(cn, -1);
    for (int i=0; i<cn; i++){
        if(colorCols[i]==-1){
            if(!dfsColor(i, 0, graphCols, colorCols)){
                Cout(0);
                return 0;
            }
        }
    }
    Cout(1);
    return 0;
}
accuracy: 1
time_ms: 1110
memory_kb: 8924
final_rank: 11

code_snippet: // AOJ #2279
// Mountain 2025.2.13

#include <bits/stdc++.h>
using namespace std;
 
bool dfsColor(int v, int c, const vector<vector<int>> &g, vector<int>& col) {
    col[v] = c;
    for (int nv : g[v]) {
        if (col[nv] == -1) {
            if (!dfsColor(nv, c^1, g, col)) return false;
        } else if (col[nv] == c) return false;
    }
    return true;
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int H, W;
    cin >> H >> W;
    vector<vector<int>> A(H, vector<int>(W));
    for (int i=0; i<H; i++){
        for (int j=0; j<W; j++) cin >> A[i][j];
    }
 
    int candCol = -1;
    for (int i=0; i<H; i++){
        int maxVal = -1, maxIdx = -1;
        for (int j=0; j<W; j++){
            if (A[i][j] > maxVal){
                maxVal = A[i][j];
                maxIdx = j;
            }
        }
        if(i==0) candCol = maxIdx;
        else if(maxIdx != candCol){
            cout << "NO\n";
            return 0;
        }
    }
 
    int candRow = -1;
    for (int j=0; j<W; j++){
        int maxVal = -1, maxIdx = -1;
        for (int i=0; i<H; i++){
            if (A[i][j] > maxVal){
                maxVal = A[i][j];
                maxIdx = i;
            }
        }
        if(j==0) candRow = maxIdx;
        else if(maxIdx != candRow){
            cout << "NO\n";
            return 0;
        }
    }
 
    for (int i=0; i<H; i++){
        for (int j=0; j<W; j++){
            if(i==candRow && j==candCol) continue;
            if(A[i][j] > A[candRow][candCol]){
                cout << "NO\n";
                return 0;
            }
        }
    }
 
    vector<int> rows;
    for (int i=0; i<H; i++){
        if(i==candRow) continue;
        rows.push_back(i);
    }
    vector<int> cols;
    for (int j=0; j<W; j++){
        if(j==candCol) continue;
        cols.push_back(j);
    }
 
    int rn = rows.size();
    vector<vector<int>> graphRows(rn);
    for (int a = 0; a < rn; a++){
        for (int b = a+1; b < rn; b++){
            int i = rows[a], k = rows[b];
            int sign = 0;
            bool comparable = true;
            for (int c : cols){
                int s = (A[i][c] < A[k][c]) ? 1 : -1;
                if(sign==0) sign = s;
                else {
                    if(s != sign) { comparable = false; break; }
                }
            }
            if(!comparable){
                graphRows[a].push_back(b);
                graphRows[b].push_back(a);
            }
        }
    }
    vector<int> color(rn, -1);
    for (int i=0; i<rn; i++){
        if(color[i] == -1){
            if(!dfsColor(i, 0, graphRows, color)){
                cout << "NO\n";
                return 0;
            }
        }
    }
 
    int cn = cols.size();
    vector<vector<int>> graphCols(cn);
    for (int a = 0; a < cn; a++){
        for (int b = a+1; b < cn; b++){
            int j = cols[a], k = cols[b];
            int sign = 0;
            bool comparable = true;
            for (int i = 0; i < H; i++){
                if(i==candRow) continue;
                int s = (A[i][j] < A[i][k]) ? 1 : -1;
                if(sign==0) { sign = s; }
                else {
                    if(s != sign){ comparable = false; break; }
                }
            }
            if(!comparable){
                graphCols[a].push_back(b);
                graphCols[b].push_back(a);
            }
        }
    }
    vector<int> colorCols(cn, -1);
    for (int i=0; i<cn; i++){
        if(colorCols[i]==-1){
            if(!dfsColor(i, 0, graphCols, colorCols)){
                cout << "NO\n";
                return 0;
            }
        }
    }
    cout << "YES\n";
    return 0;
}
accuracy: 1
time_ms: 1170
memory_kb: 8568
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
int h, w;
vector<int> g[4004];
int match[4004];
bool used[4004];
bool dfs(int v){
    used[v] = true;
    for(int i=0;i<g[v].size();i++){
        int u = g[v][i];
        int w = match[u];
        if(w<0 || !used[w]&&dfs(w)){
            match[v] = u;
            match[u] = v;
            return true;
        }
    }
    return false;
}
bool bm(){
    int res1 = 0;
    memset(match, -1, sizeof(match));
    for(int v=0;v<h;v++){
        if(match[v]<0){
            memset(used, 0, sizeof(used));
            if(dfs(v)) res1++;
        }
    }
    int res2 = 0;
    for(int v=h+h;v<h+h+w;v++){
        if(match[v]<0){
            memset(used, 0, sizeof(used));
            if(dfs(v)) res2++;
        }
    }
    return res1<=2&&res2<=2;
}
int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    int mo[1001][1001];
    cin >> h >> w;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++) cin >> mo[i][j];
    }
    int hsum[1001]={};
    for(int i=0;i<h;i++){
        for(int j=0;j<i;j++){
            int c1=0,c2=0;
            for(int k=0;k<w;k++){
                if(mo[j][k]>mo[i][k]) c1++;
                else if(mo[j][k]<mo[i][k]) c2++;
            }
            if(c1==w){
                g[j].push_back(i+h);
                hsum[i]++;
            }
            else if(c2==w){
                g[i].push_back(j+h);
                hsum[j]++;
            }
        }
    }
    int wsum[1001]={};
    for(int i=0;i<w;i++){
        for(int j=0;j<i;j++){
            int c1=0,c2=0;
            for(int k=0;k<h;k++){
                if(mo[k][j]>mo[k][i]) c1++;
                else if(mo[k][j]<mo[k][i]) c2++;
            }
            if(c1==w){
                g[j+h+h].push_back(i+h+h+w);
                wsum[i]++;
            }
            else if(c2==w){
                g[i+h+h].push_back(j+h+h+w);
                wsum[j]++;
            }
        }
    }
    bool ok=bm();
    int cnt=0;
    for(int i=0;i<h;i++){
        if(hsum[i]==0) cnt++;
    }
    if(cnt!=1) ok=false;
    cnt=0;
    for(int i=0;i<w;i++){
        if(wsum[i]==0) cnt++;
    }
    if(cnt!=1) ok=false;
    cout << (ok?"YES":"NO") << endl;
    return(0);
}
accuracy: 0.08108108108108109
time_ms: 90
memory_kb: 9784
final_rank: 20

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        for (int i = 0; i < H; ++i) {
            for (int j = 0; j < H; ++j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = 0; k < H; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 16436
final_rank: 9

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        for (int i = 0; i < H; ++i) {
            for (int j = 0; j < H; ++j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        connected[j][i] = false;
                        for (int k = 0; k < H; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 600
memory_kb: 16308
final_rank: 10

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = 0; i < H; ++i) {
            for (int j = i-1; j >= 0; --j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = 0; k < j; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 15020
final_rank: 1

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = 0; i < H; ++i) {
            for (int j = i-1; j >= 0; --j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = 0; k < j; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 15104
final_rank: 2

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = 0; i < H ; ++i) {
            for (int j = i-1; j >= 0; --j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = 0; k < H; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 15124
final_rank: 4

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = H-1; i >= 0 ; --i) {
            for (int j = 0; j < i; ++j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = 0; k < H; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 15080
final_rank: 8

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = 0; i < H ; ++i) {
            for (int j = 0; j < i; ++j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = 0; k < H; ++k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 15036
final_rank: 7

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = H-1; i >= 0 ; --i) {
            for (int j = i-1; j >= 0; --j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = j-1; k >= 0; --k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 15032
final_rank: 5

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = 0; i < H ; ++i) {
            for (int j = i-1; j >= 0; --j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = j-1; k >= 0; --k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 15108
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(__typeof__(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



const int MAX = 1010;

struct Graph {
    static const int MAX_V_ = ::MAX;
    int L;
    vector<int> list[MAX_V_];
    
    void init(int n = 0) {L = n; for (int i = 0; i < MAX_V_; ++i) list[i].clear();}
    inline vector<int>& operator [] (int i) {return list[i];}
    friend ostream& operator << (ostream& s, const Graph& G) {for (int i = 0; i < G.L; ++i) {s << i << " : " << G.list[i];}return s;}
    
    void addedge(int from, int to) {
        list[from].push_back(to);
    }
} G;

int L = 0;
bool seen[MAX];
bool matched[MAX];
int level[MAX];
int matching[MAX];

void hobfs(Graph &G) {
    queue<int> que;
    for (int left = 0; left < L; ++left) {
        level[left] = -1;
        if (!matched[left]) {
            que.push(left);
            level[left] = 0;
        }
    }
    level[L] = L;
    while (!que.empty()) {
        int left = que.front();
        que.pop();
        for (int i = 0; i < G[left].size(); ++i) {
            int right = G[left][i];
            int next = matching[right];
            if (level[next] == -1) {
                level[next] = level[left] + 1;
                que.push(next);
            }
        }
    }
}

bool hodfs(Graph &G, int left) {
    if (left == L) return true;
    if (seen[left]) return false;
    seen[left] = true;
    for (int i = 0; i < G[left].size(); ++i) {
        int right = G[left][i];
        int next = matching[right];
        if (level[next] > level[left] && hodfs(G, next)) {
            matching[right] = left;
            return true;
        }
    }
    return false;
}

int Hopcroft_Karp(Graph &G) {
    L = G.L;
    for (int i = 0; i < MAX; ++i) matching[i] = L;
    memset(matched, 0, sizeof(matched));
    
    int res = 0;
    while (true) {
        hobfs(G);
        memset(seen, 0, sizeof(seen));
        bool finished = true;
        for (int left = 0; left < L; ++left) {
            if (!matched[left] && hodfs(G, left)) {
                matched[left] = true;
                ++res;
                finished = false;
            }
        }
        if (finished) break;
    }
    return res;
}


int H, W;
vint h[MAX];
int temp[MAX][MAX];
bool connected[MAX][MAX];

bool solve() {
    bool res = true;
    
    int pMax = -1, Max = -1;
    for (int i = 0; i < H; ++i) if (Max < h[i][0]) {Max = h[i][0], pMax = i;}
    for (int i = 0; i < W; ++i) {
        int epMax = -1, eMax = -1;
        for (int j = 0; j < H; ++j) if (eMax < h[j][i]) {eMax = h[j][i], epMax = j;}
        if (epMax != pMax) {res = false; break;}
    }
    if (res) {
        sort(h, h + H);
        for (int i = 0; i < H ; ++i) {
            for (int j = 0; j < i; ++j) {
                if (!connected[i][j]) {
                    bool ok = true;
                    for (int k = 0; k < W; ++k) if (h[i][k] <= h[j][k]) {ok = false; break;}
                    if (ok) {
                        connected[i][j] = true;
                        for (int k = j-1; k >= 0; --k) connected[i][k] |= connected[j][k];
                    }
                }
            }
        }
        G.init(H);
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < H; ++j) {
                if (i == j) continue;
                if (connected[i][j]) G.addedge(i,j);
            }
        
        int ans = Hopcroft_Karp(G);
        if (H - ans > 2) res = false;
    }

    return res;
}

int main() {  
    cin >> H >> W;
    for (int i = 0; i < H; ++i) h[i].resize(W, 0);
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
        scanf("%d", &h[i][j]);
        temp[j][i] = h[i][j];
    }
    
    bool can = true;
    if (!solve()) can = false;
        
    if (can) {
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j) 
                temp[i][j] = h[j][i];
        for (int i = 0; i < W; ++i) h[i].resize(H, 0);
        for (int i = 0; i < W; ++i) 
            for (int j = 0; j < H; ++j)
                h[i][j] = temp[i][j];
        swap(H, W);
       
        if (!solve()) can = false;
    }
        
    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;

    return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 15080
final_rank: 6

code_snippet: #include <algorithm>
// #include <atcoder/all>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vii = vector<int>;
using vvii = vector<vector<int>>;
using vvvii = vector<vector<vector<int>>>;
using vdd = vector<ld>;
using vvdd = vector<vector<ld>>;
using vvvdd = vector<vector<vector<ld>>>;
using vbb = vector<bool>;
using vvbb = vector<vector<bool>>;
using vvvbb = vector<vector<vector<bool>>>;
using vpll = vector<pll>;
using vvpll = vector<vector<pll>>;
using vvvpll = vector<vector<vector<pll>>>;
#define pb push_back
#define mp make_pair
#define sc second
#define fr first
#define endl '\n'
#define stpr std::fixed << setprecision
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, a, b, d) for (ll i = (a); i <= (b); i += d)
#define Rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define rrep(i, n) for (ll i = n - 1; i >= 0; i--)
#define drrep(i, a, b, d) for (ll i = (a); i >= (b); i -= d)
#define rRep(i, a, b) for (ll i = a; i >= b; i--)
#define crep(i) for (char i = 'a'; i <= 'z'; ++i)
#define Crep(i) for (char i = 'A'; i <= 'Z'; ++i)
#define ALL(x) (x).begin(), (x).end()
#define rALL(x) (x).rbegin(), (x).rend()
#define sort2(A, N) \
  sort(A, A + N,    \
       [](const pii &a, const pii &b) { return a.second < b.second; });
#define debug(v)      \
  cout << #v << ":";  \
  for (auto x : v) {  \
    cout << x << ' '; \
  }                   \
  cout << endl;
int ctoi(const char c) {
  if ('0' <= c && c <= '9') return (c - '0');
  return -1;
}
ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
constexpr ll MOD = 1000000007;
constexpr ll INF = 1000000011;
constexpr ll MOD2 = 998244353;
constexpr ll LINF = 1001002003004005006ll;
constexpr ld EPS = 10e-10;
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &&x : v) is >> x;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first;
  is >> p.second;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << ' ' << p.second;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (auto i = begin(v); i != end(v); ++i) {
    if (i != begin(v)) os << ' ';
    os << *i;
  }
  return os;
}

namespace internal {

template <class T>
struct simple_queue {
  std::vector<T> payload;
  int pos = 0;
  void reserve(int n) { payload.reserve(n); }
  int size() const { return int(payload.size()) - pos; }
  bool empty() const { return pos == int(payload.size()); }
  void push(const T &t) { payload.push_back(t); }
  T &front() { return payload[pos]; }
  void clear() {
    payload.clear();
    pos = 0;
  }
  void pop() { pos++; }
};

}  // namespace internal

template <class Cap>
struct mf_graph {
 public:
  mf_graph() : _n(0) {}
  mf_graph(int n) : _n(n), g(n) {}

  int add_edge(int from, int to, Cap cap) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    assert(0 <= cap);
    int m = int(pos.size());
    pos.push_back({from, int(g[from].size())});
    int from_id = int(g[from].size());
    int to_id = int(g[to].size());
    if (from == to) to_id++;
    g[from].push_back(_edge{to, to_id, cap});
    g[to].push_back(_edge{from, from_id, 0});
    return m;
  }

  struct edge {
    int from, to;
    Cap cap, flow;
  };

  edge get_edge(int i) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
  }
  std::vector<edge> edges() {
    int m = int(pos.size());
    std::vector<edge> result;
    for (int i = 0; i < m; i++) {
      result.push_back(get_edge(i));
    }
    return result;
  }
  void change_edge(int i, Cap new_cap, Cap new_flow) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    assert(0 <= new_flow && new_flow <= new_cap);
    auto &_e = g[pos[i].first][pos[i].second];
    auto &_re = g[_e.to][_e.rev];
    _e.cap = new_cap - new_flow;
    _re.cap = new_flow;
  }

  Cap flow(int s, int t) { return flow(s, t, std::numeric_limits<Cap>::max()); }
  Cap flow(int s, int t, Cap flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);

    std::vector<int> level(_n), iter(_n);
    internal::simple_queue<int> que;

    auto bfs = [&]() {
      std::fill(level.begin(), level.end(), -1);
      level[s] = 0;
      que.clear();
      que.push(s);
      while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (auto e : g[v]) {
          if (e.cap == 0 || level[e.to] >= 0) continue;
          level[e.to] = level[v] + 1;
          if (e.to == t) return;
          que.push(e.to);
        }
      }
    };
    auto dfs = [&](auto self, int v, Cap up) {
      if (v == s) return up;
      Cap res = 0;
      int level_v = level[v];
      for (int &i = iter[v]; i < int(g[v].size()); i++) {
        _edge &e = g[v][i];
        if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
        Cap d = self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
        if (d <= 0) continue;
        g[v][i].cap += d;
        g[e.to][e.rev].cap -= d;
        res += d;
        if (res == up) return res;
      }
      level[v] = _n;
      return res;
    };

    Cap flow = 0;
    while (flow < flow_limit) {
      bfs();
      if (level[t] == -1) break;
      std::fill(iter.begin(), iter.end(), 0);
      Cap f = dfs(dfs, t, flow_limit - flow);
      if (!f) break;
      flow += f;
    }
    return flow;
  }

  std::vector<bool> min_cut(int s) {
    std::vector<bool> visited(_n);
    internal::simple_queue<int> que;
    que.push(s);
    while (!que.empty()) {
      int p = que.front();
      que.pop();
      visited[p] = true;
      for (auto e : g[p]) {
        if (e.cap && !visited[e.to]) {
          visited[e.to] = true;
          que.push(e.to);
        }
      }
    }
    return visited;
  }

 private:
  int _n;
  struct _edge {
    int to, rev;
    Cap cap;
  };
  std::vector<std::pair<int, int>> pos;
  std::vector<std::vector<_edge>> g;
};

int main() {
  ll H, W;
  ll C, D;
  cin >> H >> W;
  vvll A(H, vll(W));
  cin >> A;
  if (1) {
    auto B = A;
    sort(ALL(B));
    vvll E(H);
    rep(i, H) {
      Rep(j, i + 1, H) {
        bool Z = 1;
        rep(k, W) {
          if (B[i][k] > B[j][k]) {
            Z = 0;
          }
        }
        if (Z) {
          E[j].pb(i);
        }
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, 1);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    if (E[H - 1].size() < H - 1) {
      cNO;
      return 0;
    }
    C = H - mf.flow(2 * H, 2 * H + 1);
  }
  if (1) {
    vvll B(W, vll(H));
    rep(i, H) {
      rep(j, W) { B[j][i] = A[i][j]; }
    }
    swap(H, W);
    sort(ALL(B));
    vvll E(H);
    rep(i, H) {
      Rep(j, i + 1, H) {
        bool Z = 1;
        rep(k, W) {
          if (B[i][k] > B[j][k]) {
            Z = 0;
          }
        }
        if (Z) {
          E[j].pb(i);
        }
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, 1);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    if (E[H - 1].size() < H - 1) {
      cNO;
      return 0;
    }
    D = H - mf.flow(2 * H, 2 * H + 1);
  }
  if (C <= 2 && D <= 2) {
    cYES;
  } else {
    cNO;
  }
}
accuracy: 1
time_ms: 630
memory_kb: 48420
final_rank: 16

code_snippet: #include <algorithm>
// #include <atcoder/all>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vii = vector<int>;
using vvii = vector<vector<int>>;
using vvvii = vector<vector<vector<int>>>;
using vdd = vector<ld>;
using vvdd = vector<vector<ld>>;
using vvvdd = vector<vector<vector<ld>>>;
using vbb = vector<bool>;
using vvbb = vector<vector<bool>>;
using vvvbb = vector<vector<vector<bool>>>;
using vpll = vector<pll>;
using vvpll = vector<vector<pll>>;
using vvvpll = vector<vector<vector<pll>>>;
#define pb push_back
#define mp make_pair
#define sc second
#define fr first
#define endl '\n'
#define stpr std::fixed << setprecision
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, a, b, d) for (ll i = (a); i <= (b); i += d)
#define Rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define rrep(i, n) for (ll i = n - 1; i >= 0; i--)
#define drrep(i, a, b, d) for (ll i = (a); i >= (b); i -= d)
#define rRep(i, a, b) for (ll i = a; i >= b; i--)
#define crep(i) for (char i = 'a'; i <= 'z'; ++i)
#define Crep(i) for (char i = 'A'; i <= 'Z'; ++i)
#define ALL(x) (x).begin(), (x).end()
#define rALL(x) (x).rbegin(), (x).rend()
#define sort2(A, N) \
  sort(A, A + N,    \
       [](const pii &a, const pii &b) { return a.second < b.second; });
#define debug(v)      \
  cout << #v << ":";  \
  for (auto x : v) {  \
    cout << x << ' '; \
  }                   \
  cout << endl;
int ctoi(const char c) {
  if ('0' <= c && c <= '9') return (c - '0');
  return -1;
}
ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
constexpr ll MOD = 1000000007;
constexpr ll INF = 1000000011;
constexpr ll MOD2 = 998244353;
constexpr ll LINF = 1001002003004005006ll;
constexpr ld EPS = 10e-10;
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &&x : v) is >> x;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first;
  is >> p.second;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << ' ' << p.second;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (auto i = begin(v); i != end(v); ++i) {
    if (i != begin(v)) os << ' ';
    os << *i;
  }
  return os;
}

namespace internal {

template <class T>
struct simple_queue {
  std::vector<T> payload;
  int pos = 0;
  void reserve(int n) { payload.reserve(n); }
  int size() const { return int(payload.size()) - pos; }
  bool empty() const { return pos == int(payload.size()); }
  void push(const T &t) { payload.push_back(t); }
  T &front() { return payload[pos]; }
  void clear() {
    payload.clear();
    pos = 0;
  }
  void pop() { pos++; }
};

}  // namespace internal

template <class Cap>
struct mf_graph {
 public:
  mf_graph() : _n(0) {}
  mf_graph(int n) : _n(n), g(n) {}

  int add_edge(int from, int to, Cap cap) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    assert(0 <= cap);
    int m = int(pos.size());
    pos.push_back({from, int(g[from].size())});
    int from_id = int(g[from].size());
    int to_id = int(g[to].size());
    if (from == to) to_id++;
    g[from].push_back(_edge{to, to_id, cap});
    g[to].push_back(_edge{from, from_id, 0});
    return m;
  }

  struct edge {
    int from, to;
    Cap cap, flow;
  };

  edge get_edge(int i) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
  }
  std::vector<edge> edges() {
    int m = int(pos.size());
    std::vector<edge> result;
    for (int i = 0; i < m; i++) {
      result.push_back(get_edge(i));
    }
    return result;
  }
  void change_edge(int i, Cap new_cap, Cap new_flow) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    assert(0 <= new_flow && new_flow <= new_cap);
    auto &_e = g[pos[i].first][pos[i].second];
    auto &_re = g[_e.to][_e.rev];
    _e.cap = new_cap - new_flow;
    _re.cap = new_flow;
  }

  Cap flow(int s, int t) { return flow(s, t, std::numeric_limits<Cap>::max()); }
  Cap flow(int s, int t, Cap flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);

    std::vector<int> level(_n), iter(_n);
    internal::simple_queue<int> que;

    auto bfs = [&]() {
      std::fill(level.begin(), level.end(), -1);
      level[s] = 0;
      que.clear();
      que.push(s);
      while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (auto e : g[v]) {
          if (e.cap == 0 || level[e.to] >= 0) continue;
          level[e.to] = level[v] + 1;
          if (e.to == t) return;
          que.push(e.to);
        }
      }
    };
    auto dfs = [&](auto self, int v, Cap up) {
      if (v == s) return up;
      Cap res = 0;
      int level_v = level[v];
      for (int &i = iter[v]; i < int(g[v].size()); i++) {
        _edge &e = g[v][i];
        if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
        Cap d = self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
        if (d <= 0) continue;
        g[v][i].cap += d;
        g[e.to][e.rev].cap -= d;
        res += d;
        if (res == up) return res;
      }
      level[v] = _n;
      return res;
    };

    Cap flow = 0;
    while (flow < flow_limit) {
      bfs();
      if (level[t] == -1) break;
      std::fill(iter.begin(), iter.end(), 0);
      Cap f = dfs(dfs, t, flow_limit - flow);
      if (!f) break;
      flow += f;
    }
    return flow;
  }

  std::vector<bool> min_cut(int s) {
    std::vector<bool> visited(_n);
    internal::simple_queue<int> que;
    que.push(s);
    while (!que.empty()) {
      int p = que.front();
      que.pop();
      visited[p] = true;
      for (auto e : g[p]) {
        if (e.cap && !visited[e.to]) {
          visited[e.to] = true;
          que.push(e.to);
        }
      }
    }
    return visited;
  }

 private:
  int _n;
  struct _edge {
    int to, rev;
    Cap cap;
  };
  std::vector<std::pair<int, int>> pos;
  std::vector<std::vector<_edge>> g;
};

int main() {
  ll H, W;
  ll C, D;
  cin >> H >> W;
  vvll A(H, vll(W));
  cin >> A;
  if (1) {
    auto B = A;
    sort(ALL(B));
    vvll E(H);
    rep(i, H) {
      Rep(j, i + 1, H) {
        bool Z = 1;
        rep(k, W) {
          if (B[i][k] > B[j][k]) {
            Z = 0;
          }
        }
        if (Z) {
          E[j].pb(i);
        }
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, INF);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    C = H - mf.flow(2 * H, 2 * H + 1);
  }
  if (1) {
    vvll B(W, vll(H));
    rep(i, H) {
      rep(j, W) { B[j][i] = A[i][j]; }
    }
    swap(H, W);
    sort(ALL(B));
    vvll E(H);
    rep(i, H) {
      Rep(j, i + 1, H) {
        bool Z = 1;
        rep(k, W) {
          if (B[i][k] > B[j][k]) {
            Z = 0;
          }
        }
        if (Z) {
          E[j].pb(i);
        }
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, INF);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    D = H - mf.flow(2 * H, 2 * H + 1);
  }
  if (C <= 1 && D <= 1) {
    cYES;
  } else {
    cNO;
  }
}
accuracy: 0.6621621621621622
time_ms: 610
memory_kb: 48668
final_rank: 18

code_snippet: #include <algorithm>
// #include <atcoder/all>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vii = vector<int>;
using vvii = vector<vector<int>>;
using vvvii = vector<vector<vector<int>>>;
using vdd = vector<ld>;
using vvdd = vector<vector<ld>>;
using vvvdd = vector<vector<vector<ld>>>;
using vbb = vector<bool>;
using vvbb = vector<vector<bool>>;
using vvvbb = vector<vector<vector<bool>>>;
using vpll = vector<pll>;
using vvpll = vector<vector<pll>>;
using vvvpll = vector<vector<vector<pll>>>;
#define pb push_back
#define mp make_pair
#define sc second
#define fr first
#define endl '\n'
#define stpr std::fixed << setprecision
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, a, b, d) for (ll i = (a); i <= (b); i += d)
#define Rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define rrep(i, n) for (ll i = n - 1; i >= 0; i--)
#define drrep(i, a, b, d) for (ll i = (a); i >= (b); i -= d)
#define rRep(i, a, b) for (ll i = a; i >= b; i--)
#define crep(i) for (char i = 'a'; i <= 'z'; ++i)
#define Crep(i) for (char i = 'A'; i <= 'Z'; ++i)
#define ALL(x) (x).begin(), (x).end()
#define rALL(x) (x).rbegin(), (x).rend()
#define sort2(A, N) \
  sort(A, A + N,    \
       [](const pii &a, const pii &b) { return a.second < b.second; });
#define debug(v)      \
  cout << #v << ":";  \
  for (auto x : v) {  \
    cout << x << ' '; \
  }                   \
  cout << endl;
int ctoi(const char c) {
  if ('0' <= c && c <= '9') return (c - '0');
  return -1;
}
ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
constexpr ll MOD = 1000000007;
constexpr ll INF = 1000000011;
constexpr ll MOD2 = 998244353;
constexpr ll LINF = 1001002003004005006ll;
constexpr ld EPS = 10e-10;
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &&x : v) is >> x;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first;
  is >> p.second;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << ' ' << p.second;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (auto i = begin(v); i != end(v); ++i) {
    if (i != begin(v)) os << ' ';
    os << *i;
  }
  return os;
}

namespace internal {

template <class T>
struct simple_queue {
  std::vector<T> payload;
  int pos = 0;
  void reserve(int n) { payload.reserve(n); }
  int size() const { return int(payload.size()) - pos; }
  bool empty() const { return pos == int(payload.size()); }
  void push(const T &t) { payload.push_back(t); }
  T &front() { return payload[pos]; }
  void clear() {
    payload.clear();
    pos = 0;
  }
  void pop() { pos++; }
};

}  // namespace internal

template <class Cap>
struct mf_graph {
 public:
  mf_graph() : _n(0) {}
  mf_graph(int n) : _n(n), g(n) {}

  int add_edge(int from, int to, Cap cap) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    assert(0 <= cap);
    int m = int(pos.size());
    pos.push_back({from, int(g[from].size())});
    int from_id = int(g[from].size());
    int to_id = int(g[to].size());
    if (from == to) to_id++;
    g[from].push_back(_edge{to, to_id, cap});
    g[to].push_back(_edge{from, from_id, 0});
    return m;
  }

  struct edge {
    int from, to;
    Cap cap, flow;
  };

  edge get_edge(int i) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
  }
  std::vector<edge> edges() {
    int m = int(pos.size());
    std::vector<edge> result;
    for (int i = 0; i < m; i++) {
      result.push_back(get_edge(i));
    }
    return result;
  }
  void change_edge(int i, Cap new_cap, Cap new_flow) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    assert(0 <= new_flow && new_flow <= new_cap);
    auto &_e = g[pos[i].first][pos[i].second];
    auto &_re = g[_e.to][_e.rev];
    _e.cap = new_cap - new_flow;
    _re.cap = new_flow;
  }

  Cap flow(int s, int t) { return flow(s, t, std::numeric_limits<Cap>::max()); }
  Cap flow(int s, int t, Cap flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);

    std::vector<int> level(_n), iter(_n);
    internal::simple_queue<int> que;

    auto bfs = [&]() {
      std::fill(level.begin(), level.end(), -1);
      level[s] = 0;
      que.clear();
      que.push(s);
      while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (auto e : g[v]) {
          if (e.cap == 0 || level[e.to] >= 0) continue;
          level[e.to] = level[v] + 1;
          if (e.to == t) return;
          que.push(e.to);
        }
      }
    };
    auto dfs = [&](auto self, int v, Cap up) {
      if (v == s) return up;
      Cap res = 0;
      int level_v = level[v];
      for (int &i = iter[v]; i < int(g[v].size()); i++) {
        _edge &e = g[v][i];
        if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
        Cap d = self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
        if (d <= 0) continue;
        g[v][i].cap += d;
        g[e.to][e.rev].cap -= d;
        res += d;
        if (res == up) return res;
      }
      level[v] = _n;
      return res;
    };

    Cap flow = 0;
    while (flow < flow_limit) {
      bfs();
      if (level[t] == -1) break;
      std::fill(iter.begin(), iter.end(), 0);
      Cap f = dfs(dfs, t, flow_limit - flow);
      if (!f) break;
      flow += f;
    }
    return flow;
  }

  std::vector<bool> min_cut(int s) {
    std::vector<bool> visited(_n);
    internal::simple_queue<int> que;
    que.push(s);
    while (!que.empty()) {
      int p = que.front();
      que.pop();
      visited[p] = true;
      for (auto e : g[p]) {
        if (e.cap && !visited[e.to]) {
          visited[e.to] = true;
          que.push(e.to);
        }
      }
    }
    return visited;
  }

 private:
  int _n;
  struct _edge {
    int to, rev;
    Cap cap;
  };
  std::vector<std::pair<int, int>> pos;
  std::vector<std::vector<_edge>> g;
};

int main() {
  ll H, W;
  ll C, D;
  cin >> H >> W;
  vvll A(H, vll(W));
  cin >> A;
  if (1) {
    auto B = A;
    sort(ALL(B));
    vvll E(H);
    rep(i, H - 1) {
      if (i < H - 2) {
        bool Z = 1;
        rep(j, W) {
          if (B[i][j] > B[i + 1][j]) {
            Z = 0;
          }
        }
        if (Z) {
          E[i + 1].pb(i);
          rep(j, E[i].size()) { E[i + 1].pb(E[i][j]); }
        }
      }
      bool T = 1;
      rep(j, W) {
        if (B[i][j] > B[H - 1][j]) {
          T = 0;
        }
      }
      if (T) {
        E[H - 1].pb(i);
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, INF);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    C = H - mf.flow(2 * H, 2 * H + 1);
  }
  if (1) {
    vvll B(W, vll(H));
    rep(i, H) {
      rep(j, W) { B[j][i] = A[i][j]; }
    }
    swap(H, W);
    sort(ALL(B));
    vvll E(H);
    rep(i, H - 1) {
      if (i < H - 2) {
        bool Z = 1;
        rep(j, W) {
          if (B[i][j] > B[i + 1][j]) {
            Z = 0;
          }
        }
        if (Z) {
          E[i + 1].pb(i);
          rep(j, E[i].size()) { E[i + 1].pb(E[i][j]); }
        }
      }
      bool T = 1;
      rep(j, W) {
        if (B[i][j] > B[H - 1][j]) {
          T = 0;
        }
      }
      if (T) {
        E[H - 1].pb(i);
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, INF);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    D = H - mf.flow(2 * H, 2 * H + 1);
    // cout << D << endl;
  }
  if (C <= 1 && D <= 1) {
    cYES;
  } else {
    cNO;
  }
}
accuracy: 0.6621621621621622
time_ms: 230
memory_kb: 48528
final_rank: 17

code_snippet: #include <algorithm>
// #include <atcoder/all>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vii = vector<int>;
using vvii = vector<vector<int>>;
using vvvii = vector<vector<vector<int>>>;
using vdd = vector<ld>;
using vvdd = vector<vector<ld>>;
using vvvdd = vector<vector<vector<ld>>>;
using vbb = vector<bool>;
using vvbb = vector<vector<bool>>;
using vvvbb = vector<vector<vector<bool>>>;
using vpll = vector<pll>;
using vvpll = vector<vector<pll>>;
using vvvpll = vector<vector<vector<pll>>>;
#define pb push_back
#define mp make_pair
#define sc second
#define fr first
#define endl '\n'
#define stpr std::fixed << setprecision
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, a, b, d) for (ll i = (a); i <= (b); i += d)
#define Rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define rrep(i, n) for (ll i = n - 1; i >= 0; i--)
#define drrep(i, a, b, d) for (ll i = (a); i >= (b); i -= d)
#define rRep(i, a, b) for (ll i = a; i >= b; i--)
#define crep(i) for (char i = 'a'; i <= 'z'; ++i)
#define Crep(i) for (char i = 'A'; i <= 'Z'; ++i)
#define ALL(x) (x).begin(), (x).end()
#define rALL(x) (x).rbegin(), (x).rend()
#define sort2(A, N) \
  sort(A, A + N,    \
       [](const pii &a, const pii &b) { return a.second < b.second; });
#define debug(v)      \
  cout << #v << ":";  \
  for (auto x : v) {  \
    cout << x << ' '; \
  }                   \
  cout << endl;
int ctoi(const char c) {
  if ('0' <= c && c <= '9') return (c - '0');
  return -1;
}
ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
constexpr ll MOD = 1000000007;
constexpr ll INF = 1000000011;
constexpr ll MOD2 = 998244353;
constexpr ll LINF = 1001002003004005006ll;
constexpr ld EPS = 10e-10;
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &&x : v) is >> x;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first;
  is >> p.second;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << ' ' << p.second;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (auto i = begin(v); i != end(v); ++i) {
    if (i != begin(v)) os << ' ';
    os << *i;
  }
  return os;
}

namespace internal {

template <class T>
struct simple_queue {
  std::vector<T> payload;
  int pos = 0;
  void reserve(int n) { payload.reserve(n); }
  int size() const { return int(payload.size()) - pos; }
  bool empty() const { return pos == int(payload.size()); }
  void push(const T &t) { payload.push_back(t); }
  T &front() { return payload[pos]; }
  void clear() {
    payload.clear();
    pos = 0;
  }
  void pop() { pos++; }
};

}  // namespace internal

template <class Cap>
struct mf_graph {
 public:
  mf_graph() : _n(0) {}
  mf_graph(int n) : _n(n), g(n) {}

  int add_edge(int from, int to, Cap cap) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    assert(0 <= cap);
    int m = int(pos.size());
    pos.push_back({from, int(g[from].size())});
    int from_id = int(g[from].size());
    int to_id = int(g[to].size());
    if (from == to) to_id++;
    g[from].push_back(_edge{to, to_id, cap});
    g[to].push_back(_edge{from, from_id, 0});
    return m;
  }

  struct edge {
    int from, to;
    Cap cap, flow;
  };

  edge get_edge(int i) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
  }
  std::vector<edge> edges() {
    int m = int(pos.size());
    std::vector<edge> result;
    for (int i = 0; i < m; i++) {
      result.push_back(get_edge(i));
    }
    return result;
  }
  void change_edge(int i, Cap new_cap, Cap new_flow) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    assert(0 <= new_flow && new_flow <= new_cap);
    auto &_e = g[pos[i].first][pos[i].second];
    auto &_re = g[_e.to][_e.rev];
    _e.cap = new_cap - new_flow;
    _re.cap = new_flow;
  }

  Cap flow(int s, int t) { return flow(s, t, std::numeric_limits<Cap>::max()); }
  Cap flow(int s, int t, Cap flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);

    std::vector<int> level(_n), iter(_n);
    internal::simple_queue<int> que;

    auto bfs = [&]() {
      std::fill(level.begin(), level.end(), -1);
      level[s] = 0;
      que.clear();
      que.push(s);
      while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (auto e : g[v]) {
          if (e.cap == 0 || level[e.to] >= 0) continue;
          level[e.to] = level[v] + 1;
          if (e.to == t) return;
          que.push(e.to);
        }
      }
    };
    auto dfs = [&](auto self, int v, Cap up) {
      if (v == s) return up;
      Cap res = 0;
      int level_v = level[v];
      for (int &i = iter[v]; i < int(g[v].size()); i++) {
        _edge &e = g[v][i];
        if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
        Cap d = self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
        if (d <= 0) continue;
        g[v][i].cap += d;
        g[e.to][e.rev].cap -= d;
        res += d;
        if (res == up) return res;
      }
      level[v] = _n;
      return res;
    };

    Cap flow = 0;
    while (flow < flow_limit) {
      bfs();
      if (level[t] == -1) break;
      std::fill(iter.begin(), iter.end(), 0);
      Cap f = dfs(dfs, t, flow_limit - flow);
      if (!f) break;
      flow += f;
    }
    return flow;
  }

  std::vector<bool> min_cut(int s) {
    std::vector<bool> visited(_n);
    internal::simple_queue<int> que;
    que.push(s);
    while (!que.empty()) {
      int p = que.front();
      que.pop();
      visited[p] = true;
      for (auto e : g[p]) {
        if (e.cap && !visited[e.to]) {
          visited[e.to] = true;
          que.push(e.to);
        }
      }
    }
    return visited;
  }

 private:
  int _n;
  struct _edge {
    int to, rev;
    Cap cap;
  };
  std::vector<std::pair<int, int>> pos;
  std::vector<std::vector<_edge>> g;
};

int main() {
  ll H, W;
  ll C, D;
  cin >> H >> W;
  vvll A(H, vll(W));
  cin >> A;
  if (1) {
    auto B = A;
    sort(ALL(B));
    vvll E(H);
    rep(i, H - 1) {
      bool Z = 1;
      rep(j, W) {
        if (B[i][j] > B[i + 1][j]) {
          Z = 0;
        }
      }
      if (Z) {
        E[i + 1].pb(i);
        rep(j, E[i].size()) { E[i + 1].pb(E[i][j]); }
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, 1);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    C = H - mf.flow(2 * H, 2 * H + 1);
    // cout << C << endl;
  }
  if (1) {
    vvll B(W, vll(H));
    rep(i, H) {
      rep(j, W) { B[j][i] = A[i][j]; }
    }
    swap(H, W);
    sort(ALL(B));
    vvll E(H);
    rep(i, H - 1) {
      bool Z = 1;
      rep(j, W) {
        if (B[i][j] > B[i + 1][j]) {
          Z = 0;
        }
      }
      if (Z) {
        E[i + 1].pb(i);
        rep(j, E[i].size()) { E[i + 1].pb(E[i][j]); }
      }
    }
    mf_graph<ll> mf(2 * H + 2);
    rep(i, H) {
      mf.add_edge(2 * H, i, 1);
      mf.add_edge(H + i, 2 * H + 1, 1);
      rep(j, E[i].size()) { mf.add_edge(i, H + E[i][j], 1); }
    }
    D = H - mf.flow(2 * H, 2 * H + 1);
    // cout << D << endl;
  }
  if (C == D) {
    cYES;
  } else {
    cNO;
  }
}
accuracy: 0.12162162162162163
time_ms: 180
memory_kb: 32656
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 1005
#define NUM 2010

int H,W;
int table[2][SIZE][SIZE];
int in_num[SIZE];

int V;
vector<int> G[NUM];
int match[NUM];
bool used[NUM];

void add_edge(int from,int to){
	G[from].push_back(to);
	G[to].push_back(from);
}

int dfs(int node_id){
	used[node_id] = true;

	for(int i = 0; i < G[node_id].size(); i++){
		int adj_node_id = G[node_id][i],pair_id = match[adj_node_id];
		if((pair_id < 0)||
				(used[pair_id] == false && dfs(pair_id) == true)){

			match[node_id] = adj_node_id;
			match[adj_node_id] = node_id;
			return true;
		}
	}
	return false;
}


int bipartie_matching(){
	int ret = 0;
	for(int i = 0; i < V; i++)match[i] = -1;
	for(int node_id = 0; node_id < V; node_id++){
		if(match[node_id] < 0){
			for(int i = 0; i < V; i++)used[i] = false;
			if(dfs(node_id)){
				ret++;
			}
		}
	}
	return ret;
}


int main(){

	scanf("%d %d",&H,&W);

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			scanf("%d",&table[0][row][col]);
			table[1][col][row] = table[0][row][col];
		}
	}

	bool FLG;

	for(int i = 0; i < 2; i++){

		if(H == 1){
			swap(H,W);
			continue;
		}

		V = 2*H;

		for(int i = 0; i < H; i++){

			in_num[i] = 0;
		}

		for(int a = 0; a < H; a++){
			for(int b = 0; b < H; b++){
				if(b == a)continue;

				FLG = true;
				for(int k = 0; k < W; k++){
					if(table[i][a][k] < table[i][b][k]){

						FLG = false;
						break;
					}
				}
				if(!FLG)continue;

				add_edge(a,b+H);
				in_num[b]++;
			}
		}

		int count = 0;
		for(int i = 0; i < H; i++){

			if(in_num[i] > 0)count++;
		}
		if(count != H-1){

			printf("NO\n");
			return 0;
		}

		int num_match = bipartie_matching();

		//printf("i:%d num_match:%d\n",i,num_match);

		if(H-num_match > 2){

			printf("NO\n");
			return 0;
		}

		for(int a = 0; a < V; a++){

			G[a].clear();
		}

		swap(H,W);
	}

	printf("YES\n");

	return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 18240
final_rank: 12

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 1005
#define NUM 2010

int H,W;
int table[2][SIZE][SIZE];


int V;
vector<int> G[NUM];
int match[NUM];
bool used[NUM];

void add_edge(int from,int to){
	G[from].push_back(to);
	G[to].push_back(from);
}

int dfs(int node_id){
	used[node_id] = true;

	for(int i = 0; i < G[node_id].size(); i++){
		int adj_node_id = G[node_id][i],pair_id = match[adj_node_id];
		if((pair_id < 0)||
				(used[pair_id] == false && dfs(pair_id) == true)){

			match[node_id] = adj_node_id;
			match[adj_node_id] = node_id;
			return true;
		}
	}
	return false;
}


int bipartie_matching(){
	int ret = 0;
	for(int i = 0; i < V; i++)match[i] = -1;
	for(int node_id = 0; node_id < V; node_id++){
		if(match[node_id] < 0){
			for(int i = 0; i < V; i++)used[i] = false;
			if(dfs(node_id)){
				ret++;
			}
		}
	}
	return ret;
}


int main(){

	scanf("%d %d",&H,&W);

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			scanf("%d",&table[0][row][col]);
			table[1][col][row] = table[0][row][col];
		}
	}

	bool FLG;

	for(int i = 0; i < 2; i++){

		if(H == 1){
			swap(H,W);
			continue;
		}

		V = 2*H;

		int maximum = 0;

		for(int a = 0; a < H; a++){
			for(int b = 0; b < H; b++){
				if(b == a)continue;

				FLG = true;
				for(int k = 0; k < W; k++){
					if(table[i][a][k] < table[i][b][k]){

						FLG = false;
						break;
					}
				}
				if(!FLG)continue;

				add_edge(a,b+H);
			}
			maximum = max(maximum,(int)G[a].size());
		}

		if(maximum < H-1){

			printf("NO\n");
			return 0;
		}

		int num_match = bipartie_matching();

		//printf("i:%d num_match:%d\n",i,num_match);

		if(H-num_match > 2){

			printf("NO\n");
			return 0;
		}

		for(int a = 0; a < V; a++){

			G[a].clear();
		}

		swap(H,W);
	}

	printf("YES\n");

	return 0;
}
accuracy: 1
time_ms: 860
memory_kb: 18088
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define rrep(i,n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i,s,n) for (int i = (s); i < (n); ++i)
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vvi vector<vector<int>>
#define vl vector<ll>
#define vvl vector<vector<ll>>
#define vd vector<double>
#define vs vector<string>
#define vc vector<char>
#define vb vector<bool>
#define vp vector<P>
using namespace std;
using ll = long long;
using P = pair<int,int>;
using LP = pair<ll,ll>;
template<class T> istream& operator>>(istream& is,vector<T>& v) { for(T& t:v){is>>t;} return is; }
template<class T> ostream& operator<<(ostream& os,const vector<T>& v) { for(T t:v){os<<t<<" ";} os<<"\n"; return os; }
void Yes(bool b) { cout << (b ? "Yes" : "No") << endl; }
void YES(bool b) { cout << (b ? "YES" : "NO") << endl; }
template<class T> inline bool chmin(T& a,T b) {if(a > b){a = b; return true;} return false;}
template<class T> inline bool chmax(T& a,T b) {if(a < b){a = b; return true;} return false;}
const int inf = 1001001001;
const ll linf = 1001001001001001001;

class Bipartite_matching {
    int n;
    vvi G;
    vi match;
    vb used;
    bool dfs(int v) {
        used[v] = true;
        for(int u : G[v]) {
            int w = match[u];
            if(w < 0 || !used[w] && dfs(w)) {
                match[v] = u;
                match[u] = v;
                return true;
            }
        }
        return false;
    }

public:
    Bipartite_matching(int n):n(n),G(n),match(n),used(n) {}
    void add_edge(int v,int u) {
        G[v].pb(u);
        G[u].pb(v);
    }
    int max_matching() {
        int res = 0;
        match.assign(n,-1);
        rep(i,n) {
            if(match[i] >= 0) continue;
            used.assign(n,false);
            if(dfs(i)) res++;
        }
        return res;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    int H,W;
    cin >> H >> W;
    vvi h(H,vi(W));
    cin >> h;
    rep(_,2) {
        Bipartite_matching bp(2*H);
        vb v(H,true);
        rep(i,H) rep(j,H) {
            if(i == j) continue;
            bool ok = true;
            rep(k,W) if(h[i][k] > h[j][k]) ok = false;
            if(ok) bp.add_edge(i,j+H);
            else v[j] = false;
        }
        bool flag = false;
        rep(i,H) if(v[i]) flag = true;
        if(!flag) {
            YES(false);
            return 0;
        }
        if(H-bp.max_matching() > 2) {
            YES(false);
            return 0;
        }
        vvi nh(W,vi(H));
        rep(i,H) rep(j,W) nh[j][i] = h[i][j];
        swap(H,W);
        swap(h,nh);
    }
    YES(true);
}
accuracy: 1
time_ms: 1400
memory_kb: 16272
final_rank: 15