#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
int a[100010];
struct Mat {
  int a[2][2];
  void clear() { memset(a, 0, sizeof(a)); }
  void one() {
    a[0][0] = a[1][1] = 1;
    a[0][1] = a[1][0] = 0;
  }
  Mat operator+(const Mat &b) const {
    Mat tmp;
    tmp.clear();
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        tmp.a[i][j] = a[i][j] + b.a[i][j];
        if (tmp.a[i][j] >= MOD) {
          tmp.a[i][j] -= MOD;
        }
      }
    }
    return tmp;
  }
  Mat operator*(const Mat &b) const {
    Mat tmp;
    tmp.clear();
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2; k++) {
          tmp.a[i][k] += (long long)a[i][j] * b.a[j][k] % MOD;
          if (tmp.a[i][k] >= MOD) {
            tmp.a[i][k] -= MOD;
          }
        }
      }
    }
    return tmp;
  }
  Mat pw(int x) {
    Mat ans, num = *this;
    ans.one();
    while (x > 0) {
      if (x & 1) {
        ans = ans * num;
      }
      num = num * num;
      x >>= 1;
    }
    return ans;
  }
};
struct Tree {
  int l, r;
  Mat sum;
  Mat mult;
};
Tree seg[400010];
Mat fibo, tmp;
void build(int id, int l, int r) {
  seg[id].l = l;
  seg[id].r = r;
  seg[id].sum.clear();
  seg[id].mult.one();
  if (l == r) {
    seg[id].sum = fibo.pw(a[l] - 1);
  } else {
    int mid = (l + r) >> 1;
    build(id * 2, l, mid);
    build(id * 2 + 1, mid + 1, r);
    seg[id].sum = seg[id * 2].sum + seg[id * 2 + 1].sum;
  }
}
void Down(int id) {
  seg[id * 2].sum = seg[id * 2].sum * seg[id].mult;
  seg[id * 2].mult = seg[id * 2].mult * seg[id].mult;
  seg[id * 2 + 1].sum = seg[id * 2 + 1].sum * seg[id].mult;
  seg[id * 2 + 1].mult = seg[id * 2 + 1].mult * seg[id].mult;
  seg[id].mult.one();
}
void update(int id, int l, int r) {
  if (seg[id].r < l || seg[id].l > r) return;
  if (seg[id].l >= l && seg[id].r <= r) {
    seg[id].sum = seg[id].sum * tmp;
    seg[id].mult = seg[id].mult * tmp;
    return;
  }
  Down(id);
  update(id * 2, l, r);
  update(id * 2 + 1, l, r);
  seg[id].sum = seg[id * 2].sum + seg[id * 2 + 1].sum;
}
Mat query(int id, int l, int r) {
  if (seg[id].r < l || seg[id].l > r) {
    Mat res;
    res.clear();
    return res;
  }
  if (seg[id].l >= l && seg[id].r <= r) {
    return seg[id].sum;
  }
  Down(id);
  return query(id * 2, l, r) + query(id * 2 + 1, l, r);
}
int main() {
  fibo.a[0][0] = fibo.a[0][1] = fibo.a[1][0] = 1;
  fibo.a[1][1] = 0;
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  build(1, 1, n);
  for (int i = 0; i < m; i++) {
    int ope;
    scanf("%d", &ope);
    if (ope == 1) {
      int l, r, x;
      scanf("%d%d%d", &l, &r, &x);
      tmp = fibo;
      tmp = tmp.pw(x);
      update(1, l, r);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      Mat res = query(1, l, r);
      printf("%d\n", (res.a[0][0]) % MOD);
    }
  }
  return 0;
}
