#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int N = 100005;
struct two {
  int a, b;
  two(long long a = 0, long long b = 0) : a(a), b(b) {}
  two operator+(const two& y) const {
    return two((a + y.a) % MOD, (b + y.b) % MOD);
  }
};
struct four {
  int a, b, c, d;
  four(long long a = 0, long long b = 0, long long c = 0, long long d = 0)
      : a(a), b(b), c(c), d(d) {}
  four operator*(const four& f) const {
    return four((1ll * a * f.a % MOD + 1ll * b * f.c % MOD) % MOD,
                (1ll * a * f.b % MOD + 1ll * b * f.d % MOD) % MOD,
                (1ll * c * f.a % MOD + 1ll * d * f.c % MOD) % MOD,
                (1ll * c * f.b % MOD + 1ll * d * f.d % MOD) % MOD);
  }
  four operator^(long long e) const {
    four b = *this;
    four a(1, 0, 0, 1);
    while (e > 0) {
      if (e & 1) a = b * a;
      if (e >>= 1) b = b * b;
    }
    return a;
  }
  four operator*(long long k) const {
    return four(a * k % MOD, b * k % MOD, c * k % MOD, d * k % MOD);
  }
  two operator*(const two& f) const {
    return two((1ll * a * f.a % MOD + 1ll * b * f.b % MOD) % MOD,
               (1ll * c * f.a % MOD + 1ll * d * f.b % MOD) % MOD);
  }
  four operator+(const four& f) const {
    return four((a + f.a) % MOD, (b + f.b) % MOD, (c + f.c) % MOD,
                (d + f.d) % MOD);
  }
  friend ostream& operator<<(ostream& out, const four& f) {
    return out << f.a << ' ' << f.b << '\n' << f.c << ' ' << f.d;
  }
};
four fib(1, 1, 1, 0);
int n, q, a[N];
four st[N << 2];
four lz[N << 2];
bool has[N << 2];
four zero(0, 0, 0, 0);
four one(1, 0, 0, 1);
inline void push(int p, int L, int R) {
  if (has[p]) {
    st[p] = lz[p] * st[p];
    if (L != R) {
      lz[(p << 1)] = lz[p] * lz[(p << 1)];
      lz[(p << 1) | 1] = lz[p] * lz[(p << 1) | 1];
      has[(p << 1)] = has[(p << 1) | 1] = true;
    }
    lz[p] = one;
    has[p] = false;
  }
}
inline void pull(int p) { st[p] = st[(p << 1)] + st[(p << 1) | 1]; }
void update(int a, int b, const four& f, int p = 1, int L = 1, int R = n) {
  if (b < L || R < a) return push(p, L, R);
  if (a <= L && R <= b) {
    has[p] = true;
    lz[p] = lz[p] * f;
    return push(p, L, R);
  }
  push(p, L, R);
  update(a, b, f, (p << 1), L, ((L + R) >> 1));
  update(a, b, f, (p << 1) | 1, ((L + R) >> 1) + 1, R);
  pull(p);
}
four query(int a, int b, int p = 1, int L = 1, int R = n) {
  push(p, L, R);
  if (b < L || R < a) return zero;
  if (a <= L && R <= b) return st[p];
  const four& q = query(a, b, (p << 1), L, ((L + R) >> 1)) +
                  query(a, b, (p << 1) | 1, ((L + R) >> 1) + 1, R);
  pull(p);
  return q;
}
void build(int p = 1, int L = 1, int R = n) {
  lz[p] = one;
  has[p] = false;
  if (L == R) {
    st[p] = (fib ^ a[L]);
  } else {
    build((p << 1), L, ((L + R) >> 1));
    build((p << 1) | 1, ((L + R) >> 1) + 1, R);
    pull(p);
  }
}
int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  build();
  int tp, l, r, x;
  while (q--) {
    scanf("%d", &tp);
    if (tp == 1) {
      scanf("%d%d%d", &l, &r, &x);
      update(l, r, (fib ^ x));
    } else if (tp == 2) {
      scanf("%d%d", &l, &r);
      int ans = (query(l, r) * two(1, 0)).b;
      printf("%d\n", (int)((ans + MOD) % MOD));
    } else
      assert(false);
  }
}
