#include<algorithm>
#include<atomic>
#include<array>
#include<chrono>
#include<condition_variable>
#include<cstddef>
#include<ctime>
#include<fstream>
#include<future>
#include<iostream>
#include<iterator>
#include<limits>
#include<memory>
#include<mutex>
#include<numeric>
#include<sstream>
#include<string>
#include<vector>
using namespace std;

template<class T>
class Middle
{
public:
	using size_type=typename vector<T>::size_type;
private:
	vector<T> *vec_;
	const size_type column_;
	const size_type index_;
public:
	Middle(vector<T> &vec,const size_type column,const size_type index) noexcept
		:vec_{addressof(vec)},column_{column},index_{index}{}
	Middle(const Middle &)=default;
	operator T&()
	{
		return vec_->operator[](index_);
	}
	Middle& operator=(const Middle &)=delete;
	T& operator[](const size_t i)
	{
		return vec_->operator[](index_*column_+i);
	}
};

template<class T>
class Const_Middle
{
public:
	using size_type=typename vector<T>::size_type;
private:
	const vector<T> *vec_;
	const size_type column_;
	const size_type index_;
public:
	Const_Middle(const vector<T> &vec,const size_type column,const size_type index) noexcept
		:vec_{addressof(vec)},column_{column},index_{index}{}
	Const_Middle(const Const_Middle &)=default;
	operator const T&()
	{
		return vec_->operator[](index_);
	}
	Const_Middle& operator=(const Const_Middle &)=delete;
	const T& operator[](const size_t i)
	{
		return vec_->operator[](index_*column_+i);
	}
};

template<class T>
class Test
{
public:
	using size_type=typename vector<T>::size_type;
	vector<T> vec_;
private:
	const size_type column_;
public:
	Test(const size_type row,const size_type column)
		:column_{column},vec_(row*column){}
	Middle<T> operator[](const size_t i)
	{
		return Middle<T>{vec_,column_,i};
	}
	Const_Middle<T> operator[](const size_t i) const
	{
		return Const_Middle<T>{vec_,column_,i};
	}
};

int main()
{
	Test<int> test(3,4);
	iota(begin(test.vec_),end(test.vec_),0);
	const Test<int> &test2{test};
	cout<<test[6]<<endl;
	cout<<test[1][1]<<endl;
	cout<<test[2][3]<<endl;
	cout<<test2[6]<<endl;
	cout<<test2[1][1]<<endl;
	cout<<test2[2][3]<<endl;
}