#include <iostream>
#include <vector>
#include <cassert>
 
void permute_impl(size_t width, std::vector<std::vector<int>> const &mat,
                  size_t column, std::vector<int> &prefix) {
  if (column < width) {
    for (auto &row : mat) {
      prefix.push_back(row[column]);
      permute_impl(width, mat, column + 1, prefix);
      prefix.pop_back();
    }
  } else {
    for (auto i : prefix)
      std::cout << i << ' ';
    std::cout << '\n';
  }
}
 
void permute(std::vector<std::vector<int>> const &mat) {
  if (mat.empty())
    return;
  std::vector<int> prefix;
  size_t N = mat[0].size();
  // assert that all rows are the same size
  for (auto &row : mat)
    assert(row.size() == N);
  permute_impl(N, mat, 0, prefix);
}
 
int main() {
  std::vector<std::vector<int>> mat = {
      {0, 1, 2}, {3, 4, 5}, {6, 7, 8},
  };
 
  permute(mat);
}
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8Y2Fzc2VydD4KCnZvaWQgcGVybXV0ZV9pbXBsKHNpemVfdCB3aWR0aCwgc3RkOjp2ZWN0b3I8c3RkOjp2ZWN0b3I8aW50Pj4gY29uc3QgJm1hdCwKICAgICAgICAgICAgICAgICAgc2l6ZV90IGNvbHVtbiwgc3RkOjp2ZWN0b3I8aW50PiAmcHJlZml4KSB7CiAgaWYgKGNvbHVtbiA8IHdpZHRoKSB7CiAgICBmb3IgKGF1dG8gJnJvdyA6IG1hdCkgewogICAgICBwcmVmaXgucHVzaF9iYWNrKHJvd1tjb2x1bW5dKTsKICAgICAgcGVybXV0ZV9pbXBsKHdpZHRoLCBtYXQsIGNvbHVtbiArIDEsIHByZWZpeCk7CiAgICAgIHByZWZpeC5wb3BfYmFjaygpOwogICAgfQogIH0gZWxzZSB7CiAgICBmb3IgKGF1dG8gaSA6IHByZWZpeCkKICAgICAgc3RkOjpjb3V0IDw8IGkgPDwgJyAnOwogICAgc3RkOjpjb3V0IDw8ICdcbic7CiAgfQp9Cgp2b2lkIHBlcm11dGUoc3RkOjp2ZWN0b3I8c3RkOjp2ZWN0b3I8aW50Pj4gY29uc3QgJm1hdCkgewogIGlmIChtYXQuZW1wdHkoKSkKICAgIHJldHVybjsKICBzdGQ6OnZlY3RvcjxpbnQ+IHByZWZpeDsKICBzaXplX3QgTiA9IG1hdFswXS5zaXplKCk7CiAgLy8gYXNzZXJ0IHRoYXQgYWxsIHJvd3MgYXJlIHRoZSBzYW1lIHNpemUKICBmb3IgKGF1dG8gJnJvdyA6IG1hdCkKICAgIGFzc2VydChyb3cuc2l6ZSgpID09IE4pOwogIHBlcm11dGVfaW1wbChOLCBtYXQsIDAsIHByZWZpeCk7Cn0KCmludCBtYWluKCkgewogIHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPGludD4+IG1hdCA9IHsKICAgICAgezAsIDEsIDJ9LCB7MywgNCwgNX0sIHs2LCA3LCA4fSwKICB9OwoKICBwZXJtdXRlKG1hdCk7Cn0=