#include <algorithm>
#include <iostream>

struct ItStep {
  int cell;
  size_t x;
  size_t y;
  bool row;
};

class MatrixIterator1 {
  public:
    class iterator
    {
    public:
      Matrix &mat;
      size_t x = 0;
      size_t y = 0;

      using iterator_category = std::input_iterator_tag;
      using value_type = ItStep;
      using difference_type = ItStep;
      using pointer = ItStep *;
      using reference = ItStep;

      explicit iterator(Matrix &_mat)
        : mat(_mat) {}

      iterator& operator++() {
        x++;
        if(x < mat[0].size()) {
          return *this;
        } else {
          x = 0;
          y++;
          return *this;
        }
      }

      iterator operator++(int) {
        iterator retval = *this;
        ++(*this);
        return retval;
      }

      bool operator==(iterator other) const {
        return x == other.x && y == other.y;
      }

      reference operator*() const {
        return {
          .cell = mat[y][x],
          .x = x,
          .y = y,
          .row = x >= mat[0].size() - 1
        };
      }
  };

  Matrix &mat;

  MatrixIterator1(Matrix &mat_) :
    mat(mat_)
  {
  }

  iterator begin() {
    return iterator(mat);
  }

  iterator end() {
    iterator it(mat);
    it.y = mat.size();
    it.x = 0;
    return it;
  }
};
