#include <array>
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <vector>
std::vector<long long> gemm(const std::vector<int>& a,const std::vector<int>& b,std::size_t m,std::size_t n,std::size_t k) {
    if(m>100 || n>100 || k>100 || a.size()!=m*k || b.size()!=k*n) throw std::invalid_argument("bounded shape");
    constexpr std::size_t tile=2;std::vector<long long> c(m*n,0);
    for(std::size_t row=0;row<m;row+=tile) for(std::size_t col=0;col<n;col+=tile) {
        std::array<long long,4> accum{};
        for(std::size_t base=0;base<k;base+=tile) {
            std::array<int,4> aa{},bb{};
            for(std::size_t r=0;r<tile;++r) for(std::size_t q=0;q<tile;++q) {
                if(row+r<m && base+q<k) aa[r*tile+q]=a[(row+r)*k+base+q];
                if(base+r<k && col+q<n) bb[r*tile+q]=b[(base+r)*n+col+q];
            }
            for(std::size_t r=0;r<tile;++r) for(std::size_t q=0;q<tile;++q)
                for(std::size_t x=0;x<tile;++x) accum[r*tile+q]+=static_cast<long long>(aa[r*tile+x])*bb[x*tile+q];
        }
        for(std::size_t r=0;r<tile;++r) for(std::size_t q=0;q<tile;++q)
            if(row+r<m && col+q<n) c[(row+r)*n+col+q]=accum[r*tile+q];
    }
    return c;
}
int main() {
    int shapes=0;
    for(std::size_t m=0;m<=5;++m) for(std::size_t n=0;n<=5;++n) for(std::size_t k=0;k<=5;++k) {
        std::vector<int>a(m*k),b(k*n);for(std::size_t i=0;i<a.size();++i)a[i]=static_cast<int>(i%7)-3;
        for(std::size_t i=0;i<b.size();++i)b[i]=static_cast<int>(i%5)-2;
        auto c=gemm(a,b,m,n,k);
        for(std::size_t r=0;r<m;++r) for(std::size_t col=0;col<n;++col) {
            long long expected=0;for(std::size_t x=0;x<k;++x)expected+=static_cast<long long>(a[r*k+x])*b[x*n+col];
            if(c[r*n+col]!=expected) throw std::runtime_error("oracle");
        }
        ++shapes;
    }
    const auto c=gemm({1,2,3,4,5,6},{7,8,9,10,11,12},2,2,3);
    if(c!=std::vector<long long>{58,64,139,154}) throw std::runtime_error("example");
    std::cout<<"C="<<c[0]<<','<<c[1]<<';'<<c[2]<<','<<c[3]<<" shapes="<<shapes<<'\n';
}
