Problem:
Hundred-Cell Calculation Puzzles
The
hundred-cell calculation
is a kind of calculation training.
In hundred-cell calculation, a sheet with ten by ten empty cells is
given.  Numbers, 0 through 9, are written on the top of the ten columns in
an arbitrary order. 0 through 9 are also written at the left of the
ten rows in an arbitrary order.  You are to fill the empty cells with
the sums of the top and left numbers, as an example shown in the
figure below.
You may think of more generalized drills.
Such a drill has different numbers of the columns and
rows, say
w
×
h.
The numbers to be written on the top and the left can be any integers.
Hideo is designing a puzzle based on the generalized hundred-cell calculation.
A sheet is given in which some of answer cells are filled with numbers,
but numbers on the top and the left are omitted.
The puzzle is to find these omitted numbers consistent with the filled numbers.
Hideo decided to construct puzzles by preparing sheets filled with all
the correct sums and then removing some of these sums.  This
guarantees that the puzzle has at least one solution.  The existence
of the solution, however, is not enough; it should be unique.
Hideo has found through many trials that, when the leftmost of the
numbers on the top is fixed to be 0, puzzles with
w
×
h
cells may have a unique solution when
w
+
h
− 1 sums are kept. He, however, could not figure out
which cells to keep for a single unique solution.
Your task is to help Hideo by writing a program that judges solution uniqueness
for each of the puzzle candidates he has made.
Input
The input consists of at most 100 datasets, each in the following format.
w
h
x
1
y
1
n
1
...
x
k
y
k
n
k
w
and
h
in the first line are the numbers of answer cells in one row and in one column, respectively
(2 ≤
w
≤ 100 and 2 ≤
h
≤ 100).
There remain
k
numbers (
k
=
w
+
h
− 1) in the answer cells.
The
k
lines starting from the second show that
the number
n
i
is in the cell
x
i
-th from
the left and
y
i
-th from the top.
x
i
,
y
i
,
n
i
are integers satisfying 1 ≤
x
i
≤
w
, 1 ≤
y
i
≤
h
, and −100 ≤
n
i
≤ 100.
Here,
x
= 1 means the leftmost and
y
= 1 means the topmost.
Either of
x
i
≠
x
j
or
y
i
≠
y
j
holds for different
i
and
j
.
The end of the input is indicated by a line containing two zeros separated by a space.
Output
For each dataset, output YES if the puzzle has a unique solution, and NO otherwise, in a line.
Sample Input
2 2
1 1 10
1 2 1
2 2 5
3 3
1 1 1
1 2 2
2 2 3
2 3 4
3 3 5
3 3
1 1 1
1 3 3
2 2 3
3 1 3
3 3 5
3 2
1 1 8
1 2 7
2 1 7
3 2 5
6 6
1 1 -2
1 4 4
2 2 2
3 3 3
3 4 8
4 2 -4
4 6 1
5 5 4
5 6 5
6 1 -7
6 3 -6
6 6
1 2 3
1 4 0
2 1 -3
2 3 -1
3 1 0
3 2 6
4 6 0
5 4 -5
5 5 -10
6 3 -6
6 5 -10
6 6
1 5 -2
2 5 -1
3 5 -7
4 1 5
4 2 -1
4 3 4
4 4 3
4 5 -1
4 6 2
5 5 -6
6 5 0
2 6
1 1 -2
1 2 -1
1 3 -3
1 4 -2
1 5 -5
1 6 -2
2 4 0
0 0
Output for the Sample Input
YES
YES
NO
YES
NO
NO
YES
YES

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define ld long double
using namespace std;


ll detA(vector<vector<ld>> M, ll n){
    ll t = 1;
    ll det = 1;
    for (int i = 1; i < n; i++){
        if (M[i][i] == 0){
            for (int j = i; j < n; j++){
                if (M[j][i] != 0){
                    swap(M[j],M[i]);
                    break;
                }
            }
        }
        ld first = M[i][i];
        if (first == 0){
            return 0;
        }
        for (int j = i+1; j < n; j++){
            if (M[j][i] != 0){
                ld t = M[j][i];
                for (ll k = i; k < n; k++){
                    M[j][k] -= (t/first)*M[i][k];
                }
            }
        }
    }
    for (ll l = 0; l < n; l++){
        det *= M[l][l];
    }
    return det;
}


