#include <bits/stdc++.h>
using namespace std;
unsigned long long p = 1000000007LL;
struct table {
  unsigned long long t[2][2] = {{0}};
  unsigned long long line, row;
};
table F1, F2, A, UNIT, NOW;
table operator*(table t1, table t2) {
  table ans;
  ans.line = t1.line;
  ans.row = t2.row;
  for (unsigned long long i = 0; i < ans.line; i++)
    for (unsigned long long j = 0; j < ans.row; j++)
      for (unsigned long long k = 0; k < t1.row; k++)
        ans.t[i][j] = (ans.t[i][j] + t1.t[i][k] * t2.t[k][j]) % p;
  return ans;
}
table operator+(table t1, table t2) {
  table ans;
  ans.line = t1.line;
  ans.row = t2.row;
  for (unsigned long long i = 0; i < ans.line; i++)
    for (unsigned long long j = 0; j < ans.row; j++)
      ans.t[i][j] = (t1.t[i][j] + t2.t[i][j]) % p;
  return ans;
}
table qpow(table t, unsigned long long up) {
  table ans, tmp = t;
  while (up) {
    if (up & 1) {
      ans = tmp;
      tmp = tmp * tmp;
      up >>= 1;
      break;
    }
    tmp = tmp * tmp;
    up >>= 1;
  }
  while (up) {
    if (up & 1) ans = ans * tmp;
    tmp = tmp * tmp;
    up >>= 1;
  }
  return ans;
}
table gettable(int up) {}
struct node {
  table v, delta;
} t[4 * 100010];
unsigned long long num[100010];
bool check(unsigned long long l, unsigned long long r, unsigned long long ll,
           unsigned long long rr) {
  return (l < rr && r > ll) || (ll < r && rr > l);
}
void build(unsigned long long cur, unsigned long long ll,
           unsigned long long rr) {
  t[cur].delta = UNIT;
  if (ll + 1 == rr) {
    if (num[ll] == 1)
      t[cur].v = F1;
    else if (num[ll] == 2)
      t[cur].v = F2;
    else
      t[cur].v = qpow(A, num[ll] - 2) * F2;
    return;
  }
  unsigned long long mid = (ll + rr) >> 1;
  if (ll < mid) build((cur << 1) + 1, ll, mid);
  if (mid < rr) build((cur << 1) + 2, mid, rr);
  if (ll < mid && mid < rr)
    t[cur].v = t[(cur << 1) + 1].v + t[(cur << 1) + 2].v;
  else if (ll < mid)
    t[cur].v = t[(cur << 1) + 1].v;
  else
    t[cur].v = t[(cur << 1) + 2].v;
}
void update(unsigned long long cur, bool IsLeaf) {
  t[cur].v = t[cur].delta * t[cur].v;
  if (!IsLeaf) {
    t[(cur << 1) + 1].delta = t[cur].delta * t[(cur << 1) + 1].delta;
    t[(cur << 1) + 2].delta = t[cur].delta * t[(cur << 1) + 2].delta;
  }
  t[cur].delta = UNIT;
}
void add(unsigned long long cur, unsigned long long l, unsigned long long r,
         unsigned long long ll, unsigned long long rr) {
  if (l <= ll && rr <= r) {
    t[cur].delta = NOW * t[cur].delta;
    return;
  }
  unsigned long long mid = (ll + rr) >> 1;
  if (check(l, r, ll, mid)) add((cur << 1) + 1, l, r, ll, mid);
  if (check(l, r, mid, rr)) add((cur << 1) + 2, l, r, mid, rr);
  if (ll < mid) update((cur << 1) + 1, ll + 1 == mid);
  if (mid < rr) update((cur << 1) + 2, mid + 1 == rr);
  if (ll < mid && mid < rr)
    t[cur].v = t[(cur << 1) + 1].v + t[(cur << 1) + 2].v;
  else if (ll < mid)
    t[cur].v = t[(cur << 1) + 1].v;
  else
    t[cur].v = t[(cur << 1) + 2].v;
}
unsigned long long query(unsigned long long cur, unsigned long long l,
                         unsigned long long r, unsigned long long ll,
                         unsigned long long rr) {
  update(cur, ll + 1 == rr);
  if (l <= ll && rr <= r) return t[cur].v.t[0][0];
  unsigned long long ans = 0, mid = (ll + rr) >> 1;
  if (check(l, r, ll, mid)) ans += query((cur << 1) + 1, l, r, ll, mid);
  if (check(l, r, mid, rr)) ans += query((cur << 1) + 2, l, r, mid, rr);
  return ans % p;
}
unsigned long long n, m;
int main() {
  F1.line = 2;
  F1.row = 1;
  F1.t[0][0] = 1;
  F1.t[1][0] = 0;
  F2.line = 2;
  F2.row = 1;
  F2.t[0][0] = 1;
  F2.t[1][0] = 1;
  A.line = 2;
  A.row = 2;
  A.t[0][0] = 1;
  A.t[0][1] = 1;
  A.t[1][0] = 1;
  A.t[1][1] = 0;
  UNIT.line = 2;
  UNIT.row = 2;
  UNIT.t[0][0] = 1;
  UNIT.t[0][1] = 0;
  UNIT.t[1][0] = 0;
  UNIT.t[1][1] = 1;
  cin >> n >> m;
  unsigned long long i, a, b, c, todo;
  for (i = 1; i <= n; i++) cin >> num[i];
  build(0, 1, n + 1);
  for (i = 0; i < m; i++) {
    cin >> todo;
    if (todo == 1) {
      cin >> a >> b >> c;
      NOW = qpow(A, c);
      add(0, a, b + 1, 1, n + 1);
    }
    if (todo == 2) {
      cin >> a >> b;
      cout << query(0, a, b + 1, 1, n + 1) << endl;
    }
  }
}
