Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Matrix Multiplication

Write a program which reads a $n \times m$ matrix $A$ and a $m \times l$ matrix $B$, and prints their product, a $n \times l$ matrix $C$. An element of matrix $C$ is obtained by the following formula:

\[
c_{ij} = \sum_{k=1}^m a_{ik}b_{kj}
\]

where $a_{ij}$, $b_{ij}$ and $c_{ij}$ are elements of $A$, $B$ and $C$ respectively.

Input

In the first line, three integers $n$, $m$ and $l$ are given separated by space characters

In the following lines, the $n \times m$ matrix $A$ and the $m \times l$ matrix $B$ are given.

Output

Print elements of the $n \times l$ matrix $C$ ($c_{ij}$). Print a single space character between adjacent elements.

Constraints

$1 \leq n, m, l \leq 100$

$0 \leq a_{ij}, b_{ij} \leq 10000$

Sample Input

3 2 3
1 2
0 3
4 5
1 2 1
0 3 2

Sample Output

1 8 5
0 9 6
4 23 14

Note

      解説

Solution in C# (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Prac
{
  class Matrix
    {
        public int row { get; private set; }
        public int col { get; private set; }
        private int[][] content { get; set; }

        /// <summary>
        /// 指定された行と列の数を持つ空の行列型のインスタンスを生成します
        /// </summary>
        /// <param name="row">行列の行数</param>
        /// <param name="col">行列の列数</param>
        public Matrix(int row, int col)
        {
            this.row = row;
            this.col = col;
            content = new int[row][];
            for (var i = 0; i < row; i++)
            {
                content[i] = Enumerable.Repeat(0, col).ToArray();
            }
        }
        /// <summary>
        /// 与えられた行ベクトルからなる行列型を作成します
        /// </summary>
        /// <param name="RowVector">行ベクトル</param>
        public Matrix(params int[][] RowVector)
        {
            this.row = RowVector.Length;
            this.col = RowVector[0].Length;
            content = new int[row][];
            for (var i = 0; i < RowVector.Length; i++)
            {
                content[i] = RowVector[i];
            }

        }

        /// <summary>
        /// 行ベクトルのインデクサ
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public int[] this[int r]
        {
            set
            {
                content[r - 1] = value;
            }
            get
            {
                return content[r - 1];
            }
        }
        public int this[int r, int c]
        {
            set
            {
                content[r - 1][c - 1] = value;
            }
            get
            {
                return content[r - 1][c - 1];
            }
        }

        public static Matrix operator +(Matrix A, Matrix B)
        {
            if ((A.row != B.row) | (A.col != B.row))
                throw new InvalidOperationException("行列の大きさが異なります");
            var C = new Matrix(A.row, B.col);
            for (var i = 0; i < A.row; i++)
            {
                //C[i + 1] = A[i + 1].Zip(B[i + 1], (x, y) => x + y).ToArray();
            }
            return C;

        }
        public static Matrix operator *(Matrix A, Matrix B)
        {
            if (A.col != B.row)
                throw new InvalidOperationException("左項の列数と右項の行数が一致しません");
            var C = new Matrix(A.row, B.col);
            var temp = 0;
            for (var i = 1; i <= A.row; i++)
            {
                for (var j = 1; j <= B.col; j++)
                {
                    for (var k = 1; k <= B.row; k++)
                    {
                        temp += A[i, k] * B[k, j];
                    }
                    C[i, j] = temp;
                    temp = 0;

                }
            }
            return C;
        }
        public static Matrix operator -(Matrix A, Matrix B)
        {
            if ((A.row != B.row) | (A.col != B.row))
                throw new InvalidOperationException("行列の大きさが異なります");
            var C = new Matrix(A.row, B.col);
            for (var i = 0; i < A.row; i++)
            {
               // C[i + 1] = A[i + 1].Zip(B[i + 1], (x, y) => x - y).ToArray();
            }
            return C;

        }
        public void WriteMatrix()
        {
            var isFirst = true;
            for (var i = 1; i <= col; i++)
            {
                foreach (var aij in this[i])
                {
                    if (!isFirst)
                    {
                        Console.Write(" ");
                    }
                    else
                    {
                        isFirst = false;
                    }
                    Console.Write(aij);
                }
                Console.WriteLine();
                isFirst = true;
            }
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            var temp = new int[3];
            temp = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            
            var n = temp[0];
            var m = temp[1];
            var p = temp[2];

            var A = new Matrix(n, m);
            var B = new Matrix(m, p);
            for (var i = 1; i <= n; i++)
            {
                A[i] = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            } 
            for (var i = 1; i <= m; i++)
            {
                B[i] = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            }
            (A * B).WriteMatrix();
        }
    
    }
}