#include <bits/stdc++.h>   using namespace std;   const int INF = 1e9;   const long long mod = 1e9 + 7;   int n;   vector<long long> arr;   vector<pair<vector<long long>, vector<long long> > > segTree;   vector<long long> source(4, 1);   vector<long long> e(4);   vector<long long> multVec(const vector<long long>& vec,                             const vector<long long>& mat) {     vector<long long> result(2);     result[0] = (vec[0] * mat[0] + vec[1] * mat[2]) % mod;     result[1] = (vec[0] * mat[1] + vec[1] * mat[3]) % mod;     return result;   }   vector<long long> multMat(const vector<long long>& a,                             const vector<long long>& b) {     vector<long long> result(4);     result[0] = (a[0] * b[0] + a[1] * b[2]) % mod;     result[1] = (a[0] * b[1] + a[1] * b[3]) % mod;     result[2] = (a[2] * b[0] + a[3] * b[2]) % mod;     result[3] = (a[2] * b[1] + a[3] * b[3]) % mod;     return result;   }   vector<long long> binPow(vector<long long> a, long long b) {     if (b == 0) {       return e;     }     return multMat(binPow(multMat(a, a), b / 2), (b % 2 ? a : e));   }   vector<long long> fib(int idx) {     vector<long long> res(2, 1);     return multVec(res, binPow(source, idx - 1));   }   vector<long long> operator+(const vector<long long>& a,                               const vector<long long>& b) {     vector<long long> result(2);     for (int i = 0; i < 2; i++) {       result[i] = (a[i] + b[i]) % mod;     }     return result;   }   void build(int lf, int rg, int cell) {     segTree[cell].second = e;     if (lf + 1 == rg) {       segTree[cell].first = fib(arr[lf]);       return;     }     int middle = (lf + rg) >> 1;     build(lf, middle, (cell << 1) + 1);     build(middle, rg, (cell << 1) + 2);     segTree[cell].first =         segTree[(cell << 1) + 1].first + segTree[(cell << 1) + 2].first;   }   void push(int cell) {     if (segTree[cell].second != e) {       segTree[(cell << 1) + 1].first =           multVec(segTree[(cell << 1) + 1].first, segTree[cell].second);       segTree[(cell << 1) + 1].second =           multMat(segTree[(cell << 1) + 1].second, segTree[cell].second);       segTree[(cell << 1) + 2].first =           multVec(segTree[(cell << 1) + 2].first, segTree[cell].second);       segTree[(cell << 1) + 2].second =           multMat(segTree[(cell << 1) + 2].second, segTree[cell].second);       segTree[cell].second = e;     }   }   void update(int lf, int rg, int a, int b, const vector<long long>& mat,               int cell) {     if (a >= b) {       return;     }     if (lf == a && rg == b) {       segTree[cell].first = multVec(segTree[cell].first, mat);       segTree[cell].second = multMat(segTree[cell].second, mat);       return;     }     push(cell);     int middle = (lf + rg) >> 1;     update(lf, middle, a, min(b, middle), mat, (cell << 1) + 1);     update(middle, rg, max(a, middle), b, mat, (cell << 1) + 2);     segTree[cell].first =         segTree[(cell << 1) + 1].first + segTree[(cell << 1) + 2].first;   }   vector<long long> require(int lf, int rg, int a, int b, int cell) {     if (a >= b) {       return vector<long long>(2, 0);     }     if (lf == a && rg == b) {       return segTree[cell].first;     }     push(cell);     int middle = (lf + rg) >> 1;     return require(lf, middle, a, min(b, middle), (cell << 1) + 1) +            require(middle, rg, max(a, middle), b, (cell << 1) + 2);   }   void solve() {     int m;     cin >> n >> m;     arr.resize(n);     for (int i = 0; i < n; i++) {       scanf( %I64d , &arr[i]);     }     source[0] = 0;     e[0] = e[3] = 1;     segTree.resize(4 * n);     build(0, n, 0);     for (int i = 0; i < m; i++) {       int type;       scanf( %d , &type);       if (type == 1) {         int lf, rg;         long long x;         scanf( %d%d%I64d , &lf, &rg, &x);         update(0, n, lf - 1, rg, binPow(source, x), 0);       } else {         int lf, rg;         scanf( %d%d , &lf, &rg);         printf( %I64d n , require(0, n, lf - 1, rg, 0)[0]);       }     }   }   int main() {     solve();     return 0;   }