#include <iostream>
#include <iomanip>

using namespace std;

class Matrix
{
    size_t rows, cols;
    int **data;
    void swap(Matrix&M)
    {
        std::swap(data,M.data);
        std::swap(rows,M.rows);
        std::swap(cols,M.cols);
    }
public:
    Matrix(size_t rows, size_t cols):rows(rows),cols(cols)
    {
        data = new int *[rows];
        for(size_t i = 0; i < rows; i++)
            data[i] = new int[cols];
    }
    ~Matrix()
    {
        for (size_t i = 0; i < rows; i++)
            delete[] data[i];
        delete[] data;
    }

    Matrix(const Matrix&M):Matrix(M.rows,M.cols)
    {
        for(size_t i = 0; i < rows; i++)
        for(size_t j = 0; j < cols; j++)
            data[i][j] = M.data[i][j];
    }

    Matrix& operator = (const Matrix& M)
    {
        Matrix tmp(M);
        swap(tmp);
        return *this;
    }

    friend ostream& operator<<(ostream&os, const Matrix& M);
    friend istream& operator>>(istream&is,       Matrix& M);

    Matrix transpose()
    {
        Matrix temp(cols,rows);
        for(size_t i = 0; i < rows; i++)
            for(size_t j = 0; j < cols; j++)
                temp.data[j][i] = data[i][j];
        return temp;
    }
        
};


ostream& operator<<(ostream&os, const Matrix& M)
{
    for(size_t i = 0; i < M.rows; i++)
    {
        for(size_t j = 0; j < M.cols; j++)
        {
            os << M.data[i][j]<< " ";
        }
        os << "\n";
    }
    return os;
}

istream& operator>>(istream&is, Matrix& M)
{
    for(size_t i = 0; i < M.rows; i++)
    {
        for(size_t j = 0; j < M.cols; j++)
        {
            cout << "Matrix[" << i << "][" << j << "] = ";
            is >> M.data[i][j];
        }
    }
    return is;
}

int main()
{
    int num_of_cols, num_of_rows;
    cout <<"input the num of cols and rows"<<endl;
    cin >> num_of_rows >> num_of_cols;
    
    Matrix ob1(num_of_rows, num_of_cols);
    cin >> ob1;
    cout << "\n\n" << ob1 << "\n\n";

    Matrix ob2 = ob1.transpose();

    cout << ob2 << "\n\n";
}

