#ifdef NACHIA #define _GLIBCXX_DEBUG #else // disable assert #define NDEBUG #endif #include #include #include #include using namespace std; using ll = long long; const ll INF = 1ll << 60; #define REP(i,n) for(ll i=0; i using V = vector; template void chmax(A& l, const B& r){ if(l < r) l = r; } template void chmin(A& l, const B& r){ if(r < l) l = r; } V seq(ll n){ if(n == 1) return {0}; auto A = seq(n / 2); V ans; REP(i,A.size()){ ans.push_back(A[i] * 2 + (0 ^ (i%2))); ans.push_back(A[i] * 2 + (1 ^ (i%2))); } return ans; } V row(ll N){ V ans; ll n = 1; while(n*2 <= N) n *= 2; auto buf = seq(n); REP(i,buf.size()) if(i%2 == 0){ ans.push_back(buf[i]); if(buf[i] + n < N){ ans.push_back(buf[i] + n); ans.push_back(buf[i+1] + n); } ans.push_back(buf[i+1]); } return ans; } struct Node { ll val = INF; V A, B; }; bool operator<(const Node& l, const Node& r){ return l.val < r.val; } Node do_dp(ll A, ll B){ ll a = 0; while((1ll << a) <= A) a++; ll b = 0; while((1ll << b) <= B) b++; V> dp(a+1, V(b+1)); dp[0][0].val = 0; REP(i,a+1) REP(j,b+1){ if(i){ Node nx = dp[i-1][j]; nx.A.push_back(1ll << (i+j-1)); if(A & (1ll << (i-1))) nx.val += (1ll << (i+j-1)); chmin(dp[i][j], nx); } if(j){ Node nx = dp[i][j-1]; nx.B.push_back(1ll << (i+j-1)); if(B & (1ll << (j-1))) nx.val += (1ll << (i+j-1)); chmin(dp[i][j], nx); } } return dp[a][b]; } void testcase(){ ll H, W; cin >> H >> W; if(H%2 != 0 || W%2 != 0){ cout << "-1\n"; return; } auto rows = row(H); auto cols = row(W); auto mp = do_dp(H-1, W-1); REP(y,H){ REP(x,W){ if(x) cout << " "; ll val = 0; REP(a,mp.A.size()) val += (rows[y] >> a) % 2 * mp.A[a]; REP(a,mp.B.size()) val += (cols[x] >> a) % 2 * mp.B[a]; cout << val; } cout << "\n"; } } int main(){ cin.tie(0)->sync_with_stdio(0); testcase(); return 0; }