#include <bits/stdc++.h>
struct mat {
  size_t n, m;
  mat(size_t n, size_t m) : n(n), m(m) {}
  inline bool flipped() const { return n > m; }
  inline size_t l() const { return this->flipped() ? this->n : this->m; }
  inline size_t s() const { return this->flipped() ? this->m : this->n; }
  inline size_t get(size_t y, size_t x) const { return y * this->l() + x + 1; }
  inline size_t mapflip(size_t src) const {
    src -= 1;
    size_t dey = src / this->l(), dex = src % this->l();
    return (dex * this->s() + dey + 1);
  }
  inline bool black(size_t y, size_t x) const {
    if (!(y % 2)) {
      return !(x % 2);
    } else {
      return x % 2;
    }
  }
  inline std::vector<size_t> invalids(size_t src) const {
    std::vector<size_t> ret;
    src -= 1;
    size_t dey = src / this->l(), dex = src % this->l();
    if (dey) {
      ret.emplace_back(this->get(dey - 1, dex));
    }
    if (dex) {
      ret.emplace_back(this->get(dey, dex - 1));
    }
    if (dey < this->s() - 1) {
      ret.emplace_back(this->get(dey + 1, dex));
    }
    if (dex < this->l() - 1) {
      ret.emplace_back(this->get(dey, dex + 1));
    }
    return ret;
  }
};
bool valid(const mat& src, const std::vector<std::vector<uint32_t>>& data) {
  for (size_t i = 0; i < src.s(); i++) {
    for (size_t j = 0; j < src.l(); j++) {
      bool invalid = false;
      const auto v = src.invalids(data[i][j]);
      if (i) {
        invalid =
            invalid || std::find(v.begin(), v.end(), data[i - 1][j]) != v.end();
      }
      if (j) {
        invalid =
            invalid || std::find(v.begin(), v.end(), data[i][j - 1]) != v.end();
      }
      if (i < src.s() - 1) {
        invalid =
            invalid || std::find(v.begin(), v.end(), data[i + 1][j]) != v.end();
      }
      if (j < src.l() - 1) {
        invalid =
            invalid || std::find(v.begin(), v.end(), data[i][j + 1]) != v.end();
      }
      if (invalid) {
        return false;
      }
    }
  }
  return true;
}
bool do_backtrack(const mat& src, std::vector<std::vector<uint32_t>>& data,
                  const std::set<uint32_t>& nums, size_t i) {
  if (i >= src.l() * src.s()) {
    return valid(src, data);
  }
  for (const auto n : nums) {
    auto newnums = nums;
    newnums.erase(n);
    data[i / src.l()][i % src.l()] = n + 1;
    if (do_backtrack(src, data, newnums, i + 1)) {
      return true;
    }
  }
  return false;
}
bool backtrack(const mat& src, std::vector<std::vector<uint32_t>>& data) {
  std::set<uint32_t> nums;
  for (size_t i = 0; i < src.l() * src.s(); i++) {
    nums.emplace(i);
  }
  return do_backtrack(src, data, nums, 0);
}
int main() {
  size_t n = 0, m = 0;
  std::cin >> n >> m;
  mat src(n, m);
  std::vector<std::vector<uint32_t>> ret(src.s(),
                                         std::vector<uint32_t>(src.l(), 0));
  for (size_t i = 0; i < src.s(); i++) {
    size_t fillcur = 0;
    const ssize_t fillblack_begin = i % 2;
    const ssize_t fillblack_end = (src.l() - (1 - i % 2)) / 2 * 2 - i % 2;
    const ssize_t fillwhite_begin = 1 - i % 2;
    const ssize_t fillwhite_end = (src.l() - i % 2) / 2 * 2 - (1 - i % 2);
    bool inc = std::abs(fillblack_end - fillwhite_begin) > 1;
    ssize_t fillblack = inc ? fillblack_begin : fillblack_end;
    while (true) {
      if (inc) {
        if (fillblack > fillblack_end) {
          break;
        }
      } else {
        if (fillblack < fillblack_begin) {
          break;
        }
      }
      ret[i][fillcur] = src.get(i, fillblack);
      fillcur += 1;
      if (inc) {
        fillblack += 2;
      } else {
        fillblack -= 2;
      }
    }
    ssize_t fillwhite = inc ? fillwhite_begin : fillwhite_end;
    while (true) {
      if (inc) {
        if (fillwhite > fillwhite_end) {
          break;
        }
      } else {
        if (fillwhite < fillwhite_begin) {
          break;
        }
      }
      ret[i][fillcur] = src.get(i, fillwhite);
      fillcur += 1;
      if (inc) {
        fillwhite += 2;
      } else {
        fillwhite -= 2;
      }
    }
  }
  if (!valid(src, ret)) {
    if (src.l() * src.s() <= 12 && backtrack(src, ret)) {
    } else {
      std::cout << "NO" << '\n';
      return 0;
    }
  }
  std::cout << "YES" << '\n';
  if (!src.flipped()) {
    for (size_t i = 0; i < src.s(); i++) {
      for (size_t j = 0; j < src.l(); j++) {
        std::cout << ret[i][j] << ' ';
      }
      std::cout << '\n';
    }
  } else {
    for (size_t j = 0; j < src.l(); j++) {
      for (size_t i = 0; i < src.s(); i++) {
        std::cout << src.mapflip(ret[i][j]) << ' ';
      }
      std::cout << '\n';
    }
  }
  return 0;
}
