1. Concise Problem Statement  
Given integers N and M (N, M > 0, N+M ≤ 20), construct a 2^N-by-2^M matrix that contains all integers from 0 to 2^(N+M)–1 exactly once, such that any two orthogonally adjacent cells (including wrap-around at the borders) hold numbers whose binary representations differ in exactly one bit.

2. Detailed Editorial  
• Goal: Label the nodes of a toroidal grid (2^N rows × 2^M columns) with a Hamiltonian cycle on the (N+M)-cube, so that moving to any neighbor flips exactly one bit in the label.  
• Key Observation: The direct product of two cycles (one of length 2^N, one of length 2^M) is a toroidal grid. A cyclic Gray code of length 2^N is a Hamiltonian cycle on the N-cube; similarly for length 2^M on the M-cube. The Cartesian product of these two cycles is a Hamiltonian cycle on the (N+M)-cube—exactly what we need for the torus.  
• Construction Steps:  
  1. Generate a cyclic Gray code array `G_N` of length 2^N: G_N[i] = i ^ (i>>1). Consecutive entries differ in one bit, and G_N[0] and G_N[2^N–1] also differ in one bit.  
  2. Similarly generate `G_M` for length 2^M.  
  3. For each row index i in [0,2^N) and column index j in [0,2^M), assign the matrix cell (i,j) the integer `(G_N[i] << M) | G_M[j]`.  
• Correctness:  
  – Horizontal neighbors (i,j)→(i,j+1) only change the lower M bits from G_M[j] to G_M[j+1], which differ in one bit by Gray code property. Wrap-around j=2^M–1→0 also flips one bit.  
  – Vertical neighbors (i,j)→(i+1,j) only change the upper N bits from G_N[i] to G_N[i+1], which differ in one bit, including wrap-around.  
  – All labels are distinct and cover [0,2^(N+M)–1], since the map (x,y)→(x<<M)|y is a bijection between (G_N × G_M) and all (N+M)-bit values.  
• Complexity: O(2^(N+M)) time and output size, feasible for N+M≤20.

3. C++ Solution
```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n, m;

void read() { cin >> n >> m; }

vector<int> gray_code(int bits) {
    vector<int> res;
    for(int i = 0; i < (1 << bits); i++) {
        res.push_back(i ^ (i >> 1));
    }

    return res;
}

void solve() {
    // We want a 2^N x 2^M cyclic Gray arrangement of 0..2^(N+M)-1 where adjacent
    // cells differ in one bit. Take the standard reflected Gray code over N bits
    // for the rows and over M bits for the columns. Each Gray sequence is cyclic
    // (its first and last entries also differ in one bit), so wrapping the grid
    // is fine. The cell at row i, column j gets the high N bits from the row's
    // Gray value and the low M bits from the column's: (gn[i] << M) | gm[j].
    // Horizontal neighbours change only the column part by one bit and vertical
    // neighbours only the row part, so any two adjacent cells differ in exactly
    // one bit.

    vector<int> gn = gray_code(n), gm = gray_code(m);
    for(int i = 0; i < (int)gn.size(); i++) {
        for(int j = 0; j < (int)gm.size(); j++) {
            cout << (gn[i] << m) + gm[j] << ' ';
        }

        cout << '\n';
    }
}

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

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

4. Python Solution with Detailed Comments  
```python
import sys

def gray_code(n):
    """
    Generate a cyclic n-bit Gray code sequence of length 2^n.
    The i-th Gray code is i ^ (i >> 1).
    """
    return [i ^ (i >> 1) for i in range(1 << n)]

def main():
    data = sys.stdin.read().strip().split()
    N, M = map(int, data[:2])

    # Generate Gray codes for rows (N bits) and columns (M bits)
    G_N = gray_code(N)
    G_M = gray_code(M)

    # For each row index i and column index j, combine codes
    # upper N bits = G_N[i], lower M bits = G_M[j]
    # label = (G_N[i] << M) | G_M[j]
    out_lines = []
    for gn in G_N:
        row = [(gn << M) | gm for gm in G_M]
        # join row labels by spaces
        out_lines.append(" ".join(map(str, row)))

    # Print the matrix
    sys.stdout.write("\n".join(out_lines))

if __name__ == "__main__":
    main()
```

5. Compressed Editorial  
Use two independent cyclic Gray codes: one of length 2^N for rows, one of length 2^M for columns. Label cell (i,j) by concatenating the N‐bit Gray code of i (as higher bits) with the M‐bit Gray code of j (as lower bits). Horizontal and vertical neighbors differ in exactly one bit by the Gray‐code property, and wrap-around edges also flip one bit. This runs in O(2^(N+M)).