diff --git a/algorithms/math/linear_recurrence.cpp b/algorithms/math/linear_recurrence.cpp
index 3235d59c14d0a53368fa5ac19215209b3b04044a..9c3c37b61fd86dcbdb771f81f78557b0f11071f9 100644
--- a/algorithms/math/linear_recurrence.cpp
+++ b/algorithms/math/linear_recurrence.cpp
@@ -25,13 +25,15 @@
  *   [x1  x2]^n
  *   [ 1   0]
  */
-matrix solve(ll x, ll y, ll n) {
-  matrix in(2);
+template <typename T>
+matrix<T> solve(ll x, ll y, ll n) {
+  matrix<T> in(2);
 
+  // Example
   in[0][0] = x % MOD;
   in[0][1] = y % MOD;
   in[1][0] = 1;
   in[1][1] = 0;
 
-  return fast_pow(in, n);
+  return fast_pow<T>(in, n);
 }
diff --git a/algorithms/math/matrix.cpp b/algorithms/math/matrix.cpp
index 20e87f411455d815db0373013e929be802665423..f33351a79b7e3c6b55222f8f5daf8ab6d00e782d 100644
--- a/algorithms/math/matrix.cpp
+++ b/algorithms/math/matrix.cpp
@@ -2,20 +2,21 @@
  * Matrix 
  */
 
-struct Matrix {
+template <typename T>
+struct matrix {
   int r, c;
-  vector<vector<ll>> m;
+  vector<vector<T>> m;
 
-  Matrix(int k) : r(k), c(k) {
-    m = vector<vector<ll>>(k, vector<ll>(k, 0));
+  matrix(int k) : r(k), c(k) {
+    m = vector<vector<T>>(k, vector<T>(k, 0));
   }
 
-  Matrix(int r, int c) : r(r), c(c) {
-    m = vector<vector<ll>>(r, vector<ll>(c, 0));
+  matrix(int r, int c) : r(r), c(c) {
+    m = vector<vector<T>>(r, vector<T>(c, 0));
   }
 
-  Matrix operator*(Matrix a) {
-    assert(r == a.c && c = a.r);
+  matrix operator*(matrix a) {
+    assert(r == a.c && c == a.r);
 
     Matrix res(r, c);
     for (int i = 0; i < r; i++)
@@ -47,11 +48,7 @@ struct Matrix {
       m[i][i] = 1;
   }
 
-  ll *operator[](int i) {
+  vector<T> &operator[](int i) {
     return m[i];
   }
-
-  void clear() {
-    mset(m, 0);
-  }
 };
diff --git a/algorithms/structure/sqrt_decomposition.cpp b/algorithms/structure/sqrt_decomposition.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..92e58ceca10bcb2017bd080e41838172fe4eb399
--- /dev/null
+++ b/algorithms/structure/sqrt_decomposition.cpp
@@ -0,0 +1,62 @@
+/**
+ * Sqrt Decomposition
+ *
+ * Complexity (time):
+ *   Preprocess -> O(n)
+ *   Query      -> O(sqrt(n))
+ *   Update     -> O(1)
+ * Complexity (space): O(n)
+ */
+
+int v[MAX];
+int block[MAX];
+int block_size;
+
+/**
+ * Update v[idx] with val.
+ * @param idx index of v
+ * @param val new value of v[idx]
+ */
+void update(int idx, int val) {
+  block[idx / block_size] += val - v[idx];
+  v[idx] = val;
+}
+
+/**
+ * Range sum query of v[l..r].
+ * @param l,r range
+ */
+int query(int l, int r) {
+  int ans = 0;
+
+  // Query sum of elements in case l is inside a block
+  for (; l < r && ((l % block_size) != 0); ++l)
+    ans += v[l];
+
+  // Query sum of each block between l and r
+  for (; l + block_size <= r; l += block_size)
+    ans += block[l / block_size];
+
+  // Query sum of remaining blocks (e.g. r is inside a block)
+  for (; l <= r; ++l)
+    ans += v[l];
+
+  return ans;
+}
+
+/**
+ * Fills block array with necessary data to perform update and query in 
+ * less than linear time.
+ * @param n number of elements of v
+ */
+void preprocess(int n) {
+  block_size = sqrt(n);
+
+  int idx = -1;
+  for (int i = 0; i < n; ++i) {
+    if (i % block_size == 0)
+      block[++idx] = 0;
+
+    block[idx] += v[i];
+  }
+}
diff --git a/contests/Cadernaveis/URI1033.cpp b/contests/Cadernaveis/URI1033.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f85f5ef31ad7d9bac84c95bdeb0d14548c4b211f
--- /dev/null
+++ b/contests/Cadernaveis/URI1033.cpp
@@ -0,0 +1,98 @@
+#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; 
+
+typedef unsigned long long ll;
+typedef pair<int,int> ii;
+
+struct matrix {
+  int N;
+  ll b;
+  vector<vector<ll>> m;
+
+  matrix(int N, ll b) : N(N), b(b) {
+    m = vector<vector<ll>>(N, vector<ll>(N, 0));
+  }
+
+  matrix operator*(matrix a) {
+    matrix res(N, b);
+    for (int i = 0; i < N; i++)
+      for (int j = 0; j < N; j++) {
+        res[i][j] = 0;
+
+        for (int k = 0; k < N; k++)
+          res[i][j] = (((m[i][k] * a[k][j]) % b) + res[i][j]) % b; 
+      }
+    
+    return res;
+  }
+
+  void to_identity() {
+    for (auto &i : m)
+      fill(all(i), 0);
+    for (int i = 0; i < N; ++i)
+      m[i][i] = 1;
+  }
+
+  vector<ll> &operator[](int i) {
+    return m[i];
+  }
+};
+
+ll fast_pow(matrix in, ll n, ll b) {
+  matrix ans(2, b);
+  ans.to_identity();
+
+  while (n) {
+    if (n & 1)
+      ans = ans * in; 
+
+    n >>= 1;
+    in = in * in;
+  }
+
+  return ans[0][0];
+}
+
+ll solve(ll n, ll b) {
+  matrix in(2, b);
+
+  in[0][0] = 1;
+  in[0][1] = 1;
+
+  in[1][0] = 1;
+  in[1][1] = 0;
+
+  return fast_pow(in, n, b);
+}
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  ll n, b;
+  int cas = 1;
+  while (cin >> n >> b && (n || b)) {
+    ll ans = solve(n, b) % b;
+    ans = (ans + ans) % b;
+    ans = (ans - 1 + b) % b;
+
+    cout << "Case " << cas++ << ":" << " " << n << " " << b << " " << ans << ende;
+  }
+
+  return 0;
+}
diff --git a/contests/CodeJam/2018/Qualification/A.cpp b/contests/CodeJam/2018/Qualification/A.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0239075ee7e43f1f0dddc9660e1722e8b31cbe7a
--- /dev/null
+++ b/contests/CodeJam/2018/Qualification/A.cpp
@@ -0,0 +1,69 @@
+#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; 
+
+typedef long long ll;
+typedef pair<int,int> ii;
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int t; cin >> t;
+  for (int cas = 1; cas <= t; ++cas) {
+    int d; cin >> d;
+    string s; cin >> s;
+
+    int n = s.size();
+    vector<ll> v(n);
+
+    int nums = 0;
+    ll curr = 1, sum = 0;
+    for (int i = 0; i < n; ++i) {
+      if (s[i] == 'S') {
+        sum += curr;
+        nums++;
+      } else curr <<= 1;
+
+      v[i] = curr;
+    } 
+
+    cout << "Case #" << cas << ": ";
+    if (nums > d) {
+      cout << "IMPOSSIBLE" << ende;
+      continue;
+    }
+
+    int ans = 0;
+    int i = n - 2;
+    while (sum > d) {
+      if (i <= n - 2 && s[i] == 'C' && s[i+1] == 'S') {
+        sum -= v[i];
+        v[i] >>= 1;
+        sum += v[i];
+        swap(s[i], s[i+1]);
+        ans++;
+        i++;
+      } else
+        i--;
+    }
+
+    cout << ans << ende;
+  }
+
+  return 0;
+}
diff --git a/contests/CodeJam/2018/Qualification/B.cpp b/contests/CodeJam/2018/Qualification/B.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..933ccd199dbd1795d7c083983c0adc07dbb2d7e6
--- /dev/null
+++ b/contests/CodeJam/2018/Qualification/B.cpp
@@ -0,0 +1,65 @@
+#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; 
+
+typedef long long ll;
+typedef pair<int,int> ii;
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int t; cin >> t;
+  for (int cas = 1; cas <= t; ++cas) {
+    int n; cin >> n;
+    vector<int> v(n);
+    for (auto &i : v) cin >> i;
+
+    vector<int> v1, v2;
+    for (int i = 0; i < n; ++i)
+      if (i % 2) v2.pb(v[i]);
+      else v1.pb(v[i]);
+
+    sort(all(v1));
+    sort(all(v2));
+
+    int j = 0;
+    for (auto i : v1) {
+      v[j] = i;
+      j += 2;
+    }
+
+    j = 1;
+    for (auto i : v2) {
+      v[j] = i;
+      j += 2;
+    }
+
+    int ans = -1;
+    for (int i = 0; i < n - 1; ++i) {
+      if (v[i] > v[i+1]) {
+        ans = i;
+        break;
+      }
+    }
+    cout << "Case #" << cas << ": ";
+    if (ans == -1) cout << "OK" << ende;
+    else cout << ans << ende;
+  }
+
+  return 0;
+}
diff --git a/contests/CodeJam/2018/Qualification/C.cpp b/contests/CodeJam/2018/Qualification/C.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9faa1d6ff5b347b2ba787a9a6280c79cadc5d63c
--- /dev/null
+++ b/contests/CodeJam/2018/Qualification/C.cpp
@@ -0,0 +1,80 @@
+#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; 
+
+typedef long long ll;
+typedef pair<int,int> ii;
+
+int v[3][3];
+int m[1001][1001];
+
+bool check() {
+  return (v[0][0] && v[0][1] && v[0][2]);
+}
+
+int count() {
+  int num = 0;
+  for (int i = 0; i < 3; ++i)
+    for (int j = 0; j < 3; ++j)
+      num += !v[i][j];
+  return num;
+}
+
+void move(int &line) {
+  line++;
+
+  for (int i = 0; i < 3; ++i) v[0][i] = v[1][i];
+  for (int i = 0; i < 3; ++i) v[1][i] = v[2][i];
+  for (int i = 0; i < 3; ++i) v[2][i] = 0;
+}
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int t; cin >> t;
+
+  for (int cas = 1; cas <= t; ++cas) {
+    int a; cin >> a;
+    int line = 2;
+    int num = 0;
+    mset(v, 0);
+    mset(m, 0);
+
+    while (true) {
+      while (check() && line < 1000) {
+        if (count() + num >= a) break;
+        move(line);
+      }
+
+      cout << line << " " << 2 << ende;
+      cout << flush;
+      int x, y; cin >> x >> y;
+
+      if (x == 0 && y == 0) 
+        break;
+
+      if (!m[x][y]) num++;
+      m[x][y] = 1;
+
+      assert(x != -1 && y != -1);
+      v[x - line + 1][y - 1] = 1;
+    }
+  }
+
+  return 0;
+}
diff --git a/contests/ICPC_LA17/E.cpp b/contests/ICPC_LA17/E.cpp
index cd14793e21e8cb1b455dd9ac63153d887abe80ec..e6575a3af3fe880483a990d96d54604c9dd043a1 100644
--- a/contests/ICPC_LA17/E.cpp
+++ b/contests/ICPC_LA17/E.cpp
@@ -45,7 +45,6 @@ bool solve(int i, int r) {
   return dp[i][r] = false;
 }
 
-
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
diff --git a/contests/ICPC_LA17/I.cpp b/contests/ICPC_LA17/I.cpp
index 41f470e05d7b966e4649dd9d17a5a60c3116a175..c49145e12a492ca9ec1292a045c78f0015d83167 100644
--- a/contests/ICPC_LA17/I.cpp
+++ b/contests/ICPC_LA17/I.cpp
@@ -33,14 +33,12 @@ void make_set(int x) {
   size[x] = 1;
 }
 
-
 int find_set(int x) {
   if (pare[x] != x)
     pare[x] = find_set(pare[x]);
   return pare[x];
 }
 
-
 void union_set(int x, int y) {
   x = find_set(x);
   y = find_set(y);
@@ -55,7 +53,6 @@ void union_set(int x, int y) {
   size[y] += size[x];
 }
 
-
 int kruskal() {
   sort(all(edges), [&](const iii &a, const iii &b) {
     return a.se < b.se;    
@@ -107,14 +104,12 @@ void dfs(int v, int p = -1, int c = 0) {
       dfs(u.fi, v, u.se);
 }
 
-
 void preprocess(int v) {
   memset(par, -1, sizeof par);
   memset(cost, 0, sizeof cost);
   dfs(v);
 }
 
-
 int query(int p, int q) {
   int ans = 0;
 
@@ -141,7 +136,6 @@ int query(int p, int q) {
   else return max(ans, max(cost[p][0], cost[q][0]));
 }
 
-
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);