#include <bits/stdc++.h>
long long N = 1e9 + 7, dpl;
long long a[1000000], lp[1000000];
using namespace std;
class matrix {
 public:
  long long a[2][2];
  void mod() {
    a[0][0] = a[0][0] % N;
    a[0][1] = a[0][1] % N;
    a[1][0] = a[1][0] % N;
    a[1][1] = a[1][1] % N;
  }
  matrix() {
    a[0][0] = 0;
    a[0][1] = 0;
    a[1][0] = 0;
    a[1][1] = 0;
  }
  matrix operator+(matrix x) {
    matrix t;
    t.a[0][0] = a[0][0] + x.a[0][0];
    t.a[1][0] = a[1][0] + x.a[1][0];
    t.a[0][1] = a[0][1] + x.a[0][1];
    t.a[1][1] = a[1][1] + x.a[1][1];
    t.mod();
    return t;
  }
  matrix operator*(matrix x) {
    matrix t;
    t.a[0][0] = a[0][0] * x.a[0][0] + a[0][1] * x.a[1][0];
    t.a[0][1] = a[0][0] * x.a[0][1] + a[0][1] * x.a[1][1];
    t.a[1][0] = a[1][0] * x.a[0][0] + a[1][1] * x.a[1][0];
    t.a[1][1] = a[1][0] * x.a[0][1] + a[1][1] * x.a[1][1];
    t.mod();
    return t;
  }
  pair<long long, long long> operator*(pair<long long, long long> x) {
    pair<long long, long long> t;
    t.first = (a[0][0] * x.first + a[0][1] * x.second) % N;
    t.second = (a[1][0] * x.first + a[1][1] * x.second) % N;
    return t;
  }
} I, F, pwr[1000000];
pair<long long, long long> seg_tree[1000000];
matrix power(long long x) {
  if (x == 0) return I;
  if (x < dpl) return pwr[x];
  matrix t = power(x / 2);
  t = t * t;
  if (x & 1) t = t * F;
  return t;
}
void build(long long l, long long r, long long p) {
  if (l > r) return;
  if (l == r) {
    seg_tree[p] = power(a[l]) * make_pair(0, 1);
    return;
  }
  long long mid = (l + r) / 2;
  build(l, mid, 2 * p);
  build(mid + 1, r, 2 * p + 1);
  seg_tree[p].first = (seg_tree[2 * p].first + seg_tree[2 * p + 1].first) % N;
  seg_tree[p].second =
      (seg_tree[2 * p].second + seg_tree[2 * p + 1].second) % N;
}
void update(long long l, long long r, long long p, long long i, long long j,
            long long x) {
  if (i > j) return;
  if (lp[p]) {
    seg_tree[p] = power(lp[p]) * seg_tree[p];
    if (i < j)
      lp[2 * p] = (lp[2 * p] + lp[p]), lp[2 * p + 1] = (lp[2 * p + 1] + lp[p]);
    lp[p] = 0;
  }
  if (l > j or r < i) return;
  if (l <= i and j <= r) {
    seg_tree[p] = power(x) * seg_tree[p];
    if (i < j) lp[2 * p] = (lp[2 * p] + x), lp[2 * p + 1] = (lp[2 * p + 1] + x);
    return;
  }
  long long mid = (i + j) / 2;
  update(l, r, 2 * p, i, mid, x);
  update(l, r, 2 * p + 1, mid + 1, j, x);
  seg_tree[p].first = (seg_tree[2 * p].first + seg_tree[2 * p + 1].first) % N;
  seg_tree[p].second =
      (seg_tree[2 * p].second + seg_tree[2 * p + 1].second) % N;
}
long long query(long long l, long long r, long long p, long long i,
                long long j) {
  if (i > j) return 0;
  if (lp[p]) {
    seg_tree[p] = power(lp[p]) * seg_tree[p];
    if (i < j)
      lp[2 * p] = (lp[2 * p] + lp[p]), lp[2 * p + 1] = (lp[2 * p + 1] + lp[p]);
    lp[p] = 0;
  }
  if (l > j or r < i) return 0;
  if (l <= i and j <= r) return seg_tree[p].first;
  long long mid = (i + j) / 2, ans = 0;
  ans = query(l, r, 2 * p, i, mid);
  ans += query(l, r, 2 * p + 1, mid + 1, j);
  ans = ans % N;
  return ans;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  I.a[0][0] = 1;
  I.a[1][1] = 1;
  F.a[0][0] = 1;
  F.a[0][1] = 1;
  F.a[1][0] = 1;
  dpl = 1;
  while (dpl < 1000000) {
    pwr[dpl] = power(dpl);
    dpl++;
  }
  long long n, m, i, t, l, r, x;
  cin >> n >> m;
  for (i = 1; i <= n; i++) cin >> a[i];
  build(1, n, 1);
  while (m--) {
    cin >> t >> l >> r;
    if (t == 1) {
      cin >> x;
      update(l, r, 1, 1, n, x);
    } else
      cout << query(l, r, 1, 1, n) << endl;
  }
  return 0;
}
