#include <bits/stdc++.h>
// what the fuck
template<typename T, int N>
struct NDVector { using type = std::vector<typename NDVector<T, N - 1>::type>; };
template<typename T>
struct NDVector<T, 1> { using type = std::vector<T>; };
// A tensor is essentially a vector of tensors. (or multidimensional array)
template<typename T, int N>
using Tensor = typename NDVector<T, N>::type;
/**
* Create a multidimensional vector with the given dimension sizes.
*
* In particular, create_vector(N) = create_tensor(N), create_matrix(N, M) = create_tensor(N, M).
* If you have some weird multidimensional DP, you can create the DP table by doing:
* dp = create_tensor(5, 5, 5, 5, 5);
*
* Be careful, for a large number of dimensions, this uses a lot of memory and is very cache unfriendly.
*/
template<typename T>
std::vector<T> create_tensor(int N) {
return std::vector<T>(N);
}
template <typename T, typename... ArgTypes>
Tensor<T, sizeof...(ArgTypes) + 1> create_tensor(int N, ArgTypes... args) {
auto under = create_tensor<T>(args...);
return std::vector(N, under);
}
/**
* Create a matrix of the given dimensions.
*/
template<typename T>
Tensor<T, 2> create_matrix(int N, int M) {
return create_tensor<T>(N, M);
}
/**
* Frequently used definitions, like Vector, Matrices, pairs of ints, pairs, triples, etc.
*/
template<typename T>
using Vector = Tensor<T, 1>; // I could use std::vector<T>, but this is just too cool.
template<typename T>
using Matrix = Tensor<T, 2>;
template<typename T1, typename T2>
using Pair = std::pair<T1, T2>;
using PairII = Pair<int, int>;
using PairLL = Pair<long long, long long>;
template<typename T1, typename T2, typename T3>
using Triple = std::tuple<T1, T2, T3>;
/**
* Read a vector from input. Set start to 1 if you want it to be 1-indexed.
*/
template<typename T>
Vector<T> read_vector(int N, int start = 0) {
Vector<T> v(start + N);
for (int i = start; i < (int)v.size(); i++) {
std::cin >> v[i];
}
return v;
}
/**
* Read a matrix from input. Set start_l to make lines 1-indexed. Same thing for start_c.
*/
template<typename T>
Matrix<T> read_matrix(int N, int M, int start_l = 0, int start_c = 0) {
Matrix<T> matr = create_matrix<T>(N + start_l, M + start_c);
for (int l = start_l; l < N + start_l; l++)
for (int c = start_c; c < M + start_c; c++)
std::cin >> matr[l][c];
return matr;
}
/**
* Print a tensor to the output stream. Prints all indices between i and j, and the elements
* are separated by the given separator.
*
* To generalize, for each dimension, you give the bounds that you want to print and the separator
* between each order. To print a matrix, you would do:
*
* print_tensor(matr, std::cout, 0, N - 1, "\n", 0, M - 1, " ");
*/
template<typename T>
void print_tensor(Tensor<T, 1>& tens, std::ostream&fout, int i, int j, const char* sep) {
for (int t = std::max(i, 0); t <= j && t < (int)tens.size(); t++) {
fout << tens[t];
if (t + 1 <= j)
fout << sep;
}
}
template<typename T, typename... Sizes>
void print_tensor(
Tensor<T, sizeof...(Sizes) / 3 + 1>& tens,
std::ostream& fout,
int i, int j, const char* sep, Sizes... sizes) {
for (int t = std::max(i, 0); t <= j && t < (int)tens.size(); t++) {
print_tensor<T>(tens[t], fout, sizes...);
if (t + 1 <= j)
fout << sep;
}
}
/**
* Print a vector to the given output stream with given bounds and separator.
*/
template<typename T>
void print_vector(std::vector<T>& v, std::ostream& fout, int i = 0, int j = (1 << 30), const char* sep = " ") {
print_tensor<T>(v, fout, i, j, sep);
}
/**
* Read a vector of pairs. Set start to 1 if you want this to be 1-indexed.
*/
template<typename T1, typename T2>
Vector<Pair<T1, T2>> read_pairvec(int N, int start = 0) {
Vector<Pair<T1, T2>> input = Vector<Pair<T1, T2>>(start + N);
for (int i = start; i < start + N; i++)
std::cin >> input[i].first >> input[i].second;
return input;
}
/**
* Read a vector of triples. Set start to 1 if you want this to be 1-indexed.
*
* If you need higher order tuples, like quadruples, you're better off using a matrix instead.
*/
template<typename T1, typename T2, typename T3>
Vector<Triple<T1, T2, T3>> read_triplevec(int N, int start = 0) {
Vector<Triple<T1, T2, T3>> input = Vector<Triple<T1, T2, T3>>(start + N);
for (int i = start; i < N + start; i++) {
T1 a;
T2 b;
T3 c;
std::cin >> a >> b >> c;
input[i] = {a, b, c};
}
return input;
}
/**
* Removes duplicates from vector. Assumes it is sorted.
*/
template<typename T>
void deduplicate(Vector<T>& v) {
v.resize(std::unique(v.begin(), v.end()) - v.begin());
}
/**
* Solve a testcase of the problem. You will code your solution here instead of main.
*/
void solve_test();
/**
* Call this function if you have a problem with multiple testcases.
*/
void multitest_problem() {
int T;
std::cin >> T;
while (T--) solve_test();
}
int main() {
std::cin.tie(NULL);
std::iostream::sync_with_stdio(false);
// Choose one of the following functions, depending on the problem type.
solve_test();
//multitest_problem();
return 0;
}
/******************************************** modulo.h ******************************************/
/**
* Classic modulos. The third one is not const in case you need dynamic modulo operations.
*/
const int MOD = 666013;
// const int MOD = 998244353;
//const int MOD = 1000000007;
//int MOD = 1234;
/**
* Modulo class that encapsulates all the modulo operations. Addition, multiplication, subtraction.
*/
struct Modulo {
int val;
Modulo(long long v = 0) { v %= MOD; if (v < 0) v += MOD; val = v; }
Modulo& operator+=(Modulo const& x) {
val = val + x.val;
if (val >= MOD)
val = val - MOD;
return *this;
}
Modulo& operator-=(Modulo const& x) {
val = val - x.val;
if (val < 0)
val = val + MOD;
return *this;
}
Modulo& operator*=(Modulo const& x) {
val = (long long)val * x.val % MOD;
return *this;
}
friend Modulo operator+(Modulo a, Modulo const b) { return a += b; }
friend Modulo operator-(Modulo a, Modulo const b) { return a -= b; }
friend Modulo operator-(Modulo const b) { return 0 - b; }
friend Modulo operator*(Modulo a, Modulo const b) { return a *= b; }
friend std::ostream& operator<<(std::ostream& fout, Modulo const x) { return fout << x.val; }
friend bool operator==(Modulo const a, Modulo const b) { return a.val == b.val; }
friend bool operator!=(Modulo const a, Modulo const b) { return a.val != b.val; }
};
/**
* Binary exponentiation of modulo numbers.
*/
Modulo lgput(Modulo b, long long e) {
Modulo ac = 1;
while (e > 0) {
if (e % 2 == 1)
ac = ac * b;
b = b * b;
e /= 2;
}
return ac;
}
/**
* Compute the inverse of the given modulo number.
*
* XXX: MOD must be a prime number. Otherwise you have to do some crazy stuff.
*/
Modulo inverse(Modulo a) {
return lgput(a, MOD - 2);
}
/************************************* linear-algebra.h *********************************/
/**
* Matrix data structure used for linear algebra.
*/
template<typename T>
struct LinMatrix {
std::vector<std::vector<T>> val;
LinMatrix(int N, int M): val(N, std::vector<T>(M)) {}
LinMatrix(int N): LinMatrix(N, N) {}
LinMatrix(): LinMatrix(0, 0) {}
LinMatrix(std::vector<std::vector<T>>& val): val(std::move(val)) {}
/**
* Return sizes of the matrix.
*/
std::pair<int, int> get_sizes() const {
int N = val.size();
if (N == 0) return {0, 0};
return {N, val[0].size()};
}
/**
* Standard matrix operations. Addition, subtraction, multiplication.
*
* If you need another underlying data structure, you do not have to implement all operations.
*/
LinMatrix<T>& operator+= (const LinMatrix<T>& b) {
assert(get_sizes() == b.get_sizes());
auto [n, m] = get_sizes();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
val[i][j] = val[i][j] + b.val[i][j];
return *this;
}
LinMatrix<T>& operator-= (const LinMatrix<T>& b) {
assert(get_sizes() == b.get_sizes());
auto [n, m] = get_sizes();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
val[i][j] = val[i][j] - b.val[i][j];
return *this;
}
friend LinMatrix<T> operator+ (const LinMatrix<T>& a, const LinMatrix<T>& b) {
auto res = a;
res += b;
return res;
}
friend LinMatrix<T> operator* (const LinMatrix<T>& a, const LinMatrix<T>& b) {
auto [N, M] = a.get_sizes();
auto [M2, K] = b.get_sizes();
assert(M == M2);
LinMatrix res(N, K);
for (int l = 0; l < N; l++)
for (int c = 0; c < K; c++)
for (int k = 0; k < M; k++)
res.val[l][c] = res.val[l][c] + a.val[l][k] * b.val[k][c];
return res;
}
LinMatrix<T>& operator *= (const LinMatrix& a) {
auto res = (*this) * a;
val = std::move(res.val);
return *this;
}
/**
* Complete matrix elements line by line, from left to right, as long as there is enough place. Good for manual testing
*
* For instance:
* LinMatrix<int> x(3);
* x = {1, 2, 3, 4, 5, 6, 7}; // first two rows look as you would expect
* // last row is {7, 0, 0};
*/
LinMatrix<T>& operator= (std::vector<T> v) {
auto [N, M] = get_sizes();
int p = 0;
for (int l = 0; l < N; l++)
for (int c = 0; c < M; c++) {
if (p < (int)v.size())
val[l][c] = v[p++];
else
val[l][c] = 0;
}
return *this;
}
friend std::ostream& operator<<(std::ostream& fout, LinMatrix<T>& v) {
auto [N, M] = v.get_sizes();
for (int l = 0; l < N; l++) {
for (int c = 0; c < N; c++)
fout << v.val[l][c] << " ";
fout << "\n";
}
return fout;
}
};
/**
* Create the identity matrix of size N.
*/
template<typename T>
LinMatrix<T> identitymatrix(int N, T e = 1, T n = 0) {
LinMatrix<T> res(N);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (i == j)
res.val[i][j] = e;
else
res.val[i][j] = n;
return res;
}
/**
* Create the null matrix of size N.
*/
template<typename T>
LinMatrix<T> nullmatrix(int N, T n = 0) {
LinMatrix<T> res(N);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
res.val[i][j] = n;
return res;
}
/**
* Logarithmic exponentiation.
*/
template<typename T>
LinMatrix<T> lgput(LinMatrix<T> A, int e, T neutral = 1, T null = 0) {
auto [N, M] = A.get_sizes();
assert(N == M);
LinMatrix<T> ac = identitymatrix(N, neutral, null);
while (e > 0) {
if (e % 2 == 1)
ac = ac * A;
A = A * A;
e /= 2;
}
return ac;
}
/**
* Given a matrix, split it into multiple matrices, each being just a row.
*/
template<typename T>
std::vector<LinMatrix<T>> split_into_rows(LinMatrix<T>& M) {
std::vector<LinMatrix<T>> res;
auto [R, C] = M.get_sizes();
for (int i = 0; i < R; i++) {
std::vector<std::vector<T>> row = {M.val[i]};
res.push_back(LinMatrix<T>(row));
}
return res;
}
/**
* Similarly, given a bunch of rows, merge them into a single matrix.
*/
template<typename T>
LinMatrix<T> join_rows(std::vector<LinMatrix<T>>& rows) {
std::vector<LinMatrix<T>> res;
int M = rows[0].get_sizes().second;
std::vector<std::vector<T>> val;
for (int i = 0; i < (int)rows.size(); i++) {
auto [Np, Mp] = rows[i].get_sizes();
assert(Np == 1); // all rows must be actually rows.
assert(Mp == M); // all rows must have the same size.
val.push_back(rows[i].val[0]);
}
return LinMatrix<T>(val);
}
/**
* Use this example to do Fibonacci. You have a bunch of rows
* that you use like normal variables to build your linear recurrence, and
* then you create your matrix.
*/
LinMatrix<Modulo> build_recurrence() {
LinMatrix<Modulo> I = identitymatrix<Modulo>(2);
auto rows = split_into_rows(I);
auto fn = rows[0];
auto fn1 = rows[1];
auto fn2 = fn + fn1;
fn = fn1;
fn1 = fn2;
Vector<LinMatrix<Modulo>> M = {fn, fn1};
return join_rows(M);
}
void solve_test() {
// int64_t N;
// int M;
// std::cin >> N >> M;
std::ifstream fin("kfib.in");
std::ofstream fout("kfib.out");
int K;
fin >> K;
auto rec = build_recurrence();
rec = lgput(rec, K);
auto fib = LinMatrix<Modulo>(2, 1);
fib = std::vector<Modulo>{0, 1};
fib = rec * fib;
fout << fib.val[0][0];
fin.close();
fout.close();
}