#include <iostream>
#include <valarray>

template<typename T>
class Matrix {
    std::valarray<T> data;
    size_t columns;
 public:
    Matrix(size_t rows, size_t columns)
    : data(rows*columns), columns(columns) {}

    T operator()(size_t row, size_t col) const
    {
        return data[row + columns*col];
    }

    T& operator()(size_t row, size_t col)
    {
        return data[row + columns*col];
    }

    Matrix& operator+=(const Matrix& other)
    {
        data += other.data;
        return *this;
    }
};

template<typename T>
Matrix<T> operator+(Matrix<T> lhs, const Matrix<T>& rhs)
{
    return lhs += rhs;
}

int main()
{
    Matrix<int> m1(2,2);
    m1(0,0) = 1; m1(0,1) = 2;
    m1(1,0) = 3; m1(1,1) = 4;

    Matrix<int> m2 = m1;
    Matrix<int> m3 = m1 + m2;

    std::cout << m3(0,0) << ' ' << m3(0,1) << '\n'
              << m3(1,0) << ' ' << m3(1,1) << '\n';
}
