#include using namespace std; using ll=long long; const ll ILL=2167167167167167167; const int INF=2100000000; #define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++) #define all(p) p.begin(),p.end() template using pq_ = priority_queue, greater>; template int LB(vector &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();} template int UB(vector &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();} template bool chmin(T &a,T b){if(b bool chmax(T &a,T b){if(a void So(vector &v) {sort(v.begin(),v.end());} template void Sore(vector &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});} bool yneos(bool a,bool upp=false){if(a){cout<<(upp?"YES\n":"Yes\n");}else{cout<<(upp?"NO\n":"No\n");}return a;} template void vec_out(vector &p,int ty=0){ if(ty==2){cout<<'{';for(int i=0;i<(int)p.size();i++){if(i){cout<<",";}cout<<'"'< T vec_min(vector &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;} template T vec_max(vector &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;} template T vec_sum(vector &a){T ans=T(0);for(auto &x:a) ans+=x;return ans;} int pop_count(long long a){int res=0;while(a){res+=(int)(a&1),a>>=1;}return res;} template T square(T a){return a * a;} void solve(); // DEAR MYSTERIES / TOMOO int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t = 1; // cin >> t; rep(i, 0, t) solve(); } void solve(){ int H, W; cin >> H >> W; int h = H, w = W; rep(rp, 2, 200'200) { int ch = 0, cw = 0; while (h % rp == 0) { h /= rp, ch++; } while (w % rp == 0) { w /= rp, cw++; } if (ch > cw) { while (ch) { ch--, h *= rp; } } else { while (cw) { cw--, w *= rp; } } } auto f = [&](int v) -> vector { vector p(v); rep(i, 0, v) p[i] = i; sort(all(p), [&](int l, int r) { return gcd(p[l], v) < gcd(p[r], v); }); vector inv(v); rep(i, 0, v) inv[p[i]] = i; return inv; }; auto X = f(h); auto Y = f(w); vector ans(h, vector(w)); rep(rp, 1, h * w + 1) { ans[X[rp % h]][Y[rp % w]] = rp; } rep(i, 0, H){ rep(j, 0, W) { if (j) cout << " "; cout << ans[i % h][j % w] + h * w * ((i / h) * (W / w) + j / w); } cout << "\n"; } } /* * ax = b (mod M) * or * a = by (mod M) とはなんなんだろうか? * g(a) = gcd(a, M) としたときに、 * 隣接しているものについて、 * 一方が一方の約数になっているものと言える * H, W が互いに素なら簡単? * A[i][j] = i (mod H) * A[i][j] = j (mod W) * いやだめか * でも、H = 1 で解いた解を p[i] として、適当に   * そうでないとき、 * 例えば、2p * 2q のときはどうするか * A[i][j] = i (mod 2p) * A[i][j] = j (mod q) * p, q がどっちも奇数ならこれで良い気もする */