func_code_string: #include <bits/stdc++.h>   using namespace std;   const int N = 1e5 + 100;   const int Mod = 1e9 + 7;   struct Mat {     long long A[2][2];     Mat() { memset(A, 0, sizeof(A)); }     void init(void) {       for (int i = 0; i < 2; i++)         for (int j = 0; j < 2; j++) A[i][j] = (i == j);     }     Mat operator+(struct Mat A) {       struct Mat B;       for (int i = 0; i < 2; i++) {         for (int j = 0; j < 2; j++) {           B.A[i][j] = this->A[i][j] + A.A[i][j];           B.A[i][j] %= Mod;         }       }       return B;     }     Mat operator*(struct Mat A) {       struct Mat B;       for (int i = 0; i < 2; i++) {         for (int j = 0; j < 2; j++) {           for (int k = 0; k < 2; k++) {             B.A[i][j] += (this->A[i][k] * A.A[k][j]);             B.A[i][j] %= Mod;           }         }       }       return B;     }     Mat operator^(int t) {       struct Mat A, B;       A.init();       for (int i = 0; i < 2; i++)         for (int j = 0; j < 2; j++) B.A[i][j] = this->A[i][j];       while (t) {         if (t & 1) A = A * B;         t >>= 1;         B = B * B;       }       return A;     }   };   struct Mat Tree[N << 2], Laze[N << 2], f;   int A[N];   void pushUp(int n) { Tree[n] = (Tree[n << 1] + Tree[n << 1 | 1]); }   void pushDown(int n) {     Tree[n << 1] = Laze[n] * Tree[n << 1];     Tree[n << 1 | 1] = Laze[n] * Tree[n << 1 | 1];     Laze[n << 1] = Laze[n] * Laze[n << 1];     Laze[n << 1 | 1] = Laze[n] * Laze[n << 1 | 1];     Laze[n].init();   }   void build(int l, int r, int rt) {     Laze[rt].init();     if (l == r) {       Tree[rt] = f ^ (A[l] - 1);       return;     }     int mid = (l + r) >> 1;     build(l, mid, rt << 1);     build(mid + 1, r, rt << 1 | 1);     pushUp(rt);   }   void update(int l, int r, int rt, int _l, int _r, struct Mat x) {     if (l >= _l && r <= _r) {       Tree[rt] = x * Tree[rt];       Laze[rt] = x * Laze[rt];       return;     }     pushDown(rt);     int mid = (l + r) >> 1;     if (_r <= mid) {       update(l, mid, rt << 1, _l, _r, x);     } else if (_l > mid) {       update(mid + 1, r, rt << 1 | 1, _l, _r, x);     } else {       update(l, mid, rt << 1, _l, _r, x);       update(mid + 1, r, rt << 1 | 1, _l, _r, x);     }     pushUp(rt);   }   int query(int l, int r, int rt, int _l, int _r) {     if (l >= _l && r <= _r) {       return Tree[rt].A[0][0];     }     pushDown(rt);     int mid = (l + r) >> 1;     if (_r <= mid) {       return query(l, mid, rt << 1, _l, _r);     } else if (_l > mid) {       return query(mid + 1, r, rt << 1 | 1, _l, _r);     }     return (query(l, mid, rt << 1, _l, _r) +             query(mid + 1, r, rt << 1 | 1, _l, _r)) %            Mod;   }   int main(void) {     int n, m;     for (int i = 0; i < 2; i++)       for (int j = 0; j < 2; j++) f.A[i][j] = 1;     f.A[1][1] = 0;     cin >> n >> m;     for (int i = 1; i <= n; i++) {       cin >> A[i];     }     build(1, n, 1);     while (m--) {       int type, l, r;       cin >> type >> l >> r;       if (type == 1) {         int x;         cin >> x;         update(1, n, 1, l, r, f ^ x);       } else if (type == 2) {         cout << query(1, n, 1, l, r) << endl;       }     }     return 0;   }   