diff --git a/algorithms/math/big_integer.cpp b/algorithms/math/big_integer.cpp
index 28851c8649c7349dcda5043b4f13b1862f4e1cbe..f88c09f0d43e6a46947257b07523f79d4f69de14 100644
--- a/algorithms/math/big_integer.cpp
+++ b/algorithms/math/big_integer.cpp
@@ -1,100 +1,231 @@
 /// Big Integer
 ///
 /// Space: O(n)
+///
+/// Status: Tested (KRAKOVIA)
+/// Caution: Just use python.
 
 const int base = 1000000000;
 const int base_d = 9;
 
 struct BigInt {
-  int sign = 1;
+  int sign;
   vector<int> num;
 
-  BigInt() {}
-  BigInt(const string &x) { read(x); }
+  BigInt() : sign(1) {}
+  BigInt(ll x) { *this = x; }
+  BigInt(const string &s) { read(s); }
+
+  void operator=(const BigInt &x) {
+    sign = x.sign;
+    num = x.num;
+  }
+
+  void operator=(ll x) {
+    sign = 1;
+    if (x < 0) sign = -1, x = -x;
+    for (; x > 0; x /= base)
+      pb(x % base);
+  }
 
   BigInt operator+(const BigInt &x) const {
     if (sign != x.sign) return *this - (-x);
 
-    BigInt ans = x;
+
     int carry = 0;
-    for (int i = 0; i < max(size(), x.size()) || carry; ++i) {
-      if (i == ans.size()) ans.push_back(0);
+    BigInt res = x;
 
-      if (i < size()) ans[i] += carry + num[i];
-      else ans[i] += carry;
+    for (int i = 0; i < max(size(), x.size()) || carry; ++i) {
+      if (i == (int) res.size())
+        res.push_back(0);
 
-      carry = ans[i] >= base;
-      if (carry) ans[i] -= base;
+      res[i] += carry + (i < size() ? num[i] : 0);
+      carry = res[i] >= base;
+      if (carry) res[i] -= base;
     }
 
-    return ans;
+    return res;
   }
 
-  BigInt operator-(const BigInt& x) const {
-    if (sign != x.sign)
-      return *this + (-x);
-    if (abs() < x.abs())
-      return -(x - *this);
+  BigInt operator-(const BigInt &x) const {
+    if (sign != x.sign) return *this + (-x);
+    if (abs() < x.abs()) return -(x - *this);
 
-    BigInt ans = *this;
     int carry = 0;
+    BigInt res = *this;
+
     for (int i = 0; i < x.size() || carry; ++i) {
-      if (i < x.size()) ans[i] -= carry + x[i];
-      else ans[i] -= carry;
+      res[i] -= carry + (i < x.size() ? x[i] : 0);
+      carry = res[i] < 0;
+      if (carry) res[i] += base;
+    }
+
+    res.trim();
+    return res;
+  }
+
+  void operator*=(int x) {
+    if (x < 0) sign = -sign, x = -x;
+
+    int carry = 0;
+    for (int i = 0; i < size() || carry; ++i) {
+      if (i == size()) pb(0);
+      ll cur = num[i] * (ll) x + carry;
 
-      carry = ans[i] < 0;
-      if (carry) ans[i] += base;
+      carry  = (int) (cur / base);
+      num[i] = (int) (cur % base);
     }
 
-    ans.trim();
-    return ans;
+    trim();
   }
 
-  // Removes leading zeros.
-  void trim() {
-    while (!num.empty() && num.back() == 0)
-      num.pop_back();
+  BigInt operator*(int x) const {
+    BigInt res = *this;
+    res *= x;
+    return res;
+  }
+
+  friend pair<BigInt, BigInt> divmod(const BigInt &a1, 
+      const BigInt &b1) 
+  {
+    int norm = base / (b1.back() + 1);
+    BigInt a = a1.abs() * norm;
+    BigInt b = b1.abs() * norm;
+    BigInt q, r;
+    q.resize(a.size());
+
+    for (int i = a.size() - 1; i >= 0; i--) {
+      r *= base;
+      r += a[i];
+
+      int s1 = r.size() <= b.size() ? 0 : r[b.size()];
+      int s2 = r.size() <= b.size() - 1 ? 0 : r[b.size() - 1];
+      int d = ((ll) base * s1 + s2) / b.back();
+
+      r -= b * d;
+      while (r < 0) r += b, --d;
+      q[i] = d;
+    }
+
+    q.sign = a1.sign * b1.sign;
+    r.sign = a1.sign;
+    q.trim(); r.trim();
+
+    return make_pair(q, r / norm);
+  }
+
+  BigInt operator/(const BigInt &x) const {
+    return divmod(*this, x).fi;
+  }
+
+  BigInt operator%(const BigInt &x) const {
+    return divmod(*this, x).se;
+  }
+
+  void operator/=(int x) {
+    if (x < 0) sign = -sign, x = -x;
+
+    for (int i = size() - 1, rem = 0; i >= 0; --i) {
+      ll cur = num[i] + rem * (ll) base;
+      num[i] = (int) (cur / x);
+      rem = (int) (cur % x);
+    }
+
+    trim();
+  }
+
+  BigInt operator/(int x) const {
+    BigInt res = *this;
+    res /= x;
+    return res;
+  }
+
+  int operator%(int x) const {
+    if (x < 0) x = -x;
+
+    int m = 0;
+    for (int i = size() - 1; i >= 0; --i)
+      m = (num[i] + m * (ll) base) % x;
+
+    return m * sign;
+  }
 
-    if (num.empty())
-      sign = 1;
+  void operator+=(const BigInt &x) {
+    *this = *this + x;
+  }
+  void operator-=(const BigInt &x) {
+    *this = *this - x;
+  }
+  void operator*=(const BigInt &x) {
+    *this = *this * x;
+  }
+  void operator/=(const BigInt &x) {
+    *this = *this / x;
   }
 
-  bool operator<(const BigInt &x) {
+  bool operator<(const BigInt &x) const {
     if (sign != x.sign)
       return sign < x.sign;
-
+    
     if (size() != x.size())
-      return (size() * sign) < (x.size() * x.sign);
+      return size() * sign < x.size() * x.sign;
 
     for (int i = size() - 1; i >= 0; i--)
       if (num[i] != x[i])
-        return (num[i] * sign) < (x[i] * x.sign);
+        return num[i] * sign < x[i] * sign;
 
     return false;
   }
 
-  bool operator==(const BigInt &x) { 
-    return !(*this < x) && !(x < *this); 
+  bool operator>(const BigInt &x) const {
+    return x < *this;
+  }
+  bool operator<=(const BigInt &x) const {
+    return !(x < *this);
+  }
+  bool operator>=(const BigInt &x) const {
+    return !(*this < x);
+  }
+  bool operator==(const BigInt &x) const {
+    return !(*this < x) && !(x < *this);
+  }
+  bool operator!=(const BigInt &x) const {
+    return *this < x || x < *this;
   }
 
-  bool operator>(const BigInt &x)  const { return  (x < *this); }
-  bool operator<=(const BigInt &x) const { return !(x < *this); }
-  bool operator>=(const BigInt &x) const { return !(*this < x); }
-  bool operator!=(const BigInt &x) const { return !(*this == x); }
+  void trim() {
+    while (!empty() && !back()) pop_back();
+    if (empty()) sign = 1;
+  }
 
+  bool is_zero() const {
+    return empty() || (size() == 1 && !num[0]);
+  }
 
-  // Handles -x (change of sign).
   BigInt operator-() const {
-    BigInt ans = *this;
-    ans.sign = -sign;
-    return ans;
+    BigInt res = *this;
+    res.sign = -sign;
+    return res;
   }
 
-  // Returs absolute value.
   BigInt abs() const {
-    BigInt ans = *this;
-    ans.sign *= ans.sign;
-    return ans;
+    BigInt res = *this;
+    res.sign *= res.sign;
+    return res;
+  }
+
+  ll to_long() const {
+    ll res = 0;
+    for (int i = size() - 1; i >= 0; i--)
+      res = res * base + num[i];
+    return res * sign;
+  }
+
+  friend BigInt gcd(const BigInt &a, const BigInt &b) {
+    return b.is_zero() ? a : gcd(b, a % b);
+  }
+  friend BigInt lcm(const BigInt &a, const BigInt &b) {
+    return a / gcd(a, b) * b;
   }
 
   // Transforms string into BigInt.
@@ -103,9 +234,8 @@ struct BigInt {
     num.clear();
 
     int pos = 0;
-    while (pos < (int) s.size() && 
-        (s[pos] == '-' || s[pos] == '+')) 
-    {
+    while (pos < s.size() && 
+        (s[pos] == '-' || s[pos] == '+')) {
       if (s[pos] == '-')
         sign = -sign;
       ++pos;
@@ -127,8 +257,7 @@ struct BigInt {
     return stream;
   }
 
-  friend ostream& operator<<(ostream &stream, 
-      const BigInt &x) {
+  friend ostream& operator<<(ostream &stream, const BigInt &x) {
     if (x.sign == -1)
       stream << '-';
 
@@ -139,10 +268,109 @@ struct BigInt {
     return stream;
   }
 
+  static vector<int> convert_base(const vector<int> &a, 
+      int oldd, int newd) 
+  {
+    vector<ll> p(max(oldd, newd) + 1);
+    p[0] = 1;
+    for (int i = 1; i < p.size(); i++)
+      p[i] = p[i - 1] * 10;
+
+    ll cur = 0;
+    int curd = 0;
+    vector<int> res;
+
+    for (int i = 0; i < a.size(); i++) {
+      cur += a[i] * p[curd];
+      curd += oldd;
+
+      while (curd >= newd) {
+        res.pb(int(cur % p[newd]));
+        cur /= p[newd];
+        curd -= newd;
+      }
+    }
+
+    res.pb((int) cur);
+    while (!res.empty() && !res.back())
+      res.pop_back();
+    return res;
+  }
+
+  static vector<ll> karatsuba(const vector<ll> &a, 
+      const vector<ll> &b) 
+  {
+    int n = a.size();
+    vector<ll> res(n + n);
+
+    if (n <= 32) {
+      for (int i = 0; i < n; i++)
+        for (int j = 0; j < n; j++)
+          res[i + j] += a[i] * b[j];
+      return res;
+    }
+
+    int k = n >> 1;
+    vector<ll> a1(a.begin(), a.begin() + k);
+    vector<ll> a2(a.begin() + k, a.end());
+    vector<ll> b1(b.begin(), b.begin() + k);
+    vector<ll> b2(b.begin() + k, b.end());
+
+    vector<ll> a1b1 = karatsuba(a1, b1);
+    vector<ll> a2b2 = karatsuba(a2, b2);
+
+    for (int i = 0; i < k; i++)
+      a2[i] += a1[i];
+    for (int i = 0; i < k; i++)
+      b2[i] += b1[i];
+
+    vector<ll> r = karatsuba(a2, b2);
+    for (int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i];
+    for (int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i];
+
+    for (int i = 0; i < r.size(); i++) res[i + k] += r[i];
+    for (int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i];
+    for (int i = 0; i < a2b2.size(); i++) res[i + n] += a2b2[i];
+
+    return res;
+  }
+
+  BigInt operator*(const BigInt &x) const {
+    vector<int> a6 = convert_base(this->num, base_d, 6);
+    vector<int> b6 = convert_base(x.num, base_d, 6);
+
+    vector<ll> a(all(a6));
+    vector<ll> b(all(b6));
+
+    while (a.size() < b.size()) a.pb(0);
+    while (b.size() < a.size()) b.pb(0);
+    while (a.size() & (a.size() - 1)) 
+      a.pb(0), b.pb(0);
+
+    vector<ll> c = karatsuba(a, b);
+
+    BigInt res;
+    int carry = 0;
+    res.sign = sign * x.sign;
+
+    for (int i = 0; i < c.size(); i++) {
+      ll cur = c[i] + carry;
+      res.pb((int) (cur % 1000000));
+      carry = (int) (cur / 1000000);
+    }
+
+    res.num = convert_base(res.num, 6, base_d);
+    res.trim();
+    return res;
+  }
+
   // Handles vector operations.
   int back() const { return num.back(); }
   bool empty() const { return num.empty(); }
   size_t size() const { return num.size(); }
+
+  void pop_back() { num.pop_back(); }
+  void resize(int x) { num.resize(x); }
   void push_back(int x) { num.push_back(x); }
 
   int &operator[](int i) { return num[i]; }
diff --git a/algorithms/math/binary_exponentiation.cpp b/algorithms/math/binary_exponentiation.cpp
index bda0665f2416948c48bf68ff8ea62450ba02ad7b..e20f965ab12606745050948856cfb9d82c697a75 100644
--- a/algorithms/math/binary_exponentiation.cpp
+++ b/algorithms/math/binary_exponentiation.cpp
@@ -3,18 +3,15 @@
 /// Time: O(log n)
 /// Space: O(1)
 
-struct BinaryExponentiation {
+struct BinExp {
   ll run(ll x, ll n) {
     ll ans = 1;
-
     while (n) {
       if (n & 1)
         ans = ans * x;
-
       n >>= 1;
       x = x * x;
     }
-
     return ans;
   }
 };
diff --git a/contests/Cadernaveis/KOCH.cpp b/contests/Cadernaveis/KOCH.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5cf2391d2465eab4ddf78133824cacfe3abc380
--- /dev/null
+++ b/contests/Cadernaveis/KOCH.cpp
@@ -0,0 +1,412 @@
+#include <bits/stdc++.h>
+ 
+#define EPS 1e-6
+#define MOD 1000000007
+#define inf 0x3f3f3f3f
+#define llinf 0x3f3f3f3f3f3f3f3f
+ 
+#define fi first
+#define se second
+#define pb push_back
+#define ende '\n'
+ 
+#define all(x) (x).begin(), (x).end()
+#define rall(x) (x).rbegin(), (x).rend()
+#define mset(x, y) memset(&x, (y), sizeof(x))
+ 
+using namespace std; 
+ 
+using ll = long long;
+using ii = pair<int,int>;
+ 
+const int base = 1000000000;
+const int base_d = 9;
+ 
+struct BigInt {
+  int sign;
+  vector<int> num;
+ 
+  BigInt() : sign(1) {}
+  BigInt(ll x) { *this = x; }
+  BigInt(const string &s) { read(s); }
+ 
+  void operator=(const BigInt &x) {
+    sign = x.sign;
+    num = x.num;
+  }
+ 
+  void operator=(ll x) {
+    sign = 1;
+    if (x < 0) sign = -1, x = -x;
+    for (; x > 0; x /= base)
+      pb(x % base);
+  }
+ 
+  BigInt operator+(const BigInt &x) const {
+    if (sign != x.sign) return *this - (-x);
+ 
+ 
+    int carry = 0;
+    BigInt res = x;
+ 
+    for (int i = 0; i < max(size(), x.size()) || carry; ++i) {
+      if (i == (int) res.size())
+        res.push_back(0);
+ 
+      res[i] += carry + (i < size() ? num[i] : 0);
+      carry = res[i] >= base;
+      if (carry) res[i] -= base;
+    }
+ 
+    return res;
+  }
+ 
+  BigInt operator-(const BigInt &x) const {
+    if (sign != x.sign) return *this + (-x);
+    if (abs() < x.abs()) return -(x - *this);
+ 
+    int carry = 0;
+    BigInt res = *this;
+ 
+    for (int i = 0; i < x.size() || carry; ++i) {
+      res[i] -= carry + (i < x.size() ? x[i] : 0);
+      carry = res[i] < 0;
+      if (carry) res[i] += base;
+    }
+ 
+    res.trim();
+    return res;
+  }
+ 
+  void operator*=(int x) {
+    if (x < 0) sign = -sign, x = -x;
+ 
+    int carry = 0;
+    for (int i = 0; i < size() || carry; ++i) {
+      if (i == size()) pb(0);
+      ll cur = num[i] * (ll) x + carry;
+ 
+      carry  = (int) (cur / base);
+      num[i] = (int) (cur % base);
+    }
+ 
+    trim();
+  }
+ 
+  BigInt operator*(int x) const {
+    BigInt res = *this;
+    res *= x;
+    return res;
+  }
+ 
+  friend pair<BigInt, BigInt> divmod(const BigInt &a1, 
+      const BigInt &b1) 
+  {
+    int norm = base / (b1.back() + 1);
+    BigInt a = a1.abs() * norm;
+    BigInt b = b1.abs() * norm;
+    BigInt q, r;
+    q.resize(a.size());
+ 
+    for (int i = a.size() - 1; i >= 0; i--) {
+      r *= base;
+      r += a[i];
+ 
+      int s1 = r.size() <= b.size() ? 0 : r[b.size()];
+      int s2 = r.size() <= b.size() - 1 ? 0 : r[b.size() - 1];
+      int d = ((ll) base * s1 + s2) / b.back();
+ 
+      r -= b * d;
+      while (r < 0) r += b, --d;
+      q[i] = d;
+    }
+ 
+    q.sign = a1.sign * b1.sign;
+    r.sign = a1.sign;
+    q.trim(); r.trim();
+ 
+    return make_pair(q, r / norm);
+  }
+ 
+  BigInt operator/(const BigInt &x) const {
+    return divmod(*this, x).fi;
+  }
+ 
+  BigInt operator%(const BigInt &x) const {
+    return divmod(*this, x).se;
+  }
+ 
+  void operator/=(int x) {
+    if (x < 0) sign = -sign, x = -x;
+ 
+    for (int i = size() - 1, rem = 0; i >= 0; --i) {
+      ll cur = num[i] + rem * (ll) base;
+      num[i] = (int) (cur / x);
+      rem = (int) (cur % x);
+    }
+ 
+    trim();
+  }
+ 
+  BigInt operator/(int x) const {
+    BigInt res = *this;
+    res /= x;
+    return res;
+  }
+ 
+  int operator%(int x) const {
+    if (x < 0) x = -x;
+ 
+    int m = 0;
+    for (int i = size() - 1; i >= 0; --i)
+      m = (num[i] + m * (ll) base) % x;
+ 
+    return m * sign;
+  }
+ 
+  void operator+=(const BigInt &x) {
+    *this = *this + x;
+  }
+  void operator-=(const BigInt &x) {
+    *this = *this - x;
+  }
+  void operator*=(const BigInt &x) {
+    *this = *this * x;
+  }
+  void operator/=(const BigInt &x) {
+    *this = *this / x;
+  }
+ 
+  bool operator<(const BigInt &x) const {
+    if (sign != x.sign)
+      return sign < x.sign;
+    
+    if (size() != x.size())
+      return size() * sign < x.size() * x.sign;
+ 
+    for (int i = size() - 1; i >= 0; i--)
+      if (num[i] != x[i])
+        return num[i] * sign < x[i] * sign;
+ 
+    return false;
+  }
+ 
+  bool operator>(const BigInt &x) const {
+    return x < *this;
+  }
+  bool operator<=(const BigInt &x) const {
+    return !(x < *this);
+  }
+  bool operator>=(const BigInt &x) const {
+    return !(*this < x);
+  }
+  bool operator==(const BigInt &x) const {
+    return !(*this < x) && !(x < *this);
+  }
+  bool operator!=(const BigInt &x) const {
+    return *this < x || x < *this;
+  }
+ 
+  void trim() {
+    while (!empty() && !back()) pop_back();
+    if (empty()) sign = 1;
+  }
+ 
+  bool is_zero() const {
+    return empty() || (size() == 1 && !num[0]);
+  }
+ 
+  BigInt operator-() const {
+    BigInt res = *this;
+    res.sign = -sign;
+    return res;
+  }
+ 
+  BigInt abs() const {
+    BigInt res = *this;
+    res.sign *= res.sign;
+    return res;
+  }
+ 
+  ll to_long() const {
+    ll res = 0;
+    for (int i = size() - 1; i >= 0; i--)
+      res = res * base + num[i];
+    return res * sign;
+  }
+ 
+  friend BigInt gcd(const BigInt &a, const BigInt &b) {
+    return b.is_zero() ? a : gcd(b, a % b);
+  }
+ 
+  friend BigInt lcm(const BigInt &a, const BigInt &b) {
+    return a / gcd(a, b) * b;
+  }
+ 
+  void read(const string &s) {
+    sign = 1;
+    num.clear();
+ 
+    int pos = 0;
+    while (pos < s.size() && 
+        (s[pos] == '-' || s[pos] == '+')) {
+      if (s[pos] == '-')
+        sign = -sign;
+      ++pos;
+    }
+ 
+    for (int i = s.size() - 1; i >= pos; i -= base_d) {
+      int x = 0;
+      for (int j = max(pos, i - base_d + 1); j <= i; j++)
+        x = x * 10 + s[j] - '0';
+      num.push_back(x);
+    }
+ 
+    trim();
+  }
+ 
+  friend istream& operator>>(istream &stream, BigInt &v) {
+    string s; stream >> s;
+    v.read(s);
+    return stream;
+  }
+ 
+  friend ostream& operator<<(ostream &stream, const BigInt &x) {
+    if (x.sign == -1)
+      stream << '-';
+ 
+    stream << (x.empty() ? 0 : x.back());
+    for (int i = x.size() - 2; i >= 0; --i)
+      stream << setw(base_d) << setfill('0') << x.num[i];
+ 
+    return stream;
+  }
+ 
+  static vector<int> convert_base(const vector<int> &a, 
+      int oldd, int newd) 
+  {
+    vector<ll> p(max(oldd, newd) + 1);
+    p[0] = 1;
+    for (int i = 1; i < p.size(); i++)
+      p[i] = p[i - 1] * 10;
+ 
+    ll cur = 0;
+    int curd = 0;
+    vector<int> res;
+ 
+    for (int i = 0; i < a.size(); i++) {
+      cur += a[i] * p[curd];
+      curd += oldd;
+ 
+      while (curd >= newd) {
+        res.pb(int(cur % p[newd]));
+        cur /= p[newd];
+        curd -= newd;
+      }
+    }
+ 
+    res.pb((int) cur);
+    while (!res.empty() && !res.back())
+      res.pop_back();
+    return res;
+  }
+ 
+  static vector<ll> karatsuba(const vector<ll> &a, 
+      const vector<ll> &b) 
+  {
+    int n = a.size();
+    vector<ll> res(n + n);
+ 
+    if (n <= 32) {
+      for (int i = 0; i < n; i++)
+        for (int j = 0; j < n; j++)
+          res[i + j] += a[i] * b[j];
+      return res;
+    }
+ 
+    int k = n >> 1;
+    vector<ll> a1(a.begin(), a.begin() + k);
+    vector<ll> a2(a.begin() + k, a.end());
+    vector<ll> b1(b.begin(), b.begin() + k);
+    vector<ll> b2(b.begin() + k, b.end());
+ 
+    vector<ll> a1b1 = karatsuba(a1, b1);
+    vector<ll> a2b2 = karatsuba(a2, b2);
+ 
+    for (int i = 0; i < k; i++)
+      a2[i] += a1[i];
+    for (int i = 0; i < k; i++)
+      b2[i] += b1[i];
+ 
+    vector<ll> r = karatsuba(a2, b2);
+    for (int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i];
+    for (int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i];
+ 
+    for (int i = 0; i < r.size(); i++) res[i + k] += r[i];
+    for (int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i];
+    for (int i = 0; i < a2b2.size(); i++) res[i + n] += a2b2[i];
+ 
+    return res;
+  }
+ 
+  BigInt operator*(const BigInt &x) const {
+    vector<int> a6 = convert_base(this->num, base_d, 6);
+    vector<int> b6 = convert_base(x.num, base_d, 6);
+ 
+    vector<ll> a(all(a6));
+    vector<ll> b(all(b6));
+ 
+    while (a.size() < b.size()) a.pb(0);
+    while (b.size() < a.size()) b.pb(0);
+    while (a.size() & (a.size() - 1)) 
+      a.pb(0), b.pb(0);
+ 
+    vector<ll> c = karatsuba(a, b);
+ 
+    BigInt res;
+    int carry = 0;
+    res.sign = sign * x.sign;
+ 
+    for (int i = 0; i < c.size(); i++) {
+      ll cur = c[i] + carry;
+      res.pb((int) (cur % 1000000));
+      carry = (int) (cur / 1000000);
+    }
+ 
+    res.num = convert_base(res.num, 6, base_d);
+    res.trim();
+    return res;
+  }
+ 
+  // Handles vector operations.
+  int back() const { return num.back(); }
+  bool empty() const { return num.empty(); }
+  size_t size() const { return num.size(); }
+ 
+  void pop_back() { num.pop_back(); }
+  void resize(int x) { num.resize(x); }
+  void push_back(int x) { num.push_back(x); }
+ 
+  int &operator[](int i) { return num[i]; }
+  int operator[](int i) const { return num[i]; }
+};
+ 
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+ 
+  vector<int> fib(1501);
+  fib[0] = 0;
+  fib[1] = 1;
+  for (int i = 2; i <= 1500; ++i)
+    fib[i] = (fib[i-1] + fib[i-2]) % 1000;
+ 
+  int t; cin >> t;
+  for (int cas = 1; cas <= t; ++cas) {
+    BigInt x; cin >> x;
+    x = x % BigInt(1500);
+    cout << setw(3) << setfill('0') << fib[x.to_long()]<< ende;
+  }
+ 
+  return 0;
+}
diff --git a/contests/Cadernaveis/KRAKOVIA.cpp b/contests/Cadernaveis/KRAKOVIA.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..847f1c22a349c1af77536609565db2172bc89aeb
--- /dev/null
+++ b/contests/Cadernaveis/KRAKOVIA.cpp
@@ -0,0 +1,267 @@
+#include <bits/stdc++.h>
+
+#define EPS 1e-6
+#define MOD 1000000007
+#define inf 0x3f3f3f3f
+#define llinf 0x3f3f3f3f3f3f3f3f
+
+#define fi first
+#define se second
+#define pb push_back
+#define ende '\n'
+
+#define all(x) (x).begin(), (x).end()
+#define rall(x) (x).rbegin(), (x).rend()
+#define mset(x, y) memset(&x, (y), sizeof(x))
+
+using namespace std; 
+
+using ll = long long;
+using ii = pair<int,int>;
+
+const int base = 1000000000;
+const int base_d = 9;
+
+struct BigInt {
+  int sign = 1;
+  vector<int> num;
+
+  BigInt() {}
+  BigInt(ll x) { *this = x; }
+  BigInt(const string &x) { read(x); }
+
+  void operator=(ll x) {
+    sign = 1;
+    if (x < 0) sign = -1, x = -x;
+    for (; x > 0; x /= base)
+      num.pb(x % base);
+  }
+
+  BigInt operator+(const BigInt &x) const {
+    if (sign != x.sign) return *this - (-x);
+
+    BigInt ans = x;
+    int carry = 0;
+    for (int i = 0; i < max(size(), x.size()) || carry; ++i) {
+      if (i == ans.size()) ans.push_back(0);
+
+      if (i < size()) ans[i] += carry + num[i];
+      else ans[i] += carry;
+
+      carry = ans[i] >= base;
+      if (carry) ans[i] -= base;
+    }
+
+    return ans;
+  }
+
+  BigInt operator-(const BigInt& x) const {
+    if (sign != x.sign)
+      return *this + (-x);
+    if (abs() < x.abs())
+      return -(x - *this);
+
+    BigInt ans = *this;
+    int carry = 0;
+    for (int i = 0; i < x.size() || carry; ++i) {
+      if (i < x.size()) ans[i] -= carry + x[i];
+      else ans[i] -= carry;
+
+      carry = ans[i] < 0;
+      if (carry) ans[i] += base;
+    }
+
+    ans.trim();
+    return ans;
+  }
+
+  void operator+=(const BigInt &v) {
+    *this = *this + v;
+  }
+  void operator-=(const BigInt &v) {
+    *this = *this - v;
+  }
+
+  void operator*=(int v) {
+    if (v < 0) sign = -sign, v = -v;
+    for (int i = 0, carry = 0; i < (int) size() || carry; ++i) {
+      if (i == (int) size())
+        num.push_back(0);
+
+      ll cur = num[i] * (ll) v + carry;
+      carry = (int) (cur / base);
+      num[i] = (int) (cur % base);
+    }
+
+    trim();
+  }
+
+  BigInt operator*(int v) const {
+    BigInt res = *this;
+    res *= v;
+    return res;
+  }
+
+  // Returns pair = (x / y, x % y).
+  friend pair<BigInt,BigInt> divmod(const BigInt &x, 
+      const BigInt &y) {
+    int norm = base / (y.back() + 1);
+
+    BigInt a = x.abs() * norm;
+    BigInt b = y.abs() * norm;
+    BigInt q, r;
+    q.num.resize(a.size());
+
+    for (int i = a.size() - 1; i >= 0; i--) {
+      r *= base;
+      r += a[i];
+      int s1 = r.size() <= b.size() ? 0 : r.num[b.size()];
+      int s2 = r.size() <= b.size() - 1 ? 0 : r.num[b.size() - 1];
+
+      int d = ((ll) base * s1 + s2) / b.back();
+      r -= b * d;
+      while (r < 0) r += b, --d;
+      q.num[i] = d;
+    }
+
+    q.sign = x.sign * y.sign;
+    r.sign = x.sign;
+    q.trim(); r.trim();
+    return make_pair(q, r / norm);
+  }
+
+  BigInt operator/(const BigInt &x) const {
+    return divmod(*this, x).fi;
+  }
+
+  void operator/=(int v) {
+    if (v < 0) sign = -sign, v = -v;
+
+    for (int i = (int) size() - 1, rem = 0; i >= 0; --i) {
+      ll cur = num[i] + rem * (ll) base;
+      num[i] = (int) (cur / v);
+      rem = (int) (cur % v);
+    }
+
+    trim();
+  }
+
+  BigInt operator/(int x) const {
+    BigInt res = *this;
+    res /= x;
+    return res;
+  }
+
+  // Removes leading zeros.
+  void trim() {
+    while (!num.empty() && num.back() == 0)
+      num.pop_back();
+
+    if (num.empty())
+      sign = 1;
+  }
+
+  bool operator<(const BigInt &x) const {
+    if (sign != x.sign)
+      return sign < x.sign;
+
+    if (size() != x.size())
+      return (size() * sign) < (x.size() * x.sign);
+
+    for (int i = size() - 1; i >= 0; i--)
+      if (num[i] != x[i])
+        return (num[i] * sign) < (x[i] * x.sign);
+
+    return false;
+  }
+
+  bool operator==(const BigInt &x) const { return !(*this < x) && !(x < *this); }
+  bool operator>(const BigInt &x)  const { return  (x < *this); }
+  bool operator<=(const BigInt &x) const { return !(x < *this); }
+  bool operator>=(const BigInt &x) const { return !(*this < x); }
+  bool operator!=(const BigInt &x) const { return !(*this == x); }
+
+  // Handles -x (change of sign).
+  BigInt operator-() const {
+    BigInt ans = *this;
+    ans.sign = -sign;
+    return ans;
+  }
+
+  // Returs absolute value.
+  BigInt abs() const {
+    BigInt ans = *this;
+    ans.sign *= ans.sign;
+    return ans;
+  }
+
+  // Transforms string into BigInt.
+  void read(const string &s) {
+    sign = 1;
+    num.clear();
+
+    int pos = 0;
+    while (pos < (int) s.size() && 
+        (s[pos] == '-' || s[pos] == '+')) 
+    {
+      if (s[pos] == '-')
+        sign = -sign;
+      ++pos;
+    }
+
+    for (int i = s.size() - 1; i >= pos; i -= base_d) {
+      int x = 0;
+      for (int j = max(pos, i - base_d + 1); j <= i; j++)
+        x = x * 10 + s[j] - '0';
+      num.push_back(x);
+    }
+
+    trim();
+  }
+
+  friend istream& operator>>(istream &stream, BigInt &v) {
+    string s; stream >> s;
+    v.read(s);
+    return stream;
+  }
+
+  friend ostream& operator<<(ostream &stream, 
+      const BigInt &x) {
+    if (x.sign == -1)
+      stream << '-';
+
+    stream << (x.empty() ? 0 : x.back());
+    for (int i = x.size() - 2; i >= 0; --i)
+      stream << setw(base_d) << setfill('0') << x.num[i];
+
+    return stream;
+  }
+
+  // Handles vector operations.
+  int back() const { return num.back(); }
+  bool empty() const { return num.empty(); }
+  size_t size() const { return num.size(); }
+  void push_back(int x) { num.push_back(x); }
+
+  int &operator[](int i) { return num[i]; }
+  int operator[](int i) const { return num[i]; }
+};
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int n, f, cas = 1;
+  while (cin >> n >> f && (n || f)) {
+    vector<BigInt> v(n);
+    for (int i = 0; i < n; ++i)
+      cin >> v[i];
+
+    BigInt sum = accumulate(all(v), BigInt("0"));
+    cout << "Bill #" << cas << " costs " << sum << ": each friend should pay " << sum / f << ende;
+    cout << ende;
+    cas++;
+  }
+
+  return 0;
+}
diff --git a/contests/Cadernaveis/MCAIRO.cpp b/contests/Cadernaveis/MCAIRO.cpp
index c65600e4977358bc0108427660ba3051565790b3..5915f7ba0a9fe7a5d88021aa5f3c73bff4cbe076 100644
--- a/contests/Cadernaveis/MCAIRO.cpp
+++ b/contests/Cadernaveis/MCAIRO.cpp
@@ -60,14 +60,9 @@ int main() {
     for (int i = 0; i < n; ++i)
       cin >> x[i] >> y[i];
 
-    int ans = 0;
-    for (int i = 0; i < n; ++i) {
-      int val = 1 + bit.query(x[i], y[i]);
-      bit.update(x[i], y[i], val);
-      ans = max(ans, val);
-    }
-
-    cout << ans << ende;
+    for (int i = 0; i < n; ++i)
+      bit.update(x[i], y[i], 1 + bit.query(x[i], y[i]));
+    cout << bit.query(1000, 1000) << ende;
   }
 
   return 0;