#include <iostream>
static constexpr auto MOD = 1000000007LL;
inline /*hint hint*/ long long mod(long long x)
{
if (x >= 0 && x < MOD) return x;
x %= MOD;
if (x < 0)
return x + MOD;
return x;
}
struct matrix
{
long long m[4][4];
static matrix multiply(const matrix &a, const matrix &b)
{
int i, j, k;
matrix c;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
c.m[i][j] = 0;
for (k = 0; k < 4; k++)
c.m[i][j] += a.m[i][k] * b.m[k][j];
c.m[i][j] = mod(c.m[i][j]);
}
return c;
}
};
static matrix operator*(matrix const& a, matrix const& b)
{
return matrix::multiply(a,b);
}
template <typename T>
T pow(T const&a, long long n)
{
if (n == 0) throw "not implemented";
if (n == 1) return a;
auto b = pow(a*a, n>>1);
return (n & 1)? b*a : b;
}
int main()
{
//std::cout << "pow(2, 0): " << pow(2, 0) << std::endl;
std::cout << "pow(2, 1): " << pow(2ll, 1) << std::endl;
std::cout << "pow(2, 2): " << pow(2ll, 2) << std::endl;
std::cout << "pow(2, 3): " << pow(2ll, 3) << std::endl;
std::cout << "pow(2, 4): " << pow(2ll, 4) << std::endl;
std::cout << "pow(2, 5): " << pow(2ll, 5) << std::endl;
std::cout << "pow(2, 10): " << pow(2ll, 10) << std::endl;
std::cout << "pow(2, 16): " << pow(2ll, 16) << std::endl;
std::cout << "pow(2, 32): " << pow(2ll, 32) << std::endl;
matrix v = { { { 1,2,3,4}, { 2,3,4,5},
{ 3,4,5,6}, { 7,8,9,0} } };
for (long i = 0; i< (1ul << 22ul); ++i)
pow(v, 16);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RhdGljIGNvbnN0ZXhwciBhdXRvIE1PRCA9IDEwMDAwMDAwMDdMTDsKCmlubGluZSAvKmhpbnQgaGludCovIGxvbmcgbG9uZyBtb2QobG9uZyBsb25nIHgpCnsKICAgIGlmICh4ID49IDAgJiYgeCA8IE1PRCkgcmV0dXJuIHg7CgogICAgeCAlPSBNT0Q7CiAgICBpZiAoeCA8IDApCiAgICAgICAgcmV0dXJuIHggKyBNT0Q7CgogICAgcmV0dXJuIHg7Cn0KCnN0cnVjdCBtYXRyaXgKewoJbG9uZyBsb25nIG1bNF1bNF07CgoJc3RhdGljIG1hdHJpeCBtdWx0aXBseShjb25zdCBtYXRyaXggJmEsIGNvbnN0IG1hdHJpeCAmYikKCXsKCQlpbnQgaSwgaiwgazsKCQltYXRyaXggYzsKCgkJZm9yIChpID0gMDsgaSA8IDQ7IGkrKykKCQkJZm9yIChqID0gMDsgaiA8IDQ7IGorKykKCQkJewoJCQkJYy5tW2ldW2pdID0gMDsKCQkJCWZvciAoayA9IDA7IGsgPCA0OyBrKyspCgkJCQkJYy5tW2ldW2pdICs9IGEubVtpXVtrXSAqIGIubVtrXVtqXTsKCQkJCWMubVtpXVtqXSA9IG1vZChjLm1baV1bal0pOwoJCQl9CgoJCXJldHVybiBjOwoJfQp9OwoKc3RhdGljIG1hdHJpeCBvcGVyYXRvcioobWF0cml4IGNvbnN0JiBhLCBtYXRyaXggY29uc3QmIGIpCnsKCXJldHVybiBtYXRyaXg6Om11bHRpcGx5KGEsYik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpUIHBvdyhUIGNvbnN0JmEsIGxvbmcgbG9uZyBuKQp7CiAgICBpZiAobiA9PSAwKSB0aHJvdyAibm90IGltcGxlbWVudGVkIjsKICAgIGlmIChuID09IDEpIHJldHVybiBhOwoKICAgIGF1dG8gYiA9IHBvdyhhKmEsIG4+PjEpOwoKICAgIHJldHVybiAobiAmIDEpPyBiKmEgOiBiOwp9CgppbnQgbWFpbigpCnsKCS8vc3RkOjpjb3V0IDw8ICJwb3coMiwgIDApOiAiIDw8IHBvdygyLCAgMCkgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJwb3coMiwgIDEpOiAiIDw8IHBvdygybGwsICAxKSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgInBvdygyLCAgMik6ICIgPDwgcG93KDJsbCwgIDIpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAicG93KDIsICAzKTogIiA8PCBwb3coMmxsLCAgMykgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJwb3coMiwgIDQpOiAiIDw8IHBvdygybGwsICA0KSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgInBvdygyLCAgNSk6ICIgPDwgcG93KDJsbCwgIDUpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAicG93KDIsIDEwKTogIiA8PCBwb3coMmxsLCAxMCkgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJwb3coMiwgMTYpOiAiIDw8IHBvdygybGwsIDE2KSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgInBvdygyLCAzMik6ICIgPDwgcG93KDJsbCwgMzIpIDw8IHN0ZDo6ZW5kbDsKCgltYXRyaXggdiA9IHsgeyB7IDEsMiwzLDR9LCB7IDIsMyw0LDV9LAoJCSAgICAgICAgICAgeyAzLDQsNSw2fSwgeyA3LDgsOSwwfSB9IH07CgoJZm9yIChsb25nIGkgPSAwOyBpPCAoMXVsIDw8IDIydWwpOyArK2kpCgkJcG93KHYsIDE2KTsKfQo=