int main(){
    while (true){
        ll H,W;
        cin >> W >> H;
        if (H == 0 and W == 0){
            break;
        }
        else{
            vector<vector<ld>> A(H+W,vector<ld>(H+W,0));
            A[0][0] = 1;
            for (ll i = 1; i < H+W; i++){
                ll x,y,z;
                cin >> x >> y >> z;
                A[i][x-1] = 1;
                A[i][W+y-1] = 1;
            }
            
            bool a;

            if (detA(A,H+W) == 0){
                a = false;
            }
            else{
                a = true;
            }

            
            
            vector<string> T {"NO", "YES"};
            cout << T[a] << endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 4500
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#include <atcoder/modint>
#include <deque>
#include <atcoder/scc>
using namespace std;
using namespace atcoder;
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll=vector<vector<ll>>;
using Graph=vvll;
using Edgegraph=vector<vector<pair<ll,ll>>>;
using vch=vector<char>;
using vvch=vector<vector<char>>;
using P=pair<ll,ll>;
using vP=vector<P>;
using tup=tuple<ll,ll,ll>;
using vbl=vector<bool>;
using vvbl=vector<vbl>;
using mint = atcoder::modint998244353;
const int infint = 1073741823;
const ll inf = 1LL << 60;
template <class T> inline bool chmax(T& a,T b){if (a<b){a=b;return 1;}return 0;}
template <class T> inline bool chmin(T& a,T b){if (a>b){a=b;return 1;}return 0;}
#define rep(i,x,lim) for(ll i = (x);i < (ll)(lim);i++)
#define rep2(j,x,lim) for(int j = (x);j < (int)(lim);j++)

set<ll> Hseen;
set<ll> Wseen;

void bfs(Graph WG,Graph HG,P p){
    ll w=p.first;
    ll h=p.second;
    Hseen.insert(h);
    Wseen.insert(w);
    for(ll next:WG[w]){
        if(!Hseen.count(next)) bfs(WG,HG,make_pair(w,next));
    }
    for(ll next:HG[h]){
        if(!Wseen.count(next)) bfs(WG,HG,make_pair(next,h));
    }
}
int main(){
    vbl ans;
    while(1){
        ll W,H;
        cin >> W >> H;
        ll lastx,lasty;
        if(W==0&&H==0) break;
        Graph WG(101);
        Graph HG(101);
        rep(i,0,W+H-1){
            ll x,y,n;
            cin >> x >> y >> n;
            x--;y--;
            WG[x].push_back(y);
            HG[y].push_back(x);
            lastx=x;
            lasty=y;
        }
        bfs(WG,HG,make_pair(lastx,lasty));
        if(Hseen.size()==H&&Wseen.size()==W) ans.push_back(true);
        else ans.push_back(false);
        Hseen.clear();
        Wseen.clear();
    }
    rep(i,0,ans.size()){
        if(ans[i]) cout << "YES" << '\n';
        else cout << "NO" << '\n';
    }
}
accuracy: 1
time_ms: 30
memory_kb: 6096
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#include <atcoder/dsu>
using namespace std;
using namespace atcoder;
bool solve();

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  int T = 1;
  // cin >> T;
  while(solve());
  return 0;
}

bool solve() {
  int W,H;cin>>W>>H;
  if(W==0)return 0;
  vector ex(H,vector<bool>(W));
  for(int i=0;i<W+H-1;i++){
    int x,y,n;cin>>x>>y>>n;
    x--,y--;
    ex[y][x]=true;
  }

  queue<pii>q;
  rep(i,0,H)if(ex[i][0])q.emplace(i,0);

  vector<bool>rok(H),cok(W);
  cok[0]=true;

  while(!q.empty()){
    auto [r,c]=q.front();
    cok[c]=rok[r]=true;
    ex[r][c]=false;
    q.pop();

    rep(i,0,H)if(ex[i][c])q.emplace(i,c);
    rep(i,0,W)if(ex[r][i])q.emplace(r,i);
  }

  int ok_sum=0;
  rep(i,0,H)ok_sum+=rok[i];
  rep(i,0,W)ok_sum+=cok[i];

  cout<<((ok_sum==W+H)?"YES":"NO")<<endl;
  return 1;
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 13

code_snippet: //#pragma GCC target("avx2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pli = pair<ll,int>;
#define AMARI 998244353
//#define AMARI 1000000007
#define el '\n'
#define El '\n'
#define YESNO(x) ((x) ? "Yes" : "No")
#define YES YESNO(true)
#define NO YESNO(false)
#define REV_PRIORITY_QUEUE(tp) priority_queue<tp,vector<tp>,greater<tp>>
#define EXIT_ANS(x) {cout << (x) << '\n'; return;}
template <typename T> void inline SORT(vector<T> &v){sort(v.begin(),v.end()); return;}
template <typename T> void inline VEC_UNIQ(vector<T> &v){sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); return;}
template <typename T> T inline MAX(vector<T> &v){return *max_element(v.begin(),v.end());}
template <typename T> T inline MIN(vector<T> &v){return *min_element(v.begin(),v.end());}
template <typename T> T inline SUM(vector<T> &v){T ans = 0; for(int i = 0; i < (int)v.size(); i++)ans += v[i]; return ans;}
template <typename T> void inline DEC(vector<T> &v){for(int i = 0; i < (int)v.size(); i++)v[i]--; return;}
template <typename T> void inline INC(vector<T> &v){for(int i = 0; i < (int)v.size(); i++)v[i]++; return;}
void inline TEST(void){cerr << "TEST" << endl; return;}
template <typename T> bool inline chmin(T &x,T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}
template <typename T> bool inline chmax(T &x,T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}
template <typename T = long long> vector<T> inline get_vec(int n){
    vector<T> ans(n);
    for(int i = 0; i < n; i++)cin >> ans[i];
    return ans;
}
template <typename T> void inline print_vec(vector<T> &vec,bool kaigyou = false){
    int n = (int)vec.size();
    for(int i = 0; i < n; i++){
        cout << vec[i];
        if(kaigyou || i == n - 1)cout << '\n';
        else cout << ' ';
    }
    if(!n)cout << '\n';
    return;
}
template <typename T> void inline debug_vec(vector<T> &vec,bool kaigyou = false){
    int n = (int)vec.size();
    for(int i = 0; i < n; i++){
        cerr << vec[i];
        if(kaigyou || i == n - 1)cerr << '\n';
        else cerr << ' ';
    }
    if(!n)cerr << '\n';
    return;
}
vector<vector<int>> inline get_graph(int n,int m = -1,bool direct = false){
    if(m == -1)m = n - 1;
    vector<vector<int>> g(n);
    while(m--){
        int u,v;
        cin >> u >> v;
        u--; v--;
        g[u].push_back(v);
        if(!direct)g[v].push_back(u);
    }
    return g;
}

vector<int> make_inv(vector<int> p){
    int n = (int)p.size();
    vector<int> ans(n);
    for(int i = 0; i < n; i++)ans[p[i]] = i;
    return ans;
}

#define MULTI_TEST_CASE false
void solve(void){
    ll w,h;
    cin >> w >> h;
    if(w == 0 && h == 0){exit(0);}
    vector<ll> a(w,-1);
    vector<ll> b(h,-1);
    a[0] = 0;
    vector<vector<ll>> v(h,vector<ll>(w,-1));
    for(int i=0;i<w+h-1;i++){
        ll x,y,z;
        cin >> y >> x >> z;
        x--;
        y--;
        v[x][y] = 0;
    }
    //return;
    for(int i=0;i < 2*(h+w);i++){
        for(int j=0;j<h;j++){
            for(int k=0;k<w;k++){
                if(a[k] != -1 && b[j] != -1){
                    v[j][k] = 0;
                }
                if(v[j][k] != -1){
                    if(a[k] != -1){
                        b[j] = 0;
                    }
                    if(b[j] != -1){
                        a[k] = 0;
                    }
                }
            }
        }
    }

    ll ans = 0;
    for(int i=0;i<h;i++){
        if(b[i] != -1){ans++;}
    }
    for(int i=0;i<w;i++){
        if(a[i] != -1){ans++;}
    }
    cout << ((ans == w+h)?"YES":"NO") << endl;
    return;
}

void calc(void){
    return;
}

signed main(void){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    calc();
    int t = 1;
    if(MULTI_TEST_CASE)cin >> t;
    while(1){
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<n;i++)
#define REP2(i, n) for (ll i=0;i<n;i++)
#define REP3(i, a, n) for (ll i=a;i<n;i++)
#define REP4(i, a, b, n) for(ll i=a;i<n;i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=n;i>=0;i--)
#define RREP2(i, n) for(ll i=n;i>=0;i--)
#define RREP3(i, a, n) for(ll i=n;i>=a;i--)
#define RREP4(i, a, b, n) for(ll i=n;i>=a;i-=b)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define foa(a,v)  (auto& a : (v))
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
#define pb push_back
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
template<class... T>
constexpr auto min(T... a){
    return min(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
constexpr auto max(T... a){
    return max(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}
template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void print(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void print(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}


void solve(ll h,ll w,vpll a){
    vll x(h,-1);
    vll y(w,-1);
    y[0] = 0;
    vvll check(h,vll(w,0));
    for(auto [y,x]:a){
        check[x-1][y-1] = 1;
    }
    rep(l,h+w){
        rep(i,h){
            rep(j,w){
                if(x[i] == 0 && y[j] == 0){
                    check[i][j] = 1;
                }
                if(check[i][j] && x[i] == 0){
                    y[j] = 0;
                }
                if(check[i][j] && y[j] == 0){
                    x[i] = 0;
                }
            }
        }
    }
    rep(i,h){
        rep(j,w){
            if(check[i][j] == 0){
                print("NO");
                return;
            }
        }
    }
    print("YES");
}

int main(){
    while(1){
        LL(w,h);
        if(w == 0){break;}
        vpll a;
        rep(i,h+w-1){
            LL(p,q,r);
            a.push_back({p,q});
        }
        solve(h,w,a);
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3584
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;

int main(void){
    vector<string> ans;
    while(1){
        int h,w;cin>>w>>h;
        if(h==0)break;
        vector<int> x(w,999),y(h,999);
        x[0]=0;
        vector<vector<int>> g(h,vector<int>(w,999));
        for(int k=0;k<w+h-1;k++){
            int t,s;cin>>t>>s;
            t--;s--;
            cin>>g[s][t];
            if(t==0){
                y[s]=g[s][t];
            }
        }
        for(int p=0;p<100;p++){
            for(int i=0;i<h;i++){
                for(int j=0;j<w;j++){
                    if(g[i][j]!=999&&y[i]!=999){
                        x[j]=g[i][j]-y[i];
                    }
                    if(g[i][j]!=999&&x[j]!=999){
                        y[i]=g[i][j]-x[j];
                    }
                    if(y[i]!=999&&x[j]!=999){
                        g[i][j]=y[i]+x[j];
                    }
                }
            }
        }
        bool f=true;
        for(int i=0;i<h;i++){
            if(y[i]==999){
                f=false;
                break;
            }
        }
        for(int i=0;i<w;i++){
            if(x[i]==999){
                f=false;
                break;
            }
        }
        if(f){
            ans.push_back("YES");
        }else{
            ans.push_back("NO");
        }
    }
    for(string x:ans)cout<<x<<endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3412
final_rank: 9

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

int main() {
    while (true) {
        int w, h;
        cin >> w >> h;
        if (w == 0 && h == 0) {
            break;
        }

        vector<vector<int>> grid(h, vector<int>(w, 10000));
        vector<int> top(w, 10000);
        vector<int> left(h, 10000);

        for (int i = 0; i < w + h - 1; ++i) {
            int x, y, n;
            cin >> x >> y >> n;
            grid[y-1][x-1] = n;
        }

        top[0] = 0;
        queue<pair<int, int>> q;
        q.push({0, 0}); // second 0 == top, 1 == left

        while (!q.empty()) {
            auto v = q.front();
            q.pop();
            if (v.second == 0) {
                for (int k = 0; k < h; ++k) {
                    if (grid[k][v.first] != 10000 && left[k] == 10000) {
                        left[k] = grid[k][v.first] - v.first;
                        q.push({k, 1});
                    }
                }
            } else {
                for (int k = 0; k < w; ++k) {
                    if (grid[v.first][k] != 10000 && top[k] == 10000) {
                        top[k] = grid[v.first][k] - v.first;
                        q.push({k, 0});
                    }
                }
            }

            for (int y = 0; y < h; ++y) {
                for (int x = 0; x < w; ++x) {
                    if (left[y] != 10000 && top[x] != 10000) {
                        grid[y][x] = left[y] + top[x];
                    }
                }
            }
        }

        string ans = "YES";
        for (int y = 0; y < h; ++y) {
            if (left[y] == 10000) {
                ans = "NO";
                break;
            }
        }

        for (int x = 0; x < w; ++x) {
            if (top[x] == 10000) {
                ans = "NO";
                break;
            }
        }

        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3404
final_rank: 6

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

const int initial = -101;



int main(){
    while(1){
        int w,h;
        cin >> w >> h;
        if(w==0&&h==0)break;
        vector <int> yoko(w,0),tate(h,0);
        vector <vector <int> > map(h,vector<int>(w,initial));
        yoko[0] = 1;
        for(int k=0;k<h+w-1;k++){
            int xi,yi,ni;
            cin >> xi >> yi >> ni;
            for(int i=0;i<w;i++){
                for(int j=0;j<h;j++){
                    if(xi == i+1 && yi == j+1){
                        map[j][i] = ni;
                    }
                }
            }
        }
        queue<int> q;
        q.push(1);
        while(1){
            if(q.empty())break;
            else if(q.front() > 0){
                int tmp = q.front();
                tmp -= 1;
                q.pop();
                for(int i=0;i<h;i++){
                    if(map[i][tmp] != initial){
                        map[i][tmp] = initial;
                        tate[i] = 1;
                        q.push(-i-1);
                    }
                } 
            }  
            else if(q.front() < 0){
                int tmp = -q.front();
                tmp -= 1;
                q.pop();
                for(int i=0;i<w;i++){
                    if(map[tmp][i]!= initial){
                        map[tmp][i] = initial;
                        yoko[i] = 1;
                        q.push(i+1);
                    }
                }
            }
    
        }
       
        int flag = 0;
        for(int i=0;i<h;i++){
            if(tate[i] == 0){
                flag = 1;
                break;
            }
        }
        if(flag == 0){
            for(int i=0;i<w;i++){
                if(yoko[i] == 0){
                    flag = 1;
                    break;
                }
            }
        }
        if(flag == 1)cout << "NO" << endl;
        else cout << "YES" << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3212
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    while(1){
        int h,w; cin>>w>>h;
        if(h == 0) break;
        vector<vector<int>> t(h,vector<int>(w,0));
        for(int i = 0; i<h+w-1; i++){
            int x,y,n; cin>>x>>y>>n; x--;y--;
            t[y][x] = 1;
        }


        for(int k = 0; k<w+5; k++){
            bool f = 1;
            for(int j = 0; j<h-1; j++){
            for(int j2 = j+1; j2<h; j2++){
                bool c = 0;
                for(int i = 0; i<w; i++){
                    if(t[j][i] == 1 && t[j2][i] == 1){
                        c = 1;
                        break;
                    }
                }
                if(c == 0) continue;
                for(int i = 0; i<w; i++){
                    if(t[j][i] == 1 || t[j2][i] == 1){
                        t[j][i] = 1;
                        t[j2][i] = 1;
                    }
                }
            }}
            for(int i = 0; i<h; i++){
                for(int j = 0; j<w; j++){
                    if(t[i][j] == 0){
                        f = 0;
                        break;
                    }
                }
            }
            if(f) break;
        }
        bool ans =  1;
        bool tate= 0, yoko = 0;
        for(int i = 0; i<h; i++){
            for(int j = 0; j<w; j++){
                 if(t[i][j] == 0){
                     /*if(tate == 0 && i < h-1 && t[i+1][j] == 0){
                        tate = 1;
                        for(int i2 = 0; i2<h; i2++) t[i2][j] = 1;
                        continue;
                     }else if(yoko == 0 && j < w-1 && t[i][j+1] == 0){
                        yoko = 1;
                        for(int j2 = 0; j2<w; j2++) t[i][j2] = 1;
                        continue;
                     }*/
                     ans = 0;
                     //break;
                 }
               //  cout<<t[i][j]<<" ";
            }
           // cout<<endl;
        }
        
        cout<<(ans ? "YES" : "NO")<<endl;
    }
}
accuracy: 1
time_ms: 380
memory_kb: 3420
final_rank: 15

code_snippet: // clang-format off
#include <bits/stdc++.h>

// #pragma once

using namespace std;

using ll = int64_t;
using ull = unsigned long long;
using ld = long double;
using P = pair<ll,ll>;
using V = vector<ll>;
using M = vector<vector<ll>>;

#define rep(i, n) for (ll i = 0; i < static_cast<ll>(n); ++i)
#define rep_rev(i, n) for (ll i = n - 1; i >= 0; --i)
#define rep2(i, a, b) for (ll i = a; i < static_cast<ll>(b); ++i)
#define rep_rev2(i, a, b) for (ll i = b - 1; i >= a; --i)
#define all(v) (v).begin(), (v).end()
#define bit(n,k) (((n)>>(k))&1)
#define isin(x, l, r) (l <= (x) && (x) < r)
#define dx4 {-1, 0, 1, 0}
#define dy4 {0, 1, 0, -1}
#define dx8 {-1, -1, 0, 1, 1, 1, 0, -1}
#define dy8 {0, 1, 1, 1, 0, -1, -1, -1}
#define length(a) static_cast<ll>(a.size())
#define get(x, i) get<i>(x)
#define sign(x) ((x == 0) ? 0 : (x) / abs(x))
#define ndigits(x) static_cast<ll>(floor(log10(x)) + 1)
#define deg2rad(x) ((x) * M_PI / 180)
#define rad2deg(x) ((x) * 180 / M_PI)
#define log(x, y) (log(y) / log(x))
#define scanvar(T, x) T x; cin >> x
#define scanll(x) ll x; cin >> x
#define scanv(T, v, n) vector<T> v; for (int i = 0; i < n; ++i) { T temp; cin >> temp; (v).push_back(temp); }
#define scanvs(v) vector<char> v; do { scanvar(string, temp); for (char c : temp) {v.push_back(c); } } while (false)
#define scanm(T, m, a, b) vector<vector<T>> m(a, vector<T>(b)); rep(i, a) { rep(j, b) { cin >> m[i][j]; } }
#define scanms(m, a, b) vector<vector<char>> m(a, vector<char>(b)); rep(i,a) { scanvar(string, temp); rep(j, b) { m[i][j] = temp[j]; } }
#define pl(x) cout << (x) << endl
#define printld(x) printf("%.12Lf\n", x)
#define printv(v) for (auto __x: v) {cout << __x << " ";} cout << endl;
#define printm(m) for (auto __v : m) { printv(__v); }

ll _pow(ll a, ll b) { ll res = 1; while (b > 0) { if (b & 1) res *= a; a *= a; b >>= 1; } return res; }
template <class T1, class T2, class Func> void __map(vector<T1> v, vector<T2>& res, Func f) { int n = v.size(); rep(i, n) { res[i] = f(v[i]); } }
template <class T> void __unique(vector<T>& v) { auto p = unique(all(v)); v.erase(p, v.end()); }
template <class T> void __join(const vector<T> v, const string separator, string& res) { ll n = v.size(); rep(i, n - 1) { res += to_string(v[i]) + separator; } res += to_string(v[n - 1]); }
void __joins(const vector<char> v, const string separator, string& res) { ll n = v.size(); rep(i, n - 1) { res += v[i] + separator; } if (n > 0) res += v[n - 1]; }
void __to_string(ll x, ll num, string& res, ll pad = -1) { while (x >= num) { res = to_string(x % num) + res; x /= num; } if (x > 0) res = to_string(x) + res; ll d = pad - res.size(); rep(i, d) { res = '0' + res; } }

// Debug
#define DEBUG_MODE 1
#define debug(x) if (DEBUG_MODE) { cout << "  \033[35m" << #x << "\033[m" << ": " << x << endl; }
#define debugld(x) if (DEBUG_MODE) { cout << `"  \033[35m`" << #x << `"\033[m`" << `": `"; printld(x);}
#define debugv(v) if (DEBUG_MODE) { cout << "  \033[35m" << #v << "\033[m" << ": "; for (auto& __x : v) {cout << __x << " "; } cout << endl; }
#define debugm(m) if (DEBUG_MODE) { cout << "  \033[35m" << #m << "\033[m" << ":\n"; for (auto __v : m) { cout << "  "; printv(__v); } cout << endl; }
// clang-format on
#if DEBUG_MODE

#endif

struct Node {
  ll val = 0;
  bool visited = false;
  ll x = 0;
  ll y = 0;

  Node() {}
  Node(ll x, ll y) : x(x), y(y) {}

  void setVal(ll val) {
    this->val = val;
    this->visited = true;
  }

  void print() {
    debug(x);
    debug(y);
    debug(val);
    debug(visited);
    pl("");
  }
};

void solve() {
  scanll(w);
  if (w == 0) exit(0);

  scanll(h);
  ll k = w + h - 1;
  scanm(ll, xyn, k, 3);

  vector<vector<Node>> m(h+1, vector<Node>(w+1));

  rep(i, h+1) {
    rep(j, w+1) {
      m[i][j] = Node(j, i);
    }
  }

  m[0][0].setVal(-1);

  rep(i, k) {
    ll x = xyn[i][0];
    ll y = xyn[i][1];
    ll n = xyn[i][2];
    m[y][x].setVal(n);
  }

  stack<Node*> s;
  m[0][1].setVal(0);
  s.push(&m[0][1]);

  auto cross = [&](ll x, ll y) {
    Node* left = &m[y][0];
    Node* upper = &m[0][x];
    Node* cur = &m[y][x];

    if (left == upper || left == cur || upper == cur) return;

    if (!left->visited && upper->visited && cur->visited) {
      left->setVal(cur->val - upper->val);
      s.push(left);
    }
    if (!upper->visited && left->visited && cur->visited) {
      upper->setVal(cur->val - left->val);
      s.push(upper);
    }
    if (!cur->visited && left->visited && upper->visited) {
      cur->setVal(left->val + upper->val);
      s.push(cur);
    }
  };

  while (!s.empty()) {
    Node* node = s.top();
    s.pop();

    ll x = node->x;
    ll y = node->y;

    rep(j, w+1) {
      if (j==x) continue;
      cross(j, y);
    }

    rep(i, h+1) {
      if (i==y) continue;
      cross(x, i);
    }
  }

  rep(i, h+1) {
    rep(j, w+1) {
      // m[i][j].print();
      if (!m[i][j].visited) {
        pl("NO");
        return;
      }
      // cout << m[i][j].val << " ";
    }
    // cout << endl;
  }

  pl("YES");
}

int main() {
  while (true) {
    solve();
  }
}
accuracy: 1
time_ms: 100
memory_kb: 3800
final_rank: 14

code_snippet: #include <bits/stdc++.h>

#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {

struct dsu {
  public:
    dsu() : _n(0) {}
    explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    std::vector<int> parent_or_size;
};

}  // namespace atcoder

using namespace std;
using namespace atcoder;

#define all(v) v.begin(), v.end()
#define ll long long
#define ld long double
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;

int main()
{
    while(true){
        ll w, h;
        cin >> w >> h;
        if(w == 0 && h == 0)return 0;
        ll k = w + h - 1;
        vl x(k), y(k), n(k);
        for (int i = 0; i < k;i++){
            cin >> x[i] >> y[i] >> n[i];
        }
        // in := 初期盤面
        vvl in(h, vl(w, 1e9));
        for (int i = 0; i < k;i++){
            in[y[i] - 1][x[i] - 1] = n[i];
        }
        bool ok = true;
        // 横方向のuf
        vl par(w);
        dsu uf1(w);
        for (int i = 0; i < w; i++)
            par[i] = i;
        for (int idx = 0; idx < h;idx++){
            for (int i = 0; i < w;i++){
                for (int j = i + 1; j < w;j++){
                    if(in[idx][i] != 1e9 && in[idx][j] != 1e9){
                        par[i] = par[j] = min(par[i], par[j]);
                        uf1.merge(i, j);
                    }
                }
            }
        }
        // for (int i = 0; i < w;i++){
        //     if(par[i] != 0){
        //         ok = false;
        //         break;
        //     }
        // }
        if(uf1.groups().size() != 1){
            ok = false;
        }
        // 縦方向
        vl par2(h);
        dsu uf2(h);
        for (int i = 0; i < h; i++)
            par2[i] = i;
        for (int idx = 0; idx < w; idx++){
            for (int i = 0; i < h;i++){
                for (int j = i + 1; j < h;j++){
                    if(in[i][idx] != 1e9 && in[j][idx] != 1e9){
                        par2[i] = par2[j] = min(par2[i], par2[j]);
                        uf2.merge(i, j);
                    }
                }
            }
        }
        // for (int i = 0; i < h;i++){
        //     if(par2[i] != 0){
        //         ok = false;
        //         break;
        //     }
        // }
        if(uf2.groups().size() != 1){
            ok = false;
        }
        if(ok)cout << "YES" << endl;
        else cout << "NO" << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3432
final_rank: 8

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

int checktate(vector<vector<int>> &board,vector<vector<int>> &clear,int h,int w){
    int change=0;
    for(int j=0;j<w;j++){
        for(int i=0;i<h;i++){
            if((clear.at(i).at(j)==2 || clear.at(i).at(j)==3) && board.at(i).at(j)!=-1000){
                for(int k=0;k<h;k++){
                    if(clear.at(k).at(j)==0){
                        clear.at(k).at(j)=1;
                        change=1;
                    }
                    else if(clear.at(k).at(j)==2){
                        clear.at(k).at(j)=3;
                        change=1;
                    }
                }
            }
        }
    }
    if(change){
        return 0;
    }
    return 1;
}

int checkyoko(vector<vector<int>> &board,vector<vector<int>> &clear,int h,int w){
    int change=0;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if((clear.at(i).at(j)==1 || clear.at(i).at(j)==3) && board.at(i).at(j)!=-1000){
                for(int k=0;k<w;k++){
                    if(clear.at(i).at(k)==0){
                        clear.at(i).at(k)=2;
                        change=1;
                    }
                    else if(clear.at(i).at(k)==1){
                        clear.at(i).at(k)=3;
                        change=1;
                    }
                    
                }
            }
        }
    }
    if(change){
        return 0;
    }
    return 1;
}

int checkfull(vector<vector<int>> &clear,int h,int w){
    int ok=1;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(clear.at(i).at(j)!=3){
                ok=0;
            }
        }
    }
    return ok;
}

int main(){
    int w,h,a,b,c,ok;
    while(1){
        cin>>w>>h;
        if(w==0 && h==0){
            break;
        }
        vector<vector<int>> board(h,vector<int>(w,-1000));
        vector<vector<int>> clear(h,vector<int>(w,0));
        for(int i=0;i<w+h-1;i++){
            cin>>a>>b>>c;
            board.at(b-1).at(a-1)=c;
        }
        for(int i=0;i<h;i++){
            clear.at(i).at(0)=1;
        }
        int flag=2;
        while(flag>0){
            flag=2;
            flag-=checktate(board,clear,h,w);
            flag-=checkyoko(board,clear,h,w);
        }
        ok=checkfull(clear,h,w);
        if(ok){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3460
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<long long>;
using vvl = vector<vector<long long>>; using vs = vector<string>;
using pl = pair<long long, long long>;
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template<class T>using rp_queue=priority_queue<T,vector<T>,greater<T>>;
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return a /gcd(a, b)*b;}
const ll INF = 1LL << 60;
const ld PI = acos(-1);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);
 
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif
void solve();
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
  int num_tc = 1;
  //cin >> num_tc;
  rep(tc,num_tc){
    //cout << "Case #" << tc+1 << ": " ;// << endl;
    solve();
  }
}
//見切り発車で実装しては行けない．頭の中でコードが完全に出来上がるまで書き始めるな．
void solve(){
  while(true){
    int w,h;cin>>w>>h;
    if(max(w,h)==0)return;
    const ll k = w+h-1;
    vl x(k),y(k),n(k);rep(i,k)cin>>x[i]>>y[i]>>n[i];
    vvl A(h,vl(w,INF));
    rep(i,k){
      y[i]--;
      x[i]--;
      A[y[i]][x[i]] = n[i];
    }
    vl X(h,INF),Y(w,INF);
    Y[0] = 0;
    rep(hw,h*w+1){
      rep(i,h){
        rep(j,w){
          if(A[i][j]!=INF&&X[i]!=INF)Y[j]=A[i][j]-X[i];
          if(A[i][j]!=INF&&Y[j]!=INF)X[i]=A[i][j]-Y[j];
        }
      }
    }
    bool ok = true;
    rep(i,h)ok&=X[i]!=INF;
    rep(i,w)ok&=Y[i]!=INF;
    cout<<(ok?"YES":"NO")<<endl;
  }
}
accuracy: 1
time_ms: 1610
memory_kb: 3564
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
using PP = pair<int, P>;
using PLL = pair<ll, ll>;
using PPLL = pair<ll, PLL>;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define loop(i, a, b) for (ll i = a; i <= b; ++i)
#define all(v) v.begin(), v.end()
constexpr ll INF = 1001001001001001001LL;
constexpr int INF32 = 1001001001;
constexpr ll MOD = 998244353;
constexpr ll MOD107 = 1000000007;

// Graph /////////////////////////////////////////////////////////
template <class T> struct Edge
{
    int from;
    int to;
    T val;

    Edge() : from(-1), to(-1), val(1) {}
    Edge(const int &i) {
        from = -1, to = i;
        val = 1;
    }
    Edge(int from, int to) : from(from), to(to), val(1) {}
    Edge(int from, int to, T val) : from(from), to(to), val(val) {}
    bool operator==(const Edge &e) const {
        return from == e.from && to == e.to && val == e.val;
    }
    bool operator!=(const Edge &e) const {
        return from != e.from || to != e.to || val != e.val;
    }

    operator int() const { return to; }

    friend ostream &operator<<(ostream &os, const Edge &e) {
        os << e.from << " -> " << e.to << " : " << e.val;
        return os;
    }
};
template <class T> using Graph = vector<vector<Edge<T>>>;
//////////////////////////////////////////////////////////////////

// Math //////////////////////////////////////////////////////////
ll pow(ll a, ll b) {
    ll res = 1;
    while (b > 0) {
        if (b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}
ll pow(ll a, ll b, ll mod) {
    if (b < 0) return pow(a, mod - 1 + b, mod);
    ll res = 1;
    while (b > 0) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
/**
 * @brief 法がmodのときのaの逆元を求める
 * @remark modが素数のときのみ有効
 * @remark
 * aとmodが互いに素でなければいけない(割り算の代わりに使う場合は、気にしなくても大丈夫)
 * @details a^(p-1) ≡ 1 mod p -[両辺にa^(-1)を掛ける]-> a^(p-2) ≡ a^(-1) mod p
 * @param a 逆元を求めたい値
 * @param mod 法
 * @return ll aの逆元
 */
ll inv(ll a, ll mod) {
    return pow(a, mod - 2, mod);
}

ll nCrDP[67][67];
ll nCr(ll n, ll r) {
    if (nCrDP[n][r] != 0) return nCrDP[n][r];
    if (r == 0 || n == r) return 1;
    return nCrDP[n][r] = nCr(n - 1, r - 1) + nCr(n - 1, r);
}
ll nHr(ll n, ll r) {
    return nCr(n + r - 1, r);
}

unordered_map<ll, vector<ll>> fact, invfact;
ll nCr(ll n, ll r, ll mod) {
    if (fact.count(mod) == 0 || fact[mod].size() <= max(n, r)) {
        const ll size = max(500000LL, max(n, r));
        fact[mod] = vector<ll>(size + 1, 0);
        invfact[mod] = vector<ll>(size + 1, 0);
        fact[mod][0] = 1;
        for (int i = 0; i < size; ++i)
            fact[mod][i + 1] = fact[mod][i] * (i + 1) % mod;
        invfact[mod][size] = inv(fact[mod][size], mod);
        for (int i = size - 1; i >= 0; --i)
            invfact[mod][i] = invfact[mod][i + 1] * (i + 1) % mod;
    }
    return fact[mod][n] * invfact[mod][r] % mod * invfact[mod][n - r] % mod;
}
ll nHr(ll n, ll r, ll mod) {
    return nCr(n + r - 1, r, mod);
}
//////////////////////////////////////////////////////////////////

// Linear Algebra ////////////////////////////////////////////////
const double Rad2Deg = 180.0 / M_PI;
const double Deg2Rad = M_PI / 180.0;
//////////////////////////////////////////////////////////////////

int dx[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[8] = {1, 0, -1, 0, 1, -1, 1, -1};

template <class T> inline bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> inline bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << " ";
    }
    return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &vv) {
    for (size_t i = 0; i < vv.size(); ++i) {
        os << vv[i];
        if (i != vv.size() - 1) os << "\n";
    }
    return os;
}

struct phash{
    inline size_t operator()(const pair<ll, ll> & p) const{
        const auto h1 = hash<ll>()(p.first);
        const auto h2 = hash<ll>()(p.second);
        return h1 + h2 * 12345;
    }
};



int solve() {
    ll w, h;
    cin >> w >> h;
    if (w == 0) return 1;
    ll n = w + h - 1;
    unordered_set<P, phash> cells;
    rep(i, n) {
        ll x, y, value;
        cin >> x >> y >> value;
        x--, y--;
        cells.insert({x, y});
    }

    vector<bool> knownW(w, false);
    vector<bool> knownH(h, false);
    knownW[0] = true;

    for (auto pos : cells) {
        if (pos.first == 0) { knownH[pos.second] = true; }
    }

    rep(i, w) {
        rep(x, w) {
            rep(y, h) {
                P pos = {x, y};
                if (cells.count(pos) && knownH[y]) {
                    knownW[x] = true;
                    break;
                }
            }
            if (knownW[x]) {
                rep(y, h) {
                    P pos = {x, y};
                    if (cells.count(pos)) { knownH[y] = true; }
                }
            }
        }

        /* rep(y, h) {
            rep(x, w) {
                P pos = {x, y};
                if (cells.count(pos) && knownW[x]) {
                    knownH[y] = true;
                    break;
                }
            }
            if (knownH[y]) {
                rep(x, w) {
                    P pos = {x, y};
                    if (cells.count(pos)) { knownW[x] = true; }
                }
            }
        } */
    }

    bool ok = true;
    rep(x, w) {
        if (!knownW[x]) {
            ok = false;
            break;
        }
    }
    rep(y, h) {
        if (!knownH[y]) {
            ok = false;
            break;
        }
    }

    cout << (ok ? "YES" : "NO") << endl;

    return 0;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while (!solve()) {}

    return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 3380
final_rank: 16

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

bool solve(){
  int H,W;
  cin>>H>>W;
  if(H==0&&W==0)return 0;
  int K=H+W;
  vector<vector<int>>MH(H),MW(W);
  vector<int>R(K-1,0),C(K-1,0),X(K-1,0);
  queue<int>q;
  for(int i=0;i<K-1;i++)
  {
    cin>>R[i]>>C[i]>>X[i];
    R[i]--,C[i]--;
    MH[R[i]].push_back(i);
    MW[C[i]].push_back(i);
    if(R[i]==0)q.push(i);
  }
  const int INF=1<<28;
  vector<int>ansH(H,INF),ansW(W,INF);
  ansH[0]=0;
  while(!q.empty())
  {
    int i=q.front();
    q.pop();
    int r=R[i],c=C[i];
    assert(ansH[r]!=INF||ansW[c]!=INF);
    if(ansH[r]!=INF)
    {
      if(ansW[c]!=INF&&ansW[c]!=X[i]-ansH[r])
      {
        cout<<"NO"<<"\n";
        return 1;
      }
      ansW[c]=X[i]-ansH[r];
    }
    else
    {
      if(ansH[r]!=INF&&ansH[r]!=X[i]-ansW[c])
      {
        cout<<"NO"<<"\n";
        return 1;
      }
      ansH[r]=X[i]-ansW[c];
    }
    for(int j:MH[r])if(j!=i)
    {
      if(ansH[R[j]]==INF||ansW[C[j]]==INF)q.push(j);
    }
    for(int j:MW[c])if(j!=i)
    {
      if(ansH[R[j]]==INF||ansW[C[j]]==INF)q.push(j);
    }
  }
  for(int i=0;i<K-1;i++)if(ansH[R[i]]+ansW[C[i]]!=X[i])
  {
    cout<<"NO"<<"\n";
    return 1;
  }
  for(int i=0;i<H;i++)if(ansH[i]==INF)
  {
    cout<<"NO"<<"\n";
    return 1;
  }
  for(int i=0;i<W;i++)if(ansW[i]==INF)
  {
    cout<<"NO"<<"\n";
    return 1;
  }
  cout<<"YES"<<"\n";
  return 1; 
}


int main(){
  while(solve()){}
}
accuracy: 1
time_ms: 10
memory_kb: 3288
final_rank: 2

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

class UnionFind {
  private:
    vector<int> par; // 各元の親を表す配列
    vector<int> siz; // 素集合のサイズを表す
  public:
    // コンストラクタ
    UnionFind(int sz) : par(sz), siz(sz, 1) {
        for (int i = 0; i < sz; i++)
            par[i] = i; // 親は自分
    }
    int root(int x) { // 根の検索
        while (par[x] != x) {
            x = par[x] = par[par[x]]; // 経路圧縮　xの親の親をxの親とする
        }
        return x;
    }
    bool unite(int x, int y) { // 素集合の併合
        x = root(x), y = root(y);
        if (x == y)
            return false;
        if (siz[x] < siz[y]) { // マージテク
            swap(x, y);
        }
        siz[x] += siz[y];
        par[y] = x;
        return true;
    }
    bool same(int x, int y) { // 連結判定
        return root(x) == root(y);
    }
    int size(int x) { // 素集合のサイズ
        return siz[root(x)];
    }
};

int w, h;

int encode1(int a, int b) { return a * h + b; }
int encode2(int a) { return h * w + a; }
int encode3(int a) { return h * w + w + a; }

void solve() {
    int x[210] = {}, y[210] = {}, n[210] = {};
    cin >> w >> h;
    if (w == 0 && h == 0) {
        exit(0);
    }
    UnionFind uf(200010);
    for (int i = 0; i < w + h - 1; i++) {
        cin >> x[i] >> y[i] >> n[i];
        swap(x[i], y[i]);
        x[i]--, y[i]--;
        uf.unite(encode3(x[i]), encode2(y[i]));
    }
    bool flag = true;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (!uf.same(encode2(j), encode3(i))) {
                flag = false;
            }
        }
    }
    if (flag) {
        cout << "YES" << endl;
        return;
    }
    cout << "NO" << endl;
}

int main() {
    while (1) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4672
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i< (n); i++)
#define mkp(i,j) make_pair((i),(j))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int mod = 998244353;
const int inf = (1<<30);


int main(){
	while(1){
		int w,h; cin>>w>>h;
		if(w == 0) break;
		vector<bitset<(size_t)(100)>> t(w); 
		int k = w+h - 1;
		rep(i,k){
			int x,y,n; cin>>x>>y>>n;
			x--;y--;
			t[x][y] = 1;
		}
		rep(o,100){
		for(int i = 0; i < w-1; i++){
		for(int i2 = i+1; i< w; i++){
			bool c = 0;
			bitset<100> u;
			u = t[i]&t[i2];
			rep(j,h) c |= u[j];
			if(c){
				t[i] |= t[i2];
				t[i2] |= t[i];
			}
		}}}
		
		/*for(int i = w-2; i >= 0; i--){
			bool c = 0;
			bitset<100> u;
			u = t[i]&t[i+1];
			rep(j,h) c |= u[j];
			if(c){
				t[i] |= t[i+1];
				t[i+1] |= t[i];
			}
		}*/
		bool res = 1;
		rep(i,w){
			rep(j,h) res &= t[i][j];
		}

		/*rep(i,w){
			cout<<t[i]<<endl;;
		}*/
		cout<<(res ? "YES" : "NO")<<endl;

	}
}
accuracy: 1
time_ms: 20
memory_kb: 3372
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1e18;

void solve() {

    while (1) {
    ll w,h;
    cin >> w >> h;
    if (w==0) break;

    vector<vector<ll>> table(h, vector<ll>(w,INF));
    vector<ll> hidari(h,INF);
    vector<ll> ue(w,INF);
    ue[0] = 0;

    for (ll i = 0; i < w+h-1; ++i) {
        ll x,y,n;
        cin >> y >> x >> n;
        --x,--y;
        table[x][y] = n;
    }

    while (true) {

        ll ct = 0;
        for (ll i = 0; i < h; ++i) {
            for (ll j = 0; j < w; ++j) {
    
                if (table[i][j] == INF && ue[j]!= INF && hidari[i] != INF) table[i][j] = hidari[i]+ue[j],ct++;
                if (table[i][j]!= INF && ue[j] == INF && hidari[i] !=INF) ue[j] = table[i][j] - hidari[i],ct++;
                if (table[i][j]!= INF && ue[j] != INF && hidari[i] ==INF) hidari[i] = table[i][j] - ue[j],ct++;
            }
        }

        if (ct==0) break;
    }

    bool ans = true;
    for (ll i = 0; i < h; ++i) {
        for (ll j = 0; j < w; ++j) {
            if (table[i][j] == INF) ans = false;
        }
    }


    for (auto m : hidari) if (m==INF) ans = false;
    for (auto m : ue) if (m==INF) ans = false;

    if (ans) cout << "YES" << endl;
    else cout << "NO" << endl;


    }
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3432
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)

int main() {
  while (true) {
    int w, h;
    cin >> w >> h;
    if (w + h == 0) break;
    constexpr int INF = 1e9;
    vector Grid(h, vector<int>(w, INF));
    rep(_, w + h - 1) {
      int x, y, n;
      cin >> x >> y >> n;
      --x, --y;
      Grid[y][x] = n;
    }
    vector<int> row(h, INF), col(w, INF);
    col[0] = 0;
    while (true) {
      bool updated = false;
      rep(i, h) rep(j, w) {
        if (row[i] != INF && Grid[i][j] != INF && col[j] == INF) {
          col[j] = Grid[i][j] - row[i];
          updated = true;
        }
        if (row[i] == INF && Grid[i][j] != INF && col[j] != INF) {
          row[i] = Grid[i][j] - col[j];
          updated = true;
        }
      }
      if (!updated) break;
    }
    bool ok = true;
    rep(i, h) ok &= (row[i] != INF);
    rep(i, w) ok &= (col[i] != INF);
    cout << (ok ? "YES" : "NO") << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3372
final_rank: 3

code_snippet: #include <bits/stdc++.h>

// #include <atcoder/all>
typedef long long int ll;
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define REP(i, n) for (ll i = 0; i < signed(n); i++)
#define EREP(i, n) for (ll i = 1; i <= signed(n); i++)
#define ALL(a) (a).begin(), (a).end()
using namespace std;
// using namespace atcoder;
//  #define EVEL 1
#ifdef EVEL
#define DEB(X) cout << #X << ":" << X << " ";
#define TF(f) f ? cout << "true  " : cout << "false ";
#define END cout << "\n";
#else
#define DEB(X) ;
#define TF(f) ;
#define END ;
#endif
const ll INF = 9e18;
typedef std::pair<ll, ll> P;
struct edge {
  ll to, cost;
};
#define VMAX 100000
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;
}

int main(void) {
  ll N, H, W;
  // vector<ll> A(4);
  while (true) {
    N = 0;
    cin >> W >> H;
    if (W == 0 && H == 0) break;
    set<int> h, w;
    vector<P> A(W + H - 1);
    w.insert(1);
    REP(i, W + H - 1) {
      int x, y, n;
      cin >> x >> y >> n;
      A[i] = {x, y};
      if (x == 1) {
        h.insert(y);
      }
    }
    REP(loop, W + H - 1){
      REP(i, W + H - 1) {
        auto [x, y] = A[i];
        if (w.count(x)) {
          h.insert(y);
        }
        if (h.count(y)) {
          w.insert(x);
        }
      }
    }
    
    cout<<(w.size()==W&&h.size()==H?"YES":"NO")<<endl;
  }
}
accuracy: 1
time_ms: 50
memory_kb: 3368
final_rank: 7