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 with Detailed Comments  
```cpp
#include <bits/stdc++.h>
using namespace std;

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

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

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

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

int n, m;

// Read N and M
void read() {
    cin >> n >> m;
}

// Generate a cyclic n-bit Gray code sequence of length 2^n
vector<int> gray_code(int n) {
    vector<int> res;
    // For each i in [0,2^n), compute the standard reflective Gray code
    for(int i = 0; i < (1 << n); i++) {
        // i ^ (i>>1) is the i-th Gray code; the sequence is cyclic
        res.push_back(i ^ (i >> 1));
    }
    return res;
}

// Solve one test: build and print the matrix
void solve() {
    // Generate row and column Gray codes
    vector<int> gn = gray_code(n);
    vector<int> gm = gray_code(m);
    int R = gn.size();    // 2^N
    int C = gm.size();    // 2^M

    // For each row i
    for(int i = 0; i < R; i++) {
        // For each column j
        for(int j = 0; j < C; j++) {
            // Combine the N-bit row code and M-bit column code
            // Upper bits: gn[i], lower bits: gm[j]
            int label = (gn[i] << m) | gm[j];
            cout << label;
            if (j+1 < C) cout << ' ';
        }
        cout << '\n';
    }
}

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

    // Single test case
    read();
    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)).