#include <iostream>
using namespace std;
template <typename T>
class Matrix {
protected:
T** a;
int size1;
int size2;
public:
Matrix(int n, int m) {
while (n <= 0 && m <= 0) {
cout << "Введіть інший розмір";
cin >> n >> m;
}
size1 = n;
size2 = m;
a = new T* [n];
for (int i = 0; i < n; i++) {
a[i] = new T[m];
}
}
Matrix() : size1(1), size2(1) {
a = new T* [1];
a[0] = new T[1];
}
~Matrix() {
for (int i = 0; i < size1; i++) {
delete a[i];
}
delete[] a;
}
T* operator[](const int i) { return a[i]; }
// Перевантаження +
Matrix operator+(const Matrix& left) const {
Matrix result(size1, size2);
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
result.a[i][j] = a[i][j] + left.a[i][j];
}
}
return result;
}
// Перевантаження -
Matrix operator-(const Matrix& left) const {
Matrix result(size1, size2);
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
result.a[i][j] = a[i][j] - left.a[i][j];
}
}
return result;
}
// Перевантаження *
Matrix operator*(const Matrix& right) const {
Matrix result(size1, right.size2);
for (int i = 0; i < size1; i++) {
for (int j = 0; j < right.size2; j++) {
result.a[i][j] = 0;
for (int k = 0; k < size2; k++) {
result.a[i][j] += a[i][k] * right.a[k][j];
}
}
}
return result;
}
friend ostream& operator<<(ostream& x, const Matrix& a) {
for (int i = 0; i < a.size1; i++) {
for (int j = 0; j < a.size2; j++) {
x << a.a[i][j] << " ";
}
x << endl;
}
return x;
}
friend istream& operator>>(istream& is, const Matrix& a) {
for (int i = 0; i < a.size1; i++) {
for (int j = 0; j < a.size2; j++) {
is >> a.a[i][j];
}
}
return is;
}
};
template<typename T>
class SquareMatrix : public Matrix<T> {
public:
SquareMatrix(int size) : Matrix<T>(size, size) {}
T trace() {
T sum = 0;
for (int i = 0; i < this->size1; i++) {
sum += this->a[i][i];
}
return sum;
}
};
int main(void)
{
Matrix<double> a(4, 3);
cin >> a;
Matrix<double> b(3, 4);
cin >> b;
Matrix<double> c = a * b;
cout << c;
return 0;
}