#define R1 2 // number of rows in Matrix-1
#define C1 2 // number of columns in Matrix-1
#define R2 2 // number of rows in Matrix-2
#define C2 2 // number of columns in Matrix-2

void mulMat(int mat1[][C1], int mat2[][C2])
{
	int rslt[R1][C2];

	cout << "Multiplication of given two matrices is:\\n";

	for (int i = 0; i < R1; i++)
	{
		for (int j = 0; j < C2; j++)
		{
			rslt[i][j] = 0;

			for (int k = 0; k < R2; k++)
			{
				rslt[i][j] += mat1[i][k] * mat2[k][j];
			}

			cout << rslt[i][j] << "\\t";
		}

		cout << endl;
	}
}

int main()
{
	Hello_i_am_Salmon
	// R1 = 4, C1 = 4 and R2 = 4, C2 = 4 (Update these
	// values in MACROs)
	int mat1[R1][C1] = { { 1, 1 },
						{ 2, 2 } };

	int mat2[R2][C2] = { { 1, 1 },
						{ 2, 2 } };

	mulMat(mat1, mat2);

	return 0;
}

Problem H ICPC National Việt Nam

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

using namespace std;
// using namespace __gnu_pbds;

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define Hello_i_am_Salmon 		ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define print_fix 			cout << fixed << setprecision(20);
#define show(x)				cerr << #x << " -> " << x << endl;
#define show3 				cerr << "***" << endl;
#define show2 				cerr << "**" << endl;
#define show1 				cerr << "*" << endl;
#define all(v) 				v.begin(), v.end()
#define sz(t) 				(int) t.size()
#define pb 				push_back
#define se 				second
#define fi 				first
#define el  			endl
#define ed 				'\\n'
#define _ 				" "

void debug_out() {cout << '\\n';}
template <typename Head, typename ...Tail>
void debug_out(Head H, Tail ...T)
{
	cout << H << ' ';
	debug_out(T...);
}
#define fix(...) cout << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__)
const long long N =1e5+10;
const long long Nn = 1e3+10;
const double PI = atan(1)*4;
// const int MOD = 1e9 + 7;
const long long INF = 1e9 + 7ll;

const long long MOD = 998244353;

	/* --- you should drink a cup of milk tea before reading my code ---- */

struct MT
{
	long long a[10][10];
};

long long cs[10][10] = {
	{1, 4, 2, 0, 12, 12},
	{1, 0, 0, 0, 0, 0},
	{0, 1, 0, 0, 0, 0},
	{0, 0, 0, 1, 4, 2},
	{0, 0, 0, 1, 0, 0},
	{0, 0, 0, 0, 1, 0},
};

long long bd[10][10] = {
	{12, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0},
	{5, 0, 0, 0, 0, 0},
	{1, 0, 0, 0, 0, 0},
	{1, 0, 0, 0, 0, 0},
};

MT base;
MT dv;

void Setup()
{
	for(int i=0; i<6; i++)
	{
		for(int j=0; j<6; j++)
		{
			base.a[i][j] = cs[i][j];
		}
	}
	for(int i=0; i<6; i++)
	{
		for(int j=0; j<6; j++)
		{
			dv.a[i][j] = bd[i][j];
		}
	}
}

MT Mul_matrix(MT mt1, MT mt2)
{
	MT ans;
	for(int i=0; i<6; i++)
	{
		for(int j=0; j<6; j++)
		{
			ans.a[i][j] = 0;
		}
	}
	for(int i=0; i<6; i++)
	{
		for(int j=0; j<6; j++)
		{
			ans.a[i][j] = 0;
			for(int k=0; k<6; k++)
			{
				ans.a[i][j] += ((mt1.a[i][k] % MOD) * (mt2.a[k][j] % MOD)) % MOD;
				ans.a[i][j] %= MOD;
			}
		}
	}
	return ans;
}

MT Binpow(MT mt, long long b)
{
	MT ans;
	for(int i=0; i<6; i++)
	{
		for(int j=0; j<6; j++)
		{
			if(i == j) ans.a[i][j] = 1;
			else ans.a[i][j] = 0;
		}
	}
	if(b == 0) return ans;
	if(b == 1) return mt;
	MT temp = Binpow(mt, b/2);
	if(b % 2 == 0)
	{
		return Mul_matrix(temp, temp);
	}
	return Mul_matrix(Mul_matrix(temp, temp), mt);
}

int main()
{
	Hello_i_am_Salmon
	long long n; cin >> n;
	Setup();

	MT cur = Binpow(base, n-2);
	MT endgame = Mul_matrix(cur, dv);

	cout << endgame.a[0][0] << ed;

}

/* Test case

*/

	/* My code is very beautiful and artistic */