#include <bits/stdc++.h>
using namespace std;
struct Kake {
  long long a, b, c, d;
  const Kake operator+(const Kake x) {
    return Kake{(a + x.a) % 1000000007LL, (b + x.b) % 1000000007LL,
                (c + x.c) % 1000000007LL, (d + x.d) % 1000000007LL};
  }
  const Kake operator*(const Kake x) {
    return Kake{
        (a * x.a + b * x.c) % 1000000007LL, (a * x.b + b * x.d) % 1000000007LL,
        (c * x.a + d * x.c) % 1000000007LL, (c * x.b + d * x.d) % 1000000007LL};
  }
  const bool operator!=(const Kake x) {
    return (x.a != a || x.b != b || x.c != c || x.d != d);
  }
};
Kake seg_tree[262144 * 4];
Kake lazy_tree[262144 * 4];
Kake powing(int n) {
  Kake base = Kake{1, 1, 1, 0};
  Kake ans = Kake{1, 0, 0, 1};
  while (n != 0) {
    if (n % 2 == 1) {
      ans = ans * base;
    }
    base = base * base;
    n /= 2;
  }
  return ans;
}
void seg_set(int now);
void merge(int now) {
  seg_tree[now] = seg_tree[now] * lazy_tree[now];
  lazy_tree[now * 2] = lazy_tree[now * 2] * lazy_tree[now];
  lazy_tree[now * 2 + 1] = lazy_tree[now * 2 + 1] * lazy_tree[now];
  lazy_tree[now] = Kake{1, 0, 0, 1};
  seg_set(now / 2);
}
void seg_set(int now) {
  if (now == 0) return;
  if (lazy_tree[now * 2] != Kake{1, 0, 0, 1}) merge(now * 2);
  if (lazy_tree[now * 2 + 1] != Kake{1, 0, 0, 1}) merge(now * 2 + 1);
  seg_tree[now] = seg_tree[now * 2] + seg_tree[now * 2 + 1];
  if (now >= 2) {
    seg_set(now / 2);
  }
}
Kake seg_find(int now, int n_l, int n_r, int w_l, int w_r, Kake setting) {
  if (w_l <= n_l && n_r <= w_r) {
    lazy_tree[now] = lazy_tree[now] * setting;
  }
  merge(now);
  if (w_l <= n_l && n_r <= w_r) {
    return seg_tree[now];
  }
  if (w_r <= n_l || n_r <= w_l) {
    return Kake{0, 0, 0, 0};
  }
  return seg_find(now * 2, n_l, (n_l + n_r) / 2, w_l, w_r, setting) +
         seg_find(now * 2 + 1, (n_l + n_r) / 2, n_r, w_l, w_r, setting);
}
int main() {
  iostream::sync_with_stdio(false);
  long long n, m;
  cin >> n >> m;
  for (long long i = 0; i < n; ++i) {
    long long a;
    cin >> a;
    a--;
    seg_tree[i + 262144] = powing(a);
  }
  for (long long q = 0; q < 262144 * 4; ++q) {
    lazy_tree[q] = Kake{1, 0, 0, 1};
  }
  for (long long i = 262144 - 1; i >= 0; --i) {
    seg_tree[i] = seg_tree[i * 2] + seg_tree[i * 2 + 1];
  }
  for (long long i = 0; i < m; ++i) {
    long long a;
    cin >> a;
    if (a == 2) {
      long long b, c;
      cin >> b >> c;
      Kake ans = seg_find(1, 0, 262144, b - 1, c, Kake{1, 0, 0, 1});
      cout << ans.a << endl;
    } else {
      long long b, c, d;
      cin >> b >> c >> d;
      seg_find(1, 0, 262144, b - 1, c, powing(d));
    }
  }
}
