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 ab09b06bc5432ac2c33df522264bcce1c410d724..951517043c4af58afd163791b6d4e49002ad5cf7 100644
--- a/algorithms/math/matrix.cpp
+++ b/algorithms/math/matrix.cpp
@@ -2,20 +2,21 @@
  * 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));
+    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));
+    m = vector<vector<T>>(r, vector<T>(c, 0));
   }
 
   matrix operator*(matrix a) {
-    assert(r == a.c && c = a.r);
+    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);
-  }
 };