#include<bits/stdc++.h>
#define ts cout<<"ok"<<endl
#define int long long
#define hh puts("")
#define mo 1000000000
#define ls(x) ((x)<<1)
#define rs(x) ((x)<<1|1)
using namespace std;
int n,m,sum[1000005],f[1000005],tag[1000005];
int s1[1000005],s2[1000005];
//维护区间s1=a_l*f0+a_{l+1}*f1+a_{l+1}*f2
//s2=a_l*f1+a_{l+1}*f2+a_{l+1}*f3
inline int read(){
    int ret=0,ff=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') ff=-ff;ch=getchar();}
    while(isdigit(ch)){ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
    return ret*ff;
}
void write(int x){
    if(x>9) write(x/10);
    putchar(x%10+48);
}
inline int calc(int k,int len){
	if(!len) return s1[k];
	if(len==1) return s2[k];
	return (s1[k]*f[len-2]%mo+s2[k]*f[len-1]%mo)%mo;
}
void push_up(int l,int r,int k){
	int mid=(l+r)>>1;
	s1[k]=(s1[ls(k)]+calc(rs(k),mid-l+1))%mo;
	s2[k]=(s2[ls(k)]+calc(rs(k),mid-l+2))%mo;
}
inline void add(int l,int r,int k,int v){
	tag[k]=(tag[k]+v)%mo;
	s1[k]=(s1[k]+sum[r-l]*v%mo)%mo;
	s2[k]=(s2[k]+(sum[r-l+1]+mo-1)%mo*v%mo)%mo;
}
inline void push_down(int l,int r,int k){
	if(!tag[k]) return;
	int mid=(l+r)>>1;
	add(l,mid,ls(k),tag[k]);
	add(mid+1,r,rs(k),tag[k]);
	tag[k]=0;
}
void build(int l,int r,int x,int v,int k){
	if(l==r){
		s1[k]=s2[k]=v;
		return;
	}
	push_down(l,r,k);
	int mid=(l+r)>>1;
	if(x<=mid) build(l,mid,x,v,ls(k));
	else build(mid+1,r,x,v,rs(k));
	push_up(l,r,k);
}
inline int query(int l,int r,int x,int y,int k){
	if(x<=l&&r<=y) return calc(k,l-x);
	push_down(l,r,k);
	int mid=(l+r)>>1,res=0;
	if(x<=mid) res=(res+query(l,mid,x,y,ls(k)))%mo;
	if(mid+1<=y) res=(res+query(mid+1,r,x,y,rs(k)))%mo;
	return res;
}
void update(int l,int r,int x,int y,int v,int k){
	if(x<=l&&r<=y){
		add(l,r,k,v);
		return;
	}
	push_down(l,r,k);
	int mid=(l+r)>>1;
	if(x<=mid) update(l,mid,x,y,v,ls(k));
	if(mid+1<=y) update(mid+1,r,x,y,v,rs(k));
	push_up(l,r,k);
}
signed main(){

	n=read(),m=read();
	f[0]=f[1]=1;
	sum[0]=1;
	sum[1]=2;
	for(int i=2;i<=1000000;i++){
		f[i]=(f[i-1]+f[i-2])%mo;
		sum[i]=(sum[i-1]+f[i])%mo;
	}
	for(int i=1;i<=n;i++){
		int x=read();
		build(1,n,i,x,1);
	}
	while(m--){
		int opt=read();
		if(opt==1){
			int x=read(),v=read();
			build(1,n,x,v,1);
		}
		else if(opt==2){
			int l=read(),r=read();
			write(query(1,n,l,r,1)),hh;
		}
		else if(opt==3){
			int l=read(),r=read(),v=read();
			update(1,n,l,r,v,1);
		}
	}
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <functional>
#include <algorithm>
#include <iostream>
#include <memory.h>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <assert.h>
#include <bitset>
#include <string>
#include <cstdio>
#include <math.h>
#include <complex>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <set>
#include <bitset>
#include <map>
using namespace std;

typedef complex<double> base;

#define int64 long long
#define TASK ""
#define mp make_pair
#define pub push_back

#ifdef _DEBUG
const int N = 2000010;
#else
const int N = 2000010;
#endif

const int MOD = 1e9;

struct Node
{
    int f1, f2, sum1, sum2, upd, cnt;
    Node()
    {
        f1 = f2 = sum1 = sum2 = 0;
        upd = 0;
        cnt = 0;
    }
    Node(int x)
    {
        f1 = f2 = 1;
        sum1 = sum2 = x;
        cnt = 1;
        upd = 0;
    }
    Node(int f1, int f2, int sum1, int sum2, int upd, int cnt) : f1(f1), f2(f2), sum1(sum1), sum2(sum2), upd(upd), cnt(cnt){}
};

int n, m, a[N], f[N];
Node t[4 * N];

void add(int &a, int b)
{
    a += b;
    if (a >= MOD) a -= MOD;
}

int sum(int a, int b)
{
    return (a + b) % MOD;
}

int product(int a, int b)
{
    return (1ll * a * b) % MOD;
}

void mult(int &a, int b)
{
    a = (1ll * a * b) % MOD;
}

int get(int sum1, int sum2, int k)
{
    if (k == 0) return sum1;
    if (k == 1) return sum2;
    return sum(product(f[k - 1], sum2), product(f[k - 2], sum1));
}

Node merge(const Node &v1, const Node &v2)
{
    Node res = Node();
    res.cnt = v1.cnt + v2.cnt;
    res.f1 = sum(v1.f1, get(v2.f1, v2.f2, v1.cnt));
    res.f2 = sum(v1.f2, get(v2.f1, v2.f2, v1.cnt + 1));
    res.sum1 = sum(v1.sum1, get(v2.sum1, v2.sum2, v1.cnt));
    res.sum2 = sum(v1.sum2, get(v2.sum1, v2.sum2, v1.cnt + 1));
    res.upd = 0;
    return res;
}

void build(int v, int tl, int tr)
{
    if (tl == tr)
    {
        t[v] = Node(a[tl]);
        return;
    }
    int tm = (tl + tr) / 2;
    build(v * 2, tl, tm);
    build(v * 2 + 1, tm + 1, tr);
    t[v] = merge(t[v * 2], t[v * 2 + 1]);
}

void addNode(Node &v, int x)
{
    add(v.upd, x);
    add(v.sum1, product(x, v.f1));
    add(v.sum2, product(x, v.f1));
}

void push(int v)
{
    if (t[v].upd != 0)
    {
        addNode(t[v * 2], t[v].upd);
        addNode(t[v * 2 + 1], t[v].upd);
        t[v].upd = 0;
    }
}

void update(int v, int tl, int tr, int l, int r, int x)
{
    if (l > r) return;
    if (l == tl && r == tr)
    {
        addNode(t[v], x);
        return;
    }
    push(v);
    int tm = (tl + tr) / 2;
    update(v * 2, tl, tm, l, min(r, tm), x);
    update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, x);
    t[v] = merge(t[v * 2], t[v * 2 + 1]);
}

void assign(int v, int tl, int tr, int pos, int val)
{
    if (tl == tr)
    {
        t[v] = Node(val);
        return;
    }
    push(v);
    int tm = (tl + tr) / 2;
    if (pos <= tm) assign(v * 2, tl, tm, pos, val);
    else assign(v * 2 + 1, tm + 1, tr, pos, val);
    t[v] = merge(t[v * 2], t[v * 2 + 1]);
}

Node get(int v, int tl, int tr, int l, int r)
{
    if (l > r) return Node();
    if (l == tl && r == tr)
    {
        return t[v];
    }
    push(v);
    int tm = (tl + tr) / 2;
    return merge(get(v * 2, tl, tm, l, min(r, tm)),
                 get(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}

void calc()
{
    f[0] = 1;
    f[1] = 1;
    for (int i = 2; i <= n; i++) f[i] = sum(f[i - 1], f[i - 2]);
}

int main()
{
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    calc();
    build(1, 1, n);
    for (int i = 1; i <= m; i++)
    {
        int type;
        scanf("%d", &type);
        if (type == 1)
        {
            int x, v;
            scanf("%d%d", &x, &v);
            assign(1, 1, n, x, v);
        }
        else if (type == 2)
        {
            int l, r;
            scanf("%d%d", &l, &r);
            printf("%d\n", get(1, 1, n, l, r).sum1);
        }
        else
        {
            int l, r, d;
            scanf("%d%d%d", &l, &r, &d);
            update(1, 1, n, l, r, d);
        }
    }
	return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d\n",__LINE__)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#define int long long
#define D double
#define inf 123456789
#define mod 1000000000
il int read() {
    re int x = 0, f = 1; re char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
    return x * f;
}
#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define drep(i, s, t) for(re int i = t; i >= s; -- i)
#define Next(i, u) for(re int i = head[u]; i; i = e[i].next)
#define mem(k, p) memset(k, p, sizeof(k))
#define lb(x) (x)&(-(x))
#define ls k * 2
#define rs k * 2 + 1
#define _ 200005
int n, m, a[_], f[_], val1[_ << 2], val[_ << 2], tag[_ << 2], sum[_];
il void updata(int k, int l, int r) {
	val[k] = (val[k] + 1ll * tag[k] * sum[r - l] % mod) % mod;
	val1[k] = (val1[k] + 1ll * tag[k] * (sum[r - l + 1] - 1) % mod) % mod;
}
il void pushdown(int k, int l, int r) {
	if(tag[k] == 0) return;
	int mid = (l + r) >> 1;
	tag[ls] = (tag[ls] + tag[k]) % mod, tag[rs] = (tag[rs] + tag[k]) % mod;
	updata(ls, l, mid), updata(rs, mid + 1, r), tag[k] = 0;
}
il void pushup(int k, int l, int r) {
	int mid = (l + r) >> 1, d = mid - l + 1;
	val[k] = (val[ls] + (d >= 2) * f[d - 2] * val[rs] % mod + f[d - 1] * val1[rs] % mod) % mod;
	val1[k] = (val1[ls] + f[d - 1] * val[rs] % mod + f[d] * val1[rs] % mod) % mod;
}
il void build(int k, int l, int r) {
	if(l == r) return(void)(val[k] = val1[k] = a[l]);
	int mid = (l + r) >> 1;
	build(ls, l, mid), build(rs, mid + 1, r), pushup(k, l, r);
}
il void change(int k, int l, int r, int x, int v) {
	if(l == r) return(void)(val[k] = val1[k] = v);
	int mid = (l + r) >> 1;
	pushdown(k, l, r);
	if(x <= mid) change(ls, l, mid, x, v);
	else change(rs, mid + 1, r, x, v);
	pushup(k, l, r);
}
il int query(int k, int l, int r, int ll, int rr) {
	if(l >= ll && r <= rr) {
		int d = l - ll;
		if(d == 0) return val[k];
		if(d == 1) return val1[k];
		return (f[d - 2] * val[k] % mod + f[d - 1] * val1[k] % mod) % mod;
	}
	int mid = (l + r) >> 1, ans = 0;
	pushdown(k, l, r);
	if(ll <= mid) ans = query(ls, l, mid, ll, rr);
	if(mid < rr) ans = (ans + query(rs, mid + 1, r, ll, rr)) % mod;
	return ans;
}
il void add(int k, int l, int r, int ll, int rr, int v) {
	if(l >= ll && r <= rr) {
		tag[k] = (tag[k] + v) % mod, updata(k, l, r);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(k, l, r);
	if(ll <= mid) add(ls, l, mid, ll, rr, v);
	if(mid < rr) add(rs, mid + 1, r, ll, rr, v);
	pushup(k, l, r);
}
il void init() {
	f[0] = f[1] = 1, sum[0] = 1, sum[1] = 2;
	rep(i, 2, n + 1) f[i] = (f[i - 1] + f[i - 2]) % mod, sum[i] = (sum[i - 1] + f[i]) % mod;
}
signed main() {
	n = read(), m = read(), init();
	rep(i, 1, n) a[i] = read();
	build(1, 1, n);
	rep(i, 1, m) {
		int opt = read(), l = read(), r = read();
		if(opt == 1) change(1, 1, n, l, r);
		else if(opt == 2) printf("%I64d\n", query(1, 1, n, l, r));
		else add(1, 1, n, l, r, read());
	}
	return 0;
}


// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d\n",__LINE__)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
//#define int long long
#define D double
#define inf 123456789
#define mod 1000000000
il int read() {
    re int x = 0, f = 1; re char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
    return x * f;
}
#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define drep(i, s, t) for(re int i = t; i >= s; -- i)
#define Next(i, u) for(re int i = head[u]; i; i = e[i].next)
#define mem(k, p) memset(k, p, sizeof(k))
#define lb(x) (x)&(-(x))
#define ls k * 2
#define rs k * 2 + 1
#define _ 200005
int n, m, a[_], f[_], val1[_ << 2], val[_ << 2], tag[_ << 2], sum[_];
il void updata(int k, int l, int r) {
	val[k] = (val[k] + 1ll * tag[k] * sum[r - l] % mod) % mod;
	val1[k] = (val1[k] + 1ll * tag[k] * (sum[r - l + 1] - 1) % mod) % mod;
}
il void pushdown(int k, int l, int r) {
	if(tag[k] == 0) return;
	int mid = (l + r) >> 1;
	tag[ls] = (tag[ls] + tag[k]) % mod, tag[rs] = (tag[rs] + tag[k]) % mod;
	updata(ls, l, mid), updata(rs, mid + 1, r), tag[k] = 0;
}
il void pushup(int k, int l, int r) {
	int mid = (l + r) >> 1, d = mid - l + 1;
	val[k] = (val[ls] + (d >= 2) * f[d - 2] * val[rs] + f[d - 1] * val1[rs]) % mod;
	val1[k] = (val1[ls] + f[d - 1] * val[rs] + f[d] * val1[rs]) % mod;
}
il void build(int k, int l, int r) {
	if(l == r) return(void)(val[k] = val1[k] = a[l]);
	int mid = (l + r) >> 1;
	build(ls, l, mid), build(rs, mid + 1, r), pushup(k, l, r);
}
il void change(int k, int l, int r, int x, int v) {
	if(l == r) return(void)(val[k] = val1[k] = v);
	int mid = (l + r) >> 1;
	pushdown(k, l, r);
	if(x <= mid) change(ls, l, mid, x, v);
	else change(rs, mid + 1, r, x, v);
	pushup(k, l, r);
}
il int query(int k, int l, int r, int ll, int rr) {
	if(l >= ll && r <= rr) {
		int d = l - ll;
		if(d == 0) return val[k];
		if(d == 1) return val1[k];
		return f[d - 2] * val[k] + f[d - 1] * val1[k];
	}
	int mid = (l + r) >> 1, ans = 0;
	pushdown(k, l, r);
	if(ll <= mid) ans = query(ls, l, mid, ll, rr);
	if(mid < rr) ans = (ans + query(rs, mid + 1, r, ll, rr)) % mod;
	return ans;
}
il void add(int k, int l, int r, int ll, int rr, int v) {
	if(l >= ll && r <= rr) {
		tag[k] = (tag[k] + v) % mod, updata(k, l, r);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(k, l, r);
	if(ll <= mid) add(ls, l, mid, ll, rr, v);
	if(mid < rr) add(rs, mid + 1, r, ll, rr, v);
	pushup(k, l, r);
}
il void init() {
	f[0] = f[1] = 1, sum[0] = 1, sum[1] = 2;
	rep(i, 2, n + 1) f[i] = (f[i - 1] + f[i - 2]) % mod, sum[i] = (sum[i - 1] + f[i]) % mod;
}
il void out(int k, int l, int r) {
	if(l == r) return;
	int mid = (l + r) >> 1;
	out(ls, l, mid), out(rs, mid + 1, r);
}
int main() {
	n = read(), m = read(), init();
	rep(i, 1, n) a[i] = read();
	build(1, 1, n), out(1, 1, n);
	rep(i, 1, m) {
		int opt = read(), l = read(), r = read();
		if(opt == 1) change(1, 1, n, l, r);
		else if(opt == 2) printf("%d\n", query(1, 1, n, l, r));
		else add(1, 1, n, l, r, read());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
const int M=1e9,N=800002;
int s1[N],s2[N],tag[N],n,m,f[N],s[N],op,l,r,x,i;
int move(int s1,int s2,int k){
	if (k==-1) return s1;
	return (1ll*s1*(!k?0:f[k-1])+1ll*s2*f[k])%M;
}
void up(int t,int l,int r){
	s1[t]=(move(s1[t<<1|1],s2[t<<1|1],mid-l)+s1[t<<1])%M;
	s2[t]=(move(s1[t<<1|1],s2[t<<1|1],mid-l+1)+s2[t<<1])%M;
}
void chg(int t,int l,int r,int v){
	(tag[t]+=v)%=M;
	(s1[t]+=1ll*v*s[r-l]%M)%=M;
	(s2[t]+=1ll*v*(s[r-l+1]-1)%M)%=M;
}
void down(int t,int l,int r){
	if (tag[t]){
		chg(t<<1,l,mid,tag[t]),chg(t<<1|1,mid+1,r,tag[t]);
		tag[t]=0;
	}
}
void add(int t,int l,int r,int x,int y,int v){
	if (x<=l && r<=y){
		chg(t,l,r,v);
		return;
	}
	down(t,l,r);
	if (x<=mid) add(t<<1,l,mid,x,y,v);
	if (mid<y) add(t<<1|1,mid+1,r,x,y,v);
	up(t,l,r);
}
int query(int t,int l,int r,int x,int y){
	if (x<=l && r<=y) return move(s1[t],s2[t],l-x-1);
	down(t,l,r);
	int ans=0;
	if (x<=mid) ans+=query(t<<1,l,mid,x,y);
	if (mid<y) ans+=query(t<<1|1,mid+1,r,x,y);
	return ans;
}
void change(int x,int y){add(1,1,n,x,x,y-query(1,1,n,x,x));}
int main(){
	scanf("%d%d",&n,&m);
	f[0]=f[1]=s[0]=1,s[1]=2;
	for (i=2;i<=n;i++) f[i]=(f[i-1]+f[i-2])%M,s[i]=(s[i-1]+f[i])%M;
	for (i=1;i<=n;i++) scanf("%d",&x),change(i,x);
	for (;m--;){
		scanf("%d%d%d",&op,&l,&r);
		if (op==1) change(l,r);
		if (op==2) printf("%d\n",query(1,1,n,l,r));
		if (op==3) scanf("%d",&x),add(1,1,n,l,r,x);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
const int M=1e9,N=800002;
int s1[N],s2[N],tag[N],n,m,f[N],s[N],op,l,r,x,i;
int move(int s1,int s2,int k){
	if (k==-1) return s1;
	return (1ll*s1*(!k?0:f[k-1])+1ll*s2*f[k])%M;
}
void up(int t,int l,int r){
	s1[t]=(move(s1[t<<1|1],s2[t<<1|1],mid-l)+s1[t<<1])%M;
	s2[t]=(move(s1[t<<1|1],s2[t<<1|1],mid-l+1)+s2[t<<1])%M;
}
void chg(int t,int l,int r,int v){
	(tag[t]+=v)%=M;
	(s1[t]+=1ll*v*s[r-l]%M)%=M;
	(s2[t]+=1ll*v*(s[r-l+1]-1)%M)%=M;
}
void down(int t,int l,int r){
	if (tag[t]){
		chg(t<<1,l,mid,tag[t]),chg(t<<1|1,mid+1,r,tag[t]);
		tag[t]=0;
	}
}
void add(int t,int l,int r,int x,int y,int v){
	if (x<=l && r<=y){
		chg(t,l,r,v);
		return;
	}
	down(t,l,r);
	if (x<=mid) add(t<<1,l,mid,x,y,v);
	if (mid<y) add(t<<1|1,mid+1,r,x,y,v);
	up(t,l,r);
}
int query(int t,int l,int r,int x,int y){
	if (x<=l && r<=y) return move(s1[t],s2[t],l-x-1);
	down(t,l,r);
	int ans=0;
	if (x<=mid) ans+=query(t<<1,l,mid,x,y);
	if (mid<y) ans+=query(t<<1|1,mid+1,r,x,y);
	return ans%M;
}
void change(int x,int y){add(1,1,n,x,x,y-query(1,1,n,x,x));}
int main(){
	scanf("%d%d",&n,&m);
	f[0]=f[1]=s[0]=1,s[1]=2;
	for (i=2;i<=n;i++) f[i]=(f[i-1]+f[i-2])%M,s[i]=(s[i-1]+f[i])%M;
	for (i=1;i<=n;i++) scanf("%d",&x),change(i,x);
	for (;m--;){
		scanf("%d%d%d",&op,&l,&r);
		if (op==1) change(l,r);
		if (op==2) printf("%d\n",query(1,1,n,l,r));
		if (op==3) scanf("%d",&x),add(1,1,n,l,r,x);
	}
}


#include <iostream>
#include <algorithm>
#include <string>
#include <cstdio>
#include <set>
#include <queue>
#include <map>
#include <iomanip>
#include <cstring>
#include <cmath>

using namespace std;
const long double eps = 1e-12;

typedef long long ll;
typedef pair<int , int> pt;

#define sz(a) ((int) a.size() )
#define LL(x) (x << 1)
#define RR(x) ((x << 1) | 1)
#define For(i , a , b) for (int i = a ; i <= b ; i++)
#define Ford(i , a , b) for (int i = a ; i >= b ; i--)
#define Rep(i , n) for (int i = 0 ; i < n ; i++)

const int md = 1e9;
int mul(int a , int b) {
    return 1LL * a * b % md;
}
int add(int a , int b) {
    return (a + b) % md;
}

const int maxn = 200000 + 1912;
int n , Q;
int a[maxn];
int fib[maxn];
int sumFib[maxn];

void ReadData() {
    fib[0] = 0;
    fib[1] = 1;
    For(i , 2 , 200000) fib[i] = (fib[i - 1] + fib[i - 2]) % md;
    For(i , 1 , 200000) sumFib[i] = add(sumFib[i - 1] , fib[i]);
    scanf("%d%d" , &n , &Q);
    For(i , 1 , n) scanf("%d" , &a[i]);
}

//----------------------------------------------------------------------------
struct Node{
    int sum0 ; // f0 al + f1 al + 1 + ....
    int sum1 ; // f1 al + ....
    int sz;

    Node() {}
    Node(int val) {
        sum0 = mul(fib[0] , val);
        sum1 = mul(fib[1] , val);
        sz = 1;
    }
} zero;
Node Combine(const Node &lef , const Node &rig) {
    Node res;
    res.sz = lef.sz + rig.sz;
    // sum0
    if (res.sz == 2) {
        res.sum0 = add(lef.sum0 , rig.sum1);
    } else {
        res.sum0 = add( mul(fib[lef.sz] , rig.sum1) , mul(fib[lef.sz - 1] , rig.sum0) );
        res.sum0 = add(res.sum0 , lef.sum0);
    }
    // sum1
    res.sum1 = add( mul(fib[lef.sz + 1] , rig.sum1) , mul( fib[lef.sz] , rig.sum0) );
    res.sum1 = add(res.sum1 , lef.sum1);

    return res;
}

int l[maxn * 4] , h[maxn * 4];
Node it[maxn * 4];
int lazy[maxn * 4];
void Build(const int x , const int low , const int high) {
    l[x] = low , h[x] = high;
    if (low == high) {
        it[x] = Node(a[low]);
    } else {
        int mid = (low + high) >> 1;
        Build(LL(x) , low , mid);
        Build(RR(x) , mid + 1 , high);
        it[x] = Combine(it[LL(x)] , it[RR(x)]);
    }
   // cout << l[x] << " " << h[x] << " " << it[x].sum0 << endl;
}

void Add(const int x , const int val) {
    lazy[x] = add(lazy[x] , val);
    it[x].sum0 = add(it[x].sum0 , mul(val , sumFib[h[x] - l[x]]));
    it[x].sum1 = add(it[x].sum1 , mul(val , sumFib[h[x] - l[x] + 1]));
}

void Down(int x){
    if (lazy[x] > 0) {
        Add(LL(x) , lazy[x]);
        Add(RR(x) , lazy[x]);
        lazy[x] = 0;
    }
}

void UpdateAss(const int &x , int pos , int val) {
    if (l[x] == h[x]) {
        it[x] = Node(val);
        return;
    }
    Down(x);
    if (h[LL(x)] >= pos) UpdateAss(LL(x) , pos , val); else UpdateAss(RR(x) , pos , val);
    it[x] = Combine(it[LL(x)] , it[RR(x)]);
}

void UpdateAdd(const int &x , const int &u , const int &v , int val) {
    if (l[x] > v || h[x] < u) return;
    if (u <= l[x] && h[x] <= v) {
        Add(x , val); return;
    }
    Down(x);
    UpdateAdd(LL(x) , u , v , val);
    UpdateAdd(RR(x) , u , v , val);
    it[x] = Combine(it[LL(x)] , it[RR(x)]);
}

Node Query(const int &x , const int &u , const int &v) {
    if (l[x] > v || h[x] < u) return zero;
    if (u <= l[x] && h[x] <= v) return it[x];
    Down(x);
    return Combine(Query(LL(x) , u , v) , Query(RR(x) , u , v));
}
//----------------------------------------------------------------------------
void Process() {
    zero.sz = 0; zero.sum0 = 0 ; zero.sum1 = 0;
    Build(1 , 1 , n);
    while (Q--) {
        int type; scanf("%d" , &type);
        if (type == 1) {
            int pos , val; scanf("%d%d" , &pos , &val);
            UpdateAss(1 , pos , val);
        }
        if (type == 2) {
            int l , r; scanf("%d%d" , &l , &r);
            Node res = Query(1 , l , r);
            cout << res.sum1 << "\n";
        }
        if (type == 3) {
            int l , r , val; scanf("%d%d%d" , &l , &r , &val);
            UpdateAdd(1 , l , r, val);
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
   // freopen("/users/youaremysky/documents/workspace/input.inp" , "r" , stdin);
    ReadData();
    Process();
}


#include<cstdio>
#include<bitset>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<map>
#include<set>
#include<queue>
#include<algorithm>

using namespace std;

int ans_x, ans_y, mod, N, M, a[200009], lazy[800009], x[800009], y[800009], coef_x[200009], coef_y[200009], sum_x[200009], sum_y[200009], fibo[200009];

void Fibonacci_Precompution ()
{
    coef_x[0] = 1, coef_y[0] = 0;
    coef_x[1] = 0, coef_y[1] = 1;
    for (int i=2; i<=N + 3; i++)
    {
        coef_x[i] = coef_x[i - 1] + coef_x[i - 2];
        if (coef_x[i] >= mod) coef_x[i] -= mod;
        coef_y[i] = coef_y[i - 1] + coef_y[i - 2];
        if (coef_y[i] >= mod) coef_y[i] -= mod;
    }

    fibo[0] = fibo[1] = 1;
    for (int i=2; i<=N + 3; i++)
    {
        fibo[i] = fibo[i - 1] + fibo[i - 2];
        if (fibo[i] >= mod) fibo[i] -= mod;
    }

    sum_x[0] = 1, sum_y[0] = 0;
    for (int i=1; i<=N + 3; i++)
    {
        sum_x[i] = sum_x[i - 1] + coef_x[i];
        if (sum_x[i] >= mod) sum_x[i] -= mod;
        sum_y[i] = sum_y[i - 1] + coef_y[i];
        if (sum_y[i] >= mod) sum_y[i] -= mod;
    }
}

void Refresh (int nod, int st, int dr, int mij)
{
    int f1 = nod << 1, f2 = f1 + 1;
    x[nod] = ((long long) x[f1] + 1LL * x[f2] * coef_x[mij - st + 1] + 1LL * y[f2] * coef_x[mij - st + 2]) % mod;
    if (mij == st) y[nod] = x[f2];
    else y[nod] = ((long long) y[f1] + 1LL * y[f2] * coef_y[mij - st + 2] + 1LL * x[f2] * coef_y[mij - st + 1]) % mod;
}

void split (int nod, int st, int dr, int mij)
{
    if (lazy[nod] == 0) return ;
    int d = lazy[nod], f1 = nod << 1, f2 = f1 + 1;

    lazy[f1] += d;
    if (lazy[f1] >= mod) lazy[f1] -= mod;

    lazy[f2] += d;
    if (lazy[f2] >= mod) lazy[f2] -= mod;

    x[f1] = ((long long) x[f1] + 1LL * d * sum_x[mij - st]) % mod;
    y[f1] = ((long long) y[f1] + 1LL * d * sum_y[mij - st]) % mod;

    x[f2] = ((long long) x[f2] + 1LL * d * sum_x[dr - mij - 1]) % mod;
    y[f2] = ((long long) y[f2] + 1LL * d * sum_y[dr - mij - 1]) % mod;
    lazy[nod] = 0;
}

void Build (int nod, int st, int dr)
{
    if (st == dr)
    {
        x[nod] = a[st], y[nod] = 0;
        return ;
    }
    int mij = (st + dr) >> 1;
    Build (nod << 1, st, mij);
    Build ((nod << 1) + 1, mij + 1, dr);
    Refresh (nod, st, dr, mij);
}

void Query (int nod, int st, int dr, int x_q, int y_q)
{
    if (x_q <= st && dr <= y_q)
    {
        int pos = st - x_q;
        ans_x = ((long long) ans_x + 1LL * x[nod] * coef_x[pos] + 1LL * y[nod] * coef_x[pos + 1]) % mod;
        if (pos > 0) ans_y = ((long long) ans_y + 1LL * y[nod] * coef_y[pos + 1] + 1LL * x[nod] * coef_y[pos]) % mod;
        else ans_y = y[nod];
        return ;
    }
    int mij = (st + dr) >> 1;
    split (nod, st, dr, mij);
    if (x_q <= mij) Query (nod << 1, st, mij, x_q, y_q);
    if (y_q > mij) Query ((nod << 1) + 1, mij + 1, dr, x_q, y_q);
    Refresh (nod, st, dr, mij);
}

void Update (int nod, int st, int dr, int pos, int val)
{
    if (st == dr)
    {
        x[nod] = val;
        return ;
    }
    int mij = (st + dr) >> 1;
    split (nod, st, dr, mij);
    if (pos <= mij) Update (nod << 1, st, mij, pos, val);
    else Update ((nod << 1) + 1, mij + 1, dr, pos, val);
    Refresh (nod, st, dr, mij);
}

void Update2 (int nod, int st, int dr, int x_q, int y_q, int val)
{
    if (x_q <= st && dr <= y_q)
    {
        lazy[nod] += val;
        if (lazy[nod] >= mod) lazy[nod] -= mod;
        x[nod] = ((long long) x[nod] + 1LL * sum_x[dr - st] * val) % mod;
        y[nod] = ((long long) y[nod] + 1LL * sum_y[dr - st] * val) % mod;
        return ;
    }
    int mij = (st + dr) >> 1;
    split (nod, st, dr, mij);
    if (x_q <= mij) Update2 (nod << 1, st, mij, x_q, y_q, val);
    if (y_q > mij) Update2 ((nod << 1) + 1, mij + 1, dr, x_q, y_q, val);
    Refresh (nod, st, dr, mij);
}

int main()
{
//freopen ("input", "r", stdin);
//freopen ("output", "w", stdout);

scanf ("%d %d", &N, &M), mod = 1e9;
for (int i=1; i<=N; i++)
    scanf ("%d", &a[i]);
Fibonacci_Precompution ();
Build (1, 1, N);
while (M --)
{
    int type;
    scanf ("%d", &type);
    if (type == 1)
    {
        int pos, val;
        scanf ("%d %d", &pos, &val);
        Update (1, 1, N, pos, val);
        continue;
    }
    if (type == 3)
    {
        int left, right, val;
        scanf ("%d %d %d", &left, &right, &val);
        Update2 (1, 1, N, left, right, val);
        continue;
    }
    int left, right, ans;
    scanf ("%d %d", &left, &right), ans_x = 0, ans_y = 0;
    Query (1, 1, N, left, right);
    ans = ans_x + ans_y;
    if (ans >= mod) ans -= mod;
    printf ("%d\n", ans);
}
return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Ls (u << 1)
#define Rs (u << 1 | 1)
#define inc(i) (++ (i))
#define dec(i) (-- (i))
#define Rep(i , a , b) for(int i = (a) , i##limit = (b) ; i <= i##limit ; inc(i))
#define rep(i , a , b) for(int i = (a) , i##limit = (b) ; i >= i##limit ; dec(i))
using namespace std;

const int N = 400000 + 7 , Mod = 1000000000;
inline int Mul(int A , int B) { return 1ll * A * B % Mod; }
inline int Inc(int A , int B) { A += B; return A >= Mod ? A - Mod : A; }
inline int Dec(int A , int B) { A -= B; return A < 0 ? A + Mod : A; }
int n , m , A[N] , f[N] , Dp[N];
struct YYZ {
	int Sum1 , Sum2 , Sign , Siz;
	inline void Clear() { Sum1 = Sum2 = Sign = Siz = 0; }
}T[N << 2];
inline int Gets(int x) { return x < 0 ? 0 : f[x]; }
inline YYZ Merge(YYZ A , YYZ B) {
	if(A.Siz == 0) return B;
	if(B.Siz == 0) return A;
	YYZ C; C.Clear() , C.Siz = A.Siz + B.Siz;
	C.Sum1 = Inc(A.Sum1 , Inc(Mul(B.Sum1 , Gets(A.Siz - 2)) , Mul(B.Sum2 , Gets(A.Siz - 1))));
	C.Sum2 = Inc(A.Sum2 , Inc(Mul(B.Sum1 , Gets(A.Siz - 1)) , Mul(B.Sum2 , Gets(A.Siz))));
	return C;
}
inline void Build(int u , int l , int r) {
	T[u].Siz = r - l + 1;
	if(l == r) {
		T[u].Sum1 = T[u].Sum2 = A[l];
		return;
	}
	int Mid = (l + r) >> 1;
	Build(Ls , l , Mid) , Build(Rs , Mid + 1 , r);
	T[u] = Merge(T[Ls] , T[Rs]);
}
inline void Pushdown(int u) {
	if(T[u].Sign) {
		T[Ls].Sign = Inc(T[Ls].Sign , T[u].Sign);
		T[Ls].Sum1 = Inc(T[Ls].Sum1 , Mul(T[u].Sign , Dp[T[Ls].Siz - 1]));
		T[Ls].Sum2 = Inc(T[Ls].Sum2 , Dec(Mul(T[u].Sign , Dp[T[Ls].Siz]) , T[u].Sign));
		T[Rs].Sign = Inc(T[Rs].Sign , T[u].Sign);
		T[Rs].Sum1 = Inc(T[Rs].Sum1 , Mul(T[u].Sign , Dp[T[Rs].Siz - 1]));
		T[Rs].Sum2 = Inc(T[Rs].Sum2 , Dec(Mul(T[u].Sign , Dp[T[Rs].Siz]) , T[u].Sign));
		T[u].Sign = 0;
	}
}
inline void Change(int u , int l , int r , int Pos , int w) {
	if(l == r) {
		T[u].Sum1 = T[u].Sum2 = w;
		return;
	}
	Pushdown(u);
	int Mid = (l + r) >> 1;
	if(Mid >= Pos) Change(Ls , l , Mid , Pos , w);
	else Change(Rs , Mid + 1 , r , Pos , w);
	T[u] = Merge(T[Ls] , T[Rs]);
}
inline YYZ Query(int u , int l , int r , int L , int R) {
	if(L <= l && R >= r) return T[u];
	Pushdown(u);
	int Mid = (l + r) >> 1;
	YYZ A , B; A.Clear() , B.Clear();
	if(Mid >= L) A = Query(Ls , l , Mid , L , R);
	if(Mid < R) B = Query(Rs , Mid + 1 , r , L , R);
	return Merge(A , B);
}
inline void Update(int u , int l , int r , int L , int R , int w) {
	if(L <= l && R >= r) {
		T[u].Sign = Inc(T[u].Sign , w);
		T[u].Sum1 = Inc(T[u].Sum1 , Mul(w , Dp[T[u].Siz - 1]));
		T[u].Sum2 = Inc(T[u].Sum2 , Dec(Mul(w , Dp[T[u].Siz]) , w));
		return;
	}
	Pushdown(u);
	int Mid = (l + r) >> 1;
	if(Mid >= L) Update(Ls , l , Mid , L , R , w);
	if(Mid < R) Update(Rs , Mid + 1 , r , L , R , w);
	T[u] = Merge(T[Ls] , T[Rs]);
}

int main() {
	//freopen("Liang.in" , "r" , stdin);
	//freopen("Liang.out" , "w" , stdout);
	scanf("%d%d" , &n , &m);
	f[0] = 1;
	Rep(i , 1 , n) scanf("%d" , A + i) , f[i] = Inc(f[i - 1] , i == 1 ? 0 : f[i - 2]);
	Dp[0] = 1; Rep(i , 1 , n) Dp[i] = Inc(Dp[i - 1] , f[i]);
	Build(1 , 1 , n);
	int opt , x , y , w;
	while(m --) {
		scanf("%d%d%d" , &opt , &x , &y);
		if(opt == 1) Change(1 , 1 , n , x , y);
		else if(opt == 2) printf("%d\n" , Query(1 , 1 , n , x , y).Sum1);
			 else scanf("%d" , &w) , Update(1 , 1 , n , x , y , w);
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i, a, b) for (int i = a; i <= b; i++)
const int N = 10005, oo = 1000000000;
int a[N], f[N], n, m, type, l, r;
int main() {
  scanf("%d%d", &n, &m);
  f[0] = f[1] = 1;
  rep(i, 2, n) f[i] = (f[i - 1] + f[i - 2]) % oo;
  rep(i, 1, n) scanf("%d", a + i);
  while (m--) {
    scanf("%d%d%d", &type, &l, &r);
    if (type == 1)
      a[l] = r;
    else {
      long long ans = 0;
      rep(i, l, r) ans += 1LL * a[i] * f[i - l];
      printf("%d\n", ans % oo);
    }
  }
  return 0;
}


//sobskdrbhvk
#include <bits/stdc++.h>

using namespace std;

typedef long long int LL;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;

#define PB push_back
#define MP make_pair
#define L first
#define R second
#define sz(x) ((int)(x).size())
#define smax(x, y) ((x) = max((x), (y)))
#define smin(x, y) ((x) = min((x), (y)))
#define all(x) x.begin(),x.end()

const int maxn = 2e5 + 85 - 69;
const LL Mod = 1000LL * 1000 * 1000;
LL fibarr[maxn * 2 + 10], sumarr[maxn * 2 + 10], arr[maxn];
LL *fib, *sum;
LL seg0[maxn * 4], seg1[maxn * 4], laz[maxn * 4];
LL f0, f1;
int n, q;

LL Fib(int idx, LL a, LL b){
	return (((fib[idx] * a) % Mod) + ((fib[idx - 1] * ((b - a) % Mod)) % Mod)) % Mod;
}

void push(int, int, int);

void pull(int id){
	seg0[id] = (seg0[id * 2 + 0] + seg0[id * 2 + 1]) % Mod;
	seg1[id] = (seg1[id * 2 + 0] + seg1[id * 2 + 1]) % Mod;
	return;
}

void build(int l = 0, int r = n, int id = 1){
	if(r - l == 1){
		seg0[id] = (arr[l] * fib[l - n]) % Mod;
		seg1[id] = (arr[l] * fib[l - n + 1]) % Mod;
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, id * 2 + 0);
	build(mid, r, id * 2 + 1);
	pull(id);
	return;
}

void get(int st, int en, int l = 0, int r = n, int id = 1){
	if(st <= l and r <= en){
		f0 = (f0 + seg0[id]) % Mod;
		f1 = (f1 + seg1[id]) % Mod;
		return;
	}
	if(laz[id])push(l, r, id);
	int mid = (l + r) >> 1;
	if(st < mid)
		get(st, min(mid, en), l, mid, id * 2 + 0);
	if(en > mid)
		get(max(st, mid), en, mid, r, id * 2 + 1);
	return;
}

void modify0(int idx, LL val, int l = 0, int r = n, int id = 1){
	if(idx < l or idx >= r)
		return;
	if(r - l == 1){
		seg0[id] = (val * fib[l - n]) % Mod;
		seg1[id] = (val * fib[l - n + 1]) % Mod;
		return;
	}
	if(laz[id])push(l, r, id);
	int mid = (l + r) >> 1;
	modify0(idx, val, l, mid, id * 2 + 0);
	modify0(idx, val, mid, r, id * 2 + 1);
	pull(id);
	return;
}

void modify1(LL val, int st, int en, int l = 0, int r = n, int id = 1){
	if(st >= r or en <= l)
		return;
	if(st <= l and r <= en){
		seg0[id] += (val * ((sum[r - n] - sum[l - n]) % Mod)) % Mod;
		seg0[id] %= Mod;
		seg1[id] += (val * ((sum[r - n + 1] - sum[l - n + 1]) % Mod)) % Mod;
		seg1[id] %= Mod;
		laz[id] = (laz[id] + val) % Mod;
		return;
	}
	if(laz[id])push(l, r, id);
	int mid = (l + r) >> 1;
	modify1(val, st, en, l, mid, id * 2 + 0);
	modify1(val, st, en, mid, r, id * 2 + 1);
	pull(id);
	return;
}

void push(int l, int r, int id){
	int mid = (l + r) >> 1;
	modify1(laz[id], l, mid, l, mid, id * 2 + 0);
	modify1(laz[id], mid, r, mid, r, id * 2 + 1);
	laz[id] = 0;
	return;
}

int main(){
	fib = fibarr + maxn + 5;
	sum = sumarr + maxn + 5;
	fib[1] = 1;
	for(int i = 2; i < maxn; i++)
		fib[i] = (fib[i - 1] + fib[i - 2]) % Mod;
	for(int i = 1; i < maxn; i++)
		fib[-i] = (fib[-i + 2] - fib[-i + 1]) % Mod;
	for(int i = -maxn + 1; i + 1 < maxn; i++)
		sum[i + 1] = (sum[i] + fib[i]) % Mod;
	scanf("%d%d", &n, &q);
	for(int i = 0; i < n; i++)
		scanf("%I64d", arr + i);
	build();
	while(q--){
		int ty;
		LL fi, se, th;
		scanf("%d%I64d%I64d", &ty, &fi, &se);
		fi--;
		if(ty == 1)
			modify0(fi, se);
		else if(ty == 2){
			f0 = f1 = 0;
			get(fi, se);
			//cout << "Negar " << f0 << ' ' << f1 << endl;
			printf("%I64d\n", (((Fib(n - fi + 2, f0, f1) % Mod) + Mod) % Mod));
			//cout << ((Fib(n - fi + 2, f0, f1) % Mod) + Mod) % Mod << endl;
		}
		else{
			scanf("%I64d", &th);
			modify1(th, fi, se);
		}
	}
	return 0;
}


//K-OS WITH THE OCDE

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define ff first
#define ss second
#define ar array
#define mod 1000000000
#define pb push_back
#define mpa make_pair
#define TEST ll t; cin>>t; while(t--)
#define vell vector<ll>
#define vel2 vector<vector<ll>>
#define all(v) v.begin(),v.end()

#define for0(i,n)     for(ll i=0;i<(ll)n;i++)
#define for1(i,n)     for(ll i=1;i<=(ll)n;i++)
#define forr(i,n)     for(ll i=(ll)n-1;i>=0;i--)
#define fall(i,a,b,c) for(ll i=a;i<=(ll)b;i+=(ll)c)

#define db long double
#define endl "\n"
#define MAX INT_MAX
#define MIN INT_MIN

////////////////////////////////////////////////////////////////////////

/*Parity and inversion - ( (grid width odd) && (#inversions even) ) ||
( (grid width even) && ((blank on odd row from bottom) == (#inversions even)) )*/

////////////////////////////////////////////////////////////////////////

ll add(ll a,ll b)  { return ((a%mod+b%mod)%mod); }
ll mult(ll a,ll b) { return (((a%mod)*(b%mod))%mod); }

ll gcdExtended(ll a, ll b, ll *x, ll *y)
{
    if (a == 0) {
        *x = 0, *y = 1;
        return b;
    }

    ll x1, y1;
    ll gcd = gcdExtended(b%a, a, &x1, &y1);
    *x = y1 - (b/a) * x1;
    *y = x1;
    return gcd;
}

ll modInverse(ll  b, ll  m)
{
    ll x, y;
    ll g = gcdExtended(b, m, &x, &y);
    if (g != 1)
        return -1;
    return (x%m + m) % m;
}

ll modDivide(ll a, ll b, ll m)
{
    a = a % m;
    int inv = modInverse(b, m);
    return (inv * a) % m;
}

ll power(ll a,ll n)
{
    ll ans=1;
    while(n>0)
    {
        ll lastbit=(n&1);
        if(lastbit)
            ans*=a;

        a*=a;
        n>>=1;
    }

   return ans;
}
/////////////////////////////////////////////////
int sieveo(ll n)
{

    bool prime[n+1];
    memset(prime, true, sizeof(prime));
    ll ans=0;

    for (ll p=2; p*p<=n; p++)
    {
        if (prime[p] == true)
        {

            for (ll i=p*p; i<=n; i += p)
                prime[i] = false;
        }
    }

    for (ll p=2; p<=n; p++)
       if (prime[p])
          ans++;

          return ans;
}

///////////////////////////////

void primesieve(ll N, ll s[])
{
    vector <bool> prime(N+1, false);

    for (ll i=2; i<=N; i+=2)
        s[i] = 2;

    for (ll i=3; i<=N; i+=2)
    {
        if (prime[i] == false)
        {
            s[i] = i;

            for (ll j=i; j*i<=N; j+=2)
            {
                if (prime[i*j] == false)
                {
                    prime[i*j] = true;
                    s[i*j] = i;
                }
            }
        }
    }
}

void primefactor(ll N)
{

    ll s[N+1];
    primesieve(N, s);

    ll curr = s[N];
    ll cnt = 1;

    while (N > 1)
    {
        N /= s[N];
        if (curr == s[N])
        {
            cnt++;
           continue;
        }

      //curr==prime n.
      //cnt=power
        curr = s[N];
        cnt = 1;
    }

}

/////////////////////////////////////////////////////////

ll compute(ll x)
{
	if(x==0 || x==1)
	return 1;

	return compute(x-1)+compute(x-2);
}

void solve()
{
    ll n,m;
    cin >> n >> m;
    ll a[n+1];

    for(ll i=1 ; i<=n ; ++i)
    cin >> a[i];

    ll f[200001];

    f[0]=1;
    f[1]=1;

    for(ll i=2 ; i<=200000 ; ++i)
    f[i] = add(f[i-1],f[i-2]);

    while(m--)
    {
    	ll q;
    	cin >> q;

    	if(q==1)
    	{
    		ll idx,x;
    		cin >> idx >> x;
    		a[idx] = x;
    	}
    	else if(q==2)
    	{
    		ll l,r;
    		cin >> l >> r;
    		ll ans=0;

    		for(ll i=0 ; i<= r-l ; ++i) {
    			ans+=mult(f[i],a[i+l]);
    		}

    		cout << ans%mod << endl;
    	}

    	else
    	{
    		ll l,r,d;
    		cin >> l >> r >> d;
    		for(ll i=l ; i<=r ; ++i) {
    			a[i]+=d;
    		}
    	}
    }
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    //TEST
    solve();
}


//K-OS WITH THE OCDE

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define ff first
#define ss second
#define ar array
#define mod 1000000000
#define pb push_back
#define mpa make_pair
#define TEST ll t; cin>>t; while(t--)
#define vell vector<ll>
#define vel2 vector<vector<ll>>
#define all(v) v.begin(),v.end()

#define for0(i,n)     for(ll i=0;i<(ll)n;i++)
#define for1(i,n)     for(ll i=1;i<=(ll)n;i++)
#define forr(i,n)     for(ll i=(ll)n-1;i>=0;i--)
#define fall(i,a,b,c) for(ll i=a;i<=(ll)b;i+=(ll)c)

#define db long double
#define endl "\n"
#define MAX INT_MAX
#define MIN INT_MIN

////////////////////////////////////////////////////////////////////////

/*Parity and inversion - ( (grid width odd) && (#inversions even) ) ||
( (grid width even) && ((blank on odd row from bottom) == (#inversions even)) )*/

////////////////////////////////////////////////////////////////////////

ll add(ll a,ll b)  { return ((a%mod+b%mod)%mod); }
ll mult(ll a,ll b) { return (((a%mod)*(b%mod))%mod); }

ll gcdExtended(ll a, ll b, ll *x, ll *y)
{
    if (a == 0) {
        *x = 0, *y = 1;
        return b;
    }

    ll x1, y1;
    ll gcd = gcdExtended(b%a, a, &x1, &y1);
    *x = y1 - (b/a) * x1;
    *y = x1;
    return gcd;
}

ll modInverse(ll  b, ll  m)
{
    ll x, y;
    ll g = gcdExtended(b, m, &x, &y);
    if (g != 1)
        return -1;
    return (x%m + m) % m;
}

ll modDivide(ll a, ll b, ll m)
{
    a = a % m;
    int inv = modInverse(b, m);
    return (inv * a) % m;
}

ll power(ll a,ll n)
{
    ll ans=1;
    while(n>0)
    {
        ll lastbit=(n&1);
        if(lastbit)
            ans*=a;

        a*=a;
        n>>=1;
    }

   return ans;
}
/////////////////////////////////////////////////
int sieveo(ll n)
{

    bool prime[n+1];
    memset(prime, true, sizeof(prime));
    ll ans=0;

    for (ll p=2; p*p<=n; p++)
    {
        if (prime[p] == true)
        {

            for (ll i=p*p; i<=n; i += p)
                prime[i] = false;
        }
    }

    for (ll p=2; p<=n; p++)
       if (prime[p])
          ans++;

          return ans;
}

///////////////////////////////

void primesieve(ll N, ll s[])
{
    vector <bool> prime(N+1, false);

    for (ll i=2; i<=N; i+=2)
        s[i] = 2;

    for (ll i=3; i<=N; i+=2)
    {
        if (prime[i] == false)
        {
            s[i] = i;

            for (ll j=i; j*i<=N; j+=2)
            {
                if (prime[i*j] == false)
                {
                    prime[i*j] = true;
                    s[i*j] = i;
                }
            }
        }
    }
}

void primefactor(ll N)
{

    ll s[N+1];
    primesieve(N, s);

    ll curr = s[N];
    ll cnt = 1;

    while (N > 1)
    {
        N /= s[N];
        if (curr == s[N])
        {
            cnt++;
           continue;
        }

      //curr==prime n.
      //cnt=power
        curr = s[N];
        cnt = 1;
    }

}

/////////////////////////////////////////////////////////

ll compute(ll x)
{
	if(x==0 || x==1)
	return 1;

	return compute(x-1)+compute(x-2);
}

void solve()
{
    ll n,m;
    cin >> n >> m;
    ll a[n+1];

    for(ll i=1 ; i<=n ; ++i)
    cin >> a[i];

    while(m--)
    {
    	ll q;
    	cin >> q;

    	if(q==1)
    	{
    		ll idx,x;
    		cin >> idx >> x;
    		a[idx] = x;
    	}
    	else if(q==2)
    	{
    		ll l,r;
    		cin >> l >> r;
    		ll ans=0;
    		for(ll i=0 ; i<= r-l ; ++i) {
    			ans+=mult(compute(i),a[i+l]);
    		}

    		cout << ans%mod << endl;
    	}

    	else
    	{
    		ll l,r,d;
    		cin >> l >> r >> d;
    		for(ll i=l ; i<=r ; ++i) {
    			a[i]+=d;
    		}
    	}
    }

}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    //TEST
    solve();
}


//K-OS WITH THE OCDE

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define ff first
#define ss second
#define ar array
#define mod 1000000000
#define pb push_back
#define mpa make_pair
#define TEST ll t; cin>>t; while(t--)
#define vell vector<ll>
#define vel2 vector<vector<ll>>
#define all(v) v.begin(),v.end()

#define for0(i,n)     for(ll i=0;i<(ll)n;i++)
#define for1(i,n)     for(ll i=1;i<=(ll)n;i++)
#define forr(i,n)     for(ll i=(ll)n-1;i>=0;i--)
#define fall(i,a,b,c) for(ll i=a;i<=(ll)b;i+=(ll)c)

#define db long double
#define endl "\n"
#define MAX INT_MAX
#define MIN INT_MIN

////////////////////////////////////////////////////////////////////////

/*Parity and inversion - ( (grid width odd) && (#inversions even) ) ||
( (grid width even) && ((blank on odd row from bottom) == (#inversions even)) )*/

////////////////////////////////////////////////////////////////////////

ll add(ll a,ll b)  { return ((a%mod+b%mod)%mod); }
ll mult(ll a,ll b) { return (((a%mod)*(b%mod))%mod); }

ll gcdExtended(ll a, ll b, ll *x, ll *y)
{
    if (a == 0) {
        *x = 0, *y = 1;
        return b;
    }

    ll x1, y1;
    ll gcd = gcdExtended(b%a, a, &x1, &y1);
    *x = y1 - (b/a) * x1;
    *y = x1;
    return gcd;
}

ll modInverse(ll  b, ll  m)
{
    ll x, y;
    ll g = gcdExtended(b, m, &x, &y);
    if (g != 1)
        return -1;
    return (x%m + m) % m;
}

ll modDivide(ll a, ll b, ll m)
{
    a = a % m;
    int inv = modInverse(b, m);
    return (inv * a) % m;
}

ll power(ll a,ll n)
{
    ll ans=1;
    while(n>0)
    {
        ll lastbit=(n&1);
        if(lastbit)
            ans*=a;

        a*=a;
        n>>=1;
    }

   return ans;
}
/////////////////////////////////////////////////
int sieveo(ll n)
{

    bool prime[n+1];
    memset(prime, true, sizeof(prime));
    ll ans=0;

    for (ll p=2; p*p<=n; p++)
    {
        if (prime[p] == true)
        {

            for (ll i=p*p; i<=n; i += p)
                prime[i] = false;
        }
    }

    for (ll p=2; p<=n; p++)
       if (prime[p])
          ans++;

          return ans;
}

///////////////////////////////

void primesieve(ll N, ll s[])
{
    vector <bool> prime(N+1, false);

    for (ll i=2; i<=N; i+=2)
        s[i] = 2;

    for (ll i=3; i<=N; i+=2)
    {
        if (prime[i] == false)
        {
            s[i] = i;

            for (ll j=i; j*i<=N; j+=2)
            {
                if (prime[i*j] == false)
                {
                    prime[i*j] = true;
                    s[i*j] = i;
                }
            }
        }
    }
}

void primefactor(ll N)
{

    ll s[N+1];
    primesieve(N, s);

    ll curr = s[N];
    ll cnt = 1;

    while (N > 1)
    {
        N /= s[N];
        if (curr == s[N])
        {
            cnt++;
           continue;
        }

      //curr==prime n.
      //cnt=power
        curr = s[N];
        cnt = 1;
    }

}

/////////////////////////////////////////////////////////

ll compute(ll x)
{
	if(x==0 || x==1)
	return 1;

	return compute(x-1)+compute(x-2);
}

void solve()
{
    ll n,m;
    cin >> n >> m;
    ll a[n+1];

    for(ll i=1 ; i<=n ; ++i)
    cin >> a[i];

    ll f[200001];

    f[0]=1;
    f[1]=1;

    for(ll i=2 ; i<=200000 ; ++i)
    f[i] = (f[i-1] + f[i-2]);

    while(m--)
    {
    	ll q;
    	cin >> q;

    	if(q==1)
    	{
    		ll idx,x;
    		cin >> idx >> x;
    		a[idx] = x;
    	}
    	else if(q==2)
    	{
    		ll l,r;
    		cin >> l >> r;
    		ll ans=0;

    		for(ll i=0 ; i<= r-l ; ++i) {
    			ans+=mult(f[i],a[i+l]);
    		}

    		cout << ans%mod << endl;
    	}

    	else
    	{
    		ll l,r,d;
    		cin >> l >> r >> d;
    		for(ll i=l ; i<=r ; ++i) {
    			a[i]+=d;
    		}
    	}
    }
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    //TEST
    solve();
}


//K-OS WITH THE OCDE

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define ff first
#define ss second
#define ar array
#define mod 1000000007
#define pb push_back
#define mpa make_pair
#define TEST ll t; cin>>t; while(t--)
#define vell vector<ll>
#define vel2 vector<vector<ll>>
#define all(v) v.begin(),v.end()

#define for0(i,n)     for(ll i=0;i<(ll)n;i++)
#define for1(i,n)     for(ll i=1;i<=(ll)n;i++)
#define forr(i,n)     for(ll i=(ll)n-1;i>=0;i--)
#define fall(i,a,b,c) for(ll i=a;i<=(ll)b;i+=(ll)c)

#define db long double
#define endl "\n"
#define MAX INT_MAX
#define MIN INT_MIN

////////////////////////////////////////////////////////////////////////

/*Parity and inversion - ( (grid width odd) && (#inversions even) ) ||
( (grid width even) && ((blank on odd row from bottom) == (#inversions even)) )*/

////////////////////////////////////////////////////////////////////////

ll add(ll a,ll b)  { return ((a%mod+b%mod)%mod); }
ll mult(ll a,ll b) { return (((a%mod)*(b%mod))%mod); }

ll gcdExtended(ll a, ll b, ll *x, ll *y)
{
    if (a == 0) {
        *x = 0, *y = 1;
        return b;
    }

    ll x1, y1;
    ll gcd = gcdExtended(b%a, a, &x1, &y1);
    *x = y1 - (b/a) * x1;
    *y = x1;
    return gcd;
}

ll modInverse(ll  b, ll  m)
{
    ll x, y;
    ll g = gcdExtended(b, m, &x, &y);
    if (g != 1)
        return -1;
    return (x%m + m) % m;
}

ll modDivide(ll a, ll b, ll m)
{
    a = a % m;
    int inv = modInverse(b, m);
    return (inv * a) % m;
}

ll power(ll a,ll n)
{
    ll ans=1;
    while(n>0)
    {
        ll lastbit=(n&1);
        if(lastbit)
            ans*=a;

        a*=a;
        n>>=1;
    }

   return ans;
}
/////////////////////////////////////////////////
int sieveo(ll n)
{

    bool prime[n+1];
    memset(prime, true, sizeof(prime));
    ll ans=0;

    for (ll p=2; p*p<=n; p++)
    {
        if (prime[p] == true)
        {

            for (ll i=p*p; i<=n; i += p)
                prime[i] = false;
        }
    }

    for (ll p=2; p<=n; p++)
       if (prime[p])
          ans++;

          return ans;
}

///////////////////////////////

void primesieve(ll N, ll s[])
{
    vector <bool> prime(N+1, false);

    for (ll i=2; i<=N; i+=2)
        s[i] = 2;

    for (ll i=3; i<=N; i+=2)
    {
        if (prime[i] == false)
        {
            s[i] = i;

            for (ll j=i; j*i<=N; j+=2)
            {
                if (prime[i*j] == false)
                {
                    prime[i*j] = true;
                    s[i*j] = i;
                }
            }
        }
    }
}

void primefactor(ll N)
{

    ll s[N+1];
    primesieve(N, s);

    ll curr = s[N];
    ll cnt = 1;

    while (N > 1)
    {
        N /= s[N];
        if (curr == s[N])
        {
            cnt++;
           continue;
        }

      //curr==prime n.
      //cnt=power
        curr = s[N];
        cnt = 1;
    }

}

/////////////////////////////////////////////////////////

ll compute(ll x)
{
	if(x==0 || x==1)
	return 1;

	return compute(x-1)+compute(x-2);
}

void solve()
{
    ll n,m;
    cin >> n >> m;
    ll a[n+1];

    for(ll i=1 ; i<=n ; ++i)
    cin >> a[i];

    while(m--)
    {
    	ll q;
    	cin >> q;

    	if(q==1)
    	{
    		ll idx,x;
    		cin >> idx >> x;
    		a[idx] = x;
    	}
    	else if(q==2)
    	{
    		ll l,r;
    		cin >> l >> r;
    		ll ans=0;
    		for(ll i=0 ; i<= r-l ; ++i) {
    			ans+=mult(compute(i),a[i+l]);
    		}

    		cout << ans%mod << endl;
    	}

    	else
    	{
    		ll l,r,d;
    		cin >> l >> r >> d;
    		for(ll i=l ; i<=r ; ++i) {
    			a[i]+=d;
    		}
    	}
    }

}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    //TEST
    solve();
}


#include <bits/stdc++.h>
using namespace std;

int n,m;
long long a[112345];
long long M = 1e9;
long long fibo[112345];

int main(){
    ios_base::sync_with_stdio(0);
    //freopen("input.txt","r",stdin);

    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];

    fibo[0] = 1;
    fibo[1] = 1;
    for(int i=2;i<=112345;i++) fibo[i] = (fibo[i-1] + fibo[i-2]) % M;

    for(int i=0;i<m;i++){
        int t;cin>>t;
        if(t==1){
            int x,v;cin>>x>>v;
            a[x]=v;
        }else{
            int l,r;cin>>l>>r;
            long long sum = 0;
            for(int x=0;x<=r-l;x++) sum = (sum + fibo[x]*a[l+x])%M;
            cout << sum << "\n";
        }
    }
}
//hello


#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define MOD 1000000000
typedef long long ll;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef pair<int,int> ii;

int n, m;
vector<ll> v;

int main(void) {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;

	for(int i = 0; i < n; i++){
		ll x;
		cin >> x;
		v.pb(x);
	}

	for(int i = 0; i < m; i++){
		ll t,x,a;
		cin >> t >> x >> a;
		if(t == 1){
			v[x-1] = a;
		}
		else if(t == 2){
			ll l = x;
			ll r = a;
			l--;r--;
			ll ans = 0;
			ll f = 1;
			ll prev1 = 1;
			ll prev2 = 1;
			ans = (v[l])%MOD;
			if (r == l)
			{
				cout << ans % MOD << endl;
				continue;
			}
			ans = (((ans%MOD) + (v[l+1]%MOD))%MOD);

			for(int j = l+2; j <= r; j++){
				ll aux = f;
				f = (prev1 + prev2)%MOD;
				ans = (ans%MOD + ((((f%MOD)*(v[j]%MOD))%MOD)%MOD));
				prev1 = aux%MOD;
				prev2 = f%MOD;
			}
			cout << ans%MOD << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define MOD 1000000000
typedef long long ll;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef pair<int,int> ii;

int n, m;
vector<ll> v;

int main(void) {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;

	for(int i = 0; i < n; i++){
		int x;
		cin >> x;
		v.pb(x);
	}

	for(int i = 0; i < m; i++){
		int t,x,a;
		cin >> t >> x >> a;
		if(t == 1){
			v[x-1] = a;
		}
		else if(t == 2){
			int l = x;
			int r = a;
			l--;r--;
			ll ans = 0;
			ll f = 1;
			ll prev1 = 1;
			ll prev2 = 1;
			ans = (v[l])%MOD;
			ans = ((ans%MOD) + (v[l+1]%MOD));
			for(int j = l+2; j <= r; j++){
				ll aux = f;
				f = (prev1 + prev2)%MOD;
				ans = (ans%MOD + ((f*(v[j%MOD]))%MOD));
				prev1 = aux%MOD;
				prev2 = f%MOD;
			}
			cout << ans%MOD << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define MOD 1000000000
typedef long long ll;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef pair<int,int> ii;

int n, m;
vector<ll> v;

int main(void) {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;

	for(int i = 0; i < n; i++){
		ll x;
		cin >> x;
		v.pb(x);
	}

	for(int i = 0; i < m; i++){
		ll t,x,a;
		cin >> t >> x >> a;
		if(t == 1){
			v[x-1] = a;
		}
		else if(t == 2){
			ll l = x;
			ll r = a;
			l--;r--;
			ll ans = 0;
			ll f = 1;
			ll prev1 = 1;
			ll prev2 = 1;
			ans = (v[l])%MOD;
			ans = (((ans%MOD) + (v[l+1]%MOD))%MOD);

			for(int j = l+2; j <= r; j++){
				ll aux = f;
				f = (prev1 + prev2)%MOD;
				ans = (ans%MOD + ((f*(v[j])%MOD)%MOD));
				prev1 = aux%MOD;
				prev2 = f%MOD;
			}
			cout << ans%MOD << endl;
		}
	}

	return 0;
}


#include<bits/stdc++.h>

#define SZ(x) ((int(x.size())))

typedef long long ll;

using namespace std;

const int maxn = 200*1000+10, mod = 1000000000;
int n, m, t, x, y, d, arr[maxn], zero;
ll sum1[4 * maxn], sum2[4 * maxn], data[4 * maxn], f[maxn], psum[maxn];

struct pack
{
    ll jam1, jam2, cnt;
    pack()
    {
        jam1 = jam2 = cnt = 0;
    }
};

void bld (int x, int &l, int &r)
{
    if (r - l == 1)
    {
        sum1[x] = arr[l];
        return;
    }
    int mid = (l + r) / 2;
    bld (2 * x + 1, l, mid);
    bld (2 * x + 2, mid, r);
    sum1[x] = (sum1[2 * x + 1] + ((((sum1[2 * x + 2] * f[mid - l]) % mod) + ((sum2[2 * x + 2] * f[mid - l - 1]) % mod)) % mod)) % mod;
    sum2[x] = (sum2[2 * x + 1] + ((sum1[2 * x + 2] * f[mid - l - 1]) % mod)) % mod;
    if (mid - l > 1)
        sum2[x] = (sum2[x] + ((sum2[2 * x + 2] * f[mid - l - 2]) % mod)) % mod;
}

void push (int x, int &l, int &r)
{
    int mid = (l + r) / 2;
    data[2 * x + 1] = (data[2 * x + 1] + data[x]) % mod;
    data[2 * x + 2] = (data[2 * x + 2] + data[x]) % mod;
    sum1[2 * x + 1] = (sum1[2 * x + 1] + ((data[x] * psum[mid - l]) % mod)) % mod;
    sum2[2 * x + 1] = (sum2[2 * x + 1] + ((data[x] * psum[mid - l - 1]) % mod)) % mod;
    sum1[2 * x + 2] = (sum1[2 * x + 2] + ((data[x] * psum[r - mid]) % mod)) % mod;
    sum2[2 * x + 2] = (sum2[2 * x + 2] + ((data[x] * psum[r - mid - 1]) % mod)) % mod;
    data[x] = 0;
}

void add (int x, int &l, int &r, int &ql, int &qr, int &val)
{
    if (l >= qr || ql >= r)
        return;
    if (ql <= l && r <= qr)
    {
        data[x] = (data[x] + val) % mod;
        sum1[x] = (sum1[x] + ((psum[r - l] * val) % mod)) % mod;
        sum2[x] = (sum2[x] + ((psum[r - l - 1] * val) % mod)) % mod;
        return;
    }
    int mid = (l + r) / 2;
    push (x, l, r);
    add (2 * x + 1, l, mid, ql, qr, val);
    add (2 * x + 2, mid, r, ql, qr, val);
    sum1[x] = (sum1[2 * x + 1] + ((((sum1[2 * x + 2] * f[mid - l]) % mod) + ((sum2[2 * x + 2] * f[mid - l - 1]) % mod)) % mod)) % mod;
    sum2[x] = (sum2[2 * x + 1] + ((sum1[2 * x + 2] * f[mid - l - 1]) % mod)) % mod;
    if (mid - l > 1)
        sum2[x] = (sum2[x] + ((sum2[2 * x + 2] * f[mid - l - 2]) % mod)) % mod;
}

void st (int x, int &l, int &r, int &a, int &v)
{
    if (r - l == 1)
    {
        sum1[x] = v;
        return;
    }
    int mid = (l + r) / 2;
    push (x, l, r);
    if (a < mid)
        st (2 * x + 1, l, mid, a, v);
    else
        st (2 * x + 2, mid, r, a, v);
    sum1[x] = (sum1[2 * x + 1] + ((((sum1[2 * x + 2] * f[mid - l]) % mod) + ((sum2[2 * x + 2] * f[mid - l - 1]) % mod)) % mod)) % mod;
    sum2[x] = (sum2[2 * x + 1] + ((sum1[2 * x + 2] * f[mid - l - 1]) % mod)) % mod;
    if (mid - l > 1)
        sum2[x] = (sum2[x] + ((sum2[2 * x + 2] * f[mid - l - 2]) % mod)) % mod;
}

pack req (int x, int &l, int &r, int &ql, int &qr)
{
    pack ans;
    if (l >= qr || ql >= r)
        return ans;
    if (ql <= l && r <= qr)
    {
        ans.jam1 = sum1[x];
        ans.jam2 = sum2[x];
        ans.cnt = r - l;
        return ans;
    }
    int mid = (l + r) / 2;
    push (x, l, r);
    if (qr <= mid)
        return req (2 * x + 1, l, mid, ql, qr);
    else if (ql >= mid)
        return req (2 * x + 2, mid, r, ql, qr);
    else
    {
        pack ansl = req (2 * x + 1, l, mid, ql, qr), ansr = req (2 * x + 2, mid, r, ql, qr);
        ans.cnt = ansl.cnt + ansr.cnt;
        ans.jam1 = (ansl.jam1 + ((((ansr.jam1 * f[ansl.cnt]) % mod) + ((ansr.jam2 * f[ansl.cnt - 1]) % mod)) % mod)) % mod;
        ans.jam2 = (ansl.jam2 + ((ansr.jam1 * f[ansl.cnt - 1]) % mod)) % mod;
        if (ansl.cnt > 1)
            ans.jam2 = (ans.jam2 + ((ansr.jam2 * f[ansl.cnt - 2]) % mod)) % mod;
        return ans;
    }
}

int main()
{
    scanf("%d %d", &n, &m);
    f[0] = f[1] = psum[1] = 1;
    psum[2] = 2;
    for (int i = 2; i + 1 < maxn; i++)
    {
        f[i] = (f[i - 1] + f[i - 2]) % mod;
        psum[i + 1] = (psum[i] + f[i]) % mod;
    }
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    bld (zero, zero, n);
    for (int i = 0; i < m; i++)
    {
        scanf("%d", &t);
        x--;
        if (t == 1)
        {
            scanf("%d %d", &x, &d);
            x--;
            st (zero, zero, n, x, d);
        }
        else if (t == 2)
        {
            scanf("%d %d", &x, &y);
            x--;
            printf("%I64d\n", req (zero, zero, n, x, y).jam1);
        }
        else
        {
            scanf("%d %d %d", &x, &y, &d);
            x--;
            add (zero, zero, n, x, y, d);
        }
    }
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int md = 1e9 , n , m;
    scanf("%d%d",&n,&m);
    vector<long long>  a1(n);
    vector<int> ar(n);
    a1[0] = a1[1] = 1;
    for(int i = 2 ;i < n ;i ++)
        a1[i] = (a1[i - 1] + a1[i - 2]) % md;
    for(int i = 0; i < n ;i ++)
        scanf("%d",&ar[i]);
    for(int i = 0; i < m ;i ++){
        int t , a , b , sm = 0;
        scanf("%d%d%d",&t,&a,&b);
        if(t == 1)
            ar[a - 1] = b;
        else if(t == 2){
            for(int l = a - 1 , k = 0; l < b ;l ++ , k ++)
                sm = (sm + a1[k] * ar[l]) % md;
            printf("%d\n",sm);
        }
    }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>
#include <set>
#include <string>
#include <tuple>
#include <fstream>
#include <stdio.h>
#include <cstring>
#include <map>
#include <queue>
#include <bitset>

using namespace std;

#define vec vector
#define ALL(x) (x).begin(), (x).end()
#define mp make_pair
#define mt make_tuple

typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair< int, int > pii;

const int inf = 1000000000;
const ll inf64 = 1ll * inf * inf;
const double pi = acos(-1.0);

int n, m;
vec< int > F, a, sumF;

struct Node {
	int len;
	int g1, g2;
	int delt;

	Node() {
		len = delt = g1 = g2 = 0;
	}

	Node & operator = (const Node T) {
		len = T.len;
		g1 = T.g1;
		g2 = T.g2;
		delt = T.delt;
		return *this;
	}
};

Node merge(Node l, Node r) {
	Node ans;

	ans.delt = 0;
	ans.len = l.len + r.len;

	int k = l.len + 1;
	ans.g1 = (l.g1 + (1ll * r.g2 * F[k - 1] % inf + 1ll * r.g1 * F[k - 2] % inf) % inf) % inf;
	k++;
	ans.g2 = (l.g2 + (1ll * r.g2 * F[k - 1] % inf + 1ll * r.g1 * F[k - 2] % inf) % inf) % inf;

	return ans;
}

vec< Node > t;

void push(int v, int tl, int tr) {
	if(t[v].delt) {

		int tm = (tl + tr) / 2;

		// ls

		t[v << 1].delt += t[v].delt;
		t[v << 1].len = tm - tl + 1;
		t[v << 1].g1 = (t[v << 1].g1 + 1ll * t[v].delt * sumF[ t[v << 1].len ] % inf) % inf;
		t[v << 1].g2 = (t[v << 1].g2 + 1ll * t[v].delt * ( ( (sumF[ t[v << 1].len + 1 ] - sumF[1]) % inf + inf) % inf ) % inf) % inf;

		// rs

		t[v << 1 | 1].delt += t[v].delt;
		t[v << 1 | 1].len = tr - tm;
		t[v << 1 | 1].g1 = (t[v << 1 | 1].g1 + 1ll * t[v].delt * sumF[ t[v << 1 | 1].len ] % inf) % inf;
		t[v << 1 | 1].g2 = (t[v << 1 | 1].g2 + 1ll * t[v].delt * ( ( (sumF[ t[v << 1 | 1].len + 1 ] - sumF[1]) % inf + inf) % inf) % inf) % inf;

		// ---

		t[v << 1].delt %= inf;
		t[v << 1 | 1].delt %= inf;

		t[v].delt = 0;
	}
}

void build(int v, int tl, int tr) {
	if(tl == tr) {
		t[v].delt = 0;
		t[v].len = 1;
		t[v].g1 = (1ll * F[1] * a[tl]) % inf;
		t[v].g2 = (1ll * F[2] * a[tl]) % inf;
	}else {
		int tm = (tl + tr) / 2;
		build(v << 1, tl, tm);
		build(v << 1 | 1, tm + 1, tr);
		t[v] = merge(t[v << 1], t[v << 1 | 1]);
	}
}

void put(int v, int tl, int tr, int p, int value) {
	if(tl == tr) {
		t[v].delt = 0;
		t[v].g1 = (1ll * value * F[1]) % inf;
		t[v].g2 = (1ll * value * F[2]) % inf;
		t[v].len = 1;
		a[tl] = value;
	}else {
		int tm = (tl + tr) / 2;
		push(v, tl, tr);
		if(p <= tm) put(v << 1, tl, tm, p, value);
		else put(v << 1 | 1, tm + 1, tr, p, value);
		t[v] = merge(t[v << 1], t[v << 1 | 1]);
	}
}

Node get(int v, int tl, int tr, int l, int r) {
	if(l <= tl && tr <= r) return t[v];
	else {
		int tm = (tl + tr) / 2;
		push(v, tl, tr);
		Node ans;
		if(l <= tm) {
			if(r > tm) ans = merge(get(v << 1, tl, tm, l, r), get(v << 1 | 1, tm + 1, tr, l, r));
			else ans = get(v << 1, tl, tm, l, r);
		}else ans = get(v << 1 | 1, tm + 1, tr, l, r);
		t[v] = merge(t[v << 1], t[v << 1 | 1]);
		return ans;
	}
}

void inc(int v, int tl, int tr, int l, int r, int d) {
	if(l <= tl && tr <= r) {
		t[v].delt = (t[v].delt + d) % inf;
		t[v].len = tr - tl + 1;
		t[v].g1 = (t[v].g1 + 1ll * d * sumF[ t[v].len ] % inf) % inf;
		t[v].g2 = (t[v].g2 + 1ll * d * ( ( (sumF[ t[v].len + 1 ] - sumF[1]) % inf + inf) % inf ) % inf) % inf;
	}else {
		int tm = (tl + tr) / 2;
		push(v, tl, tr);
		if(l <= tm) inc(v << 1, tl, tm, l, r, d);
		if(r > tm) inc(v << 1 | 1, tm + 1, tr, l, r, d);
		t[v] = merge(t[v << 1], t[v << 1 | 1]);
	}
}

bool solve() {

	scanf("%d %d", &n, &m);

	F.resize(n + n + 1);

	F[0] = 0;
	F[1] = 1;

	for(int i = 2;i <= n + n;i++) F[i] = (F[i - 1] + F[i - 2]) % inf;

	sumF.resize(n + n + 1);
	for(int i = 1;i <= n + n;i++) sumF[i] = (sumF[i - 1] + F[i]) % inf;

	a.resize(n + 1);
	for(int i = 1;i <= n;i++) scanf("%d", &a[i]);

	t.resize(4 * n, Node());

	build(1, 1, n);

	for(int ty, x, v, l, r, d;m;m--) {
		scanf("%d", &ty);
		if(ty == 1) {
			scanf("%d %d", &x, &v);
			put(1, 1, n, x, v);
		}else if(ty == 2) {
			scanf("%d %d", &l, &r);
			printf("%d\n", get(1, 1, n, l, r).g1);
		}else {
			scanf("%d %d %d", &l, &r, &d);
			inc(1, 1, n, l, r, d);
		}
	}

	return true;
}

int main() {

	//while(solve());
	solve();

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const ll MOD = 1000000000;

int main()
{
  int n, m, t, x, y;
  ll v, f[105] = {1, 1};
  for (int i = 2; i <= 100; ++i) f[i] = (f[i-1]+f[i-2])%MOD;
  scanf("%d%d", &n, &m);
  ll a[n];
  for (int i = 1; i <= n; ++i) scanf("%I64d", a+i);
  while (m--) {
  	scanf("%d", &t);
  	if (t == 1)
  	  scanf("%d%lld", &x, &v), a[x] = v;
  	else if (t == 2) {
  	  ll s = 0;
  	  scanf("%d%d", &x, &y);
  	  for (int i = x; i <= y; ++i) s = (s+f[i-x]*a[i])%MOD;
  	  printf("%I64d\n", s);
  	}
  }
}


#include<bits/stdc++.h>
#define Fib(L,R) (U[(R)+2]-U[(L)+1])
#define lowbit(x) x & -x
#define rint register int
using namespace std;

const int mod = 1e9, MAX = 2e5 + 10;

struct node {
	int x, y;
	node() {}
	node(int a) { x = y = a; }
	node(int X, int Y) { x = X, y = Y; }
	inline node operator * (node b) { return node((1LL * x * b.x + 1LL * y * b.y) % mod, (1LL * y * b.x + 1LL * b.y * (x - y + mod) % mod)); }
	inline node & operator += (node b) { return *this = node((x + b.x) % mod, (y + b.y) % mod); }
	inline node operator + (node b) { return node((x + b.x) % mod, (y + b.y) %mod); }
	inline node operator - (node b) { return node((x + mod - b.x) % mod, (y + mod - b.y) %mod); }
}f[MAX], U[MAX], E[MAX];
int c[MAX], n, m;

inline node operator * (int k, node a) { return node(1LL * k * a.x % mod, 1LL * k * a.y % mod); }

inline void Add(int &x, int v) { (x += v) < mod ? : x -= mod;}

inline void ED(int p, int k) {
	static node a;
	a = k * U[p];
	for(rint r = p; r <= n; r += lowbit(r))	f[r] += a;
}

inline void AD(int p, int k){
	if(!p)	return;
	for(rint r = p, l; r; l = r - lowbit(r), Add(c[r], k), f[r] += k * Fib(l + 1, r), r = l);
	for(rint r = p + lowbit(p), l; r <= n; l = r - lowbit(r), f[r] += k * Fib(l + 1, p), r += lowbit(r));
}

inline node QU(int p) {
	if(!p) return 0;
	static node a;
	a = node(0, 0);
	for(rint r = p; r; a += f[r], r -= lowbit(r));
	for(rint r = p + lowbit(p), l; r <= n; l = r - lowbit(r), a += c[r] * Fib(l + 1, p), r += lowbit(r));
	return a;
}

inline int read() {
	int s = 0, f = 1;
	char ch;
	for(; ch < '0' || ch > '9'; ch = getchar())	if(ch == '-')	f = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar())	s = (s << 1) + (s << 3) + ch - '0';
	return s * f;
}

int main() {
	n = read(), m = read(), U[0] = node(1,0), U[1] = node(1,1);
	for(rint i = 2; i <= n+2; U[i] = U[i-1]*U[1], i++);
	E[0] = node(1,0), E[1] = node(0,1);
	for(rint i = 2; i <= n + 2; E[i] = E[i - 1] * E[1], i++);
	for(rint i = 1; i <= n; ED(i, read()), i++);
	for(rint l, r, x; m--; )
		switch(read()) {
			case 1: l = read(), ED(l, (read() + mod - ((QU(l) - QU(l - 1)) * E[l]).x) % mod);	break;
			case 2: l = read(), r = read(), printf("%d\n", ((QU(r) - QU(l - 1)) * E[l]).x);	break;
			case 3: l = read(), r = read(), x = read(), AD(r, x), AD(l - 1, mod - x);	break;
		}
	return 0;
}


#include<bits/stdc++.h>
#define Fib(L,R) (U[(R)+2]-U[(L)+1])
#define lowbit(x) (x & -x)
#define rint register int
using namespace std;

const int mod = 1e9, MAX = 2e5 + 10;
struct node {
	int x, y;
	node() {}
	node(int a) { x = y = a; }
	node(int X, int Y) { x = X, y = Y; }
	inline node operator * (node b){ return node((1LL * x * b.x + 1LL * y * b.y) % mod, (1LL * y * b.x + 1LL * b.y * (x + mod - y)) % mod); }
	inline node&operator +=(node b){ return *this = node((x + b.x) % mod, (y + b.y) % mod); }
	inline node operator + (node b){ return node((x + b.x) % mod, (y + b.y) % mod); }
	inline node operator - (node b){ return node((x + mod - b.x) % mod, (y + mod - b.y) % mod); }
}f[MAX], U[MAX], E[MAX];
int c[MAX], n, m;

inline int read() {
	int s = 0, f = 1;
	char ch;
	for(; ch < '0' || ch > '9'; ch = getchar())	if(ch == '-')	f = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar())	s = (s << 1) + (s << 3) + ch - '0';
	return s * f;
}

inline node operator * (int k, node a) { return node(1LL * k * a.x % mod, 1LL * k * a.y % mod); }

inline void Add(int &x, int v) { (x += v) < mod ? : x -= mod;}

inline void ED(int p, int k) {
	static node a;
	a = k * U[p];
	for(rint r = p; r <= n; r += lowbit(r))	f[r] += a;
}

inline void AD(int p, int k){
	if(!p)	return;
	for(rint r = p, l; r; l = r - lowbit(r), Add(c[r], k), f[r] += k * Fib(l + 1, r), r = l);
	for(rint r = p + lowbit(p), l; r <= n; l = r - lowbit(r), f[r] += k * Fib(l + 1, p), r += lowbit(r));
}

inline node QU(int p) {
	if(!p) return 0;
	static node a;
	a = node(0, 0);
	for(rint r = p; r; a += f[r], r -= lowbit(r));
	for(rint r = p + lowbit(p), l; r <= n; l = r - lowbit(r), a += c[r] * Fib(l + 1, p), r += lowbit(r));
	return a;
}

int main() {
	n = read(), m = read(), U[0] = node(1, 0), U[1] = node(1, 1);
	for(rint i = 2; i <= n + 2; U[i] = U[i - 1] * U[1], i++);
	E[0] = node(1, 0), E[1] = node(0, 1);
	for(rint i = 2; i <= n + 2; E[i] = E[i - 1] * E[1], i++);
	for(rint i = 1; i <= n; ED(i, read()), i++);
	for(rint l, r, x; m--; )
		switch(read()) {
			case 1: l = read(), ED(l, (read() + mod - ((QU(l) - QU(l - 1)) * E[l]).x) % mod);	break;
			case 2: l = read(), r = read(), printf("%d\n", ((QU(r) - QU(l - 1)) * E[l]).x);	break;
			case 3: l = read(), r = read(), x = read(), AD(r, x), AD(l - 1, mod - x);	break;
		}
	return 0;
}


#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
using namespace std;
template<class t> inline t read(t &x){
    char c=getchar();bool f=0;x=0;
    while(!isdigit(c)) f|=c=='-',c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    if(f) x=-x;return x;
}
template<class t> inline void write(t x){
    if(x<0) putchar('-'),write(-x);
    else{if(x>9) write(x/10);putchar('0'+x%10);}
}

const int mod=1e9,N=2e5+5;
int tr0[N<<2],tr1[N<<2],tg[N<<2],n,m,f[N],sum[N];

int trans(int x,int len){
	if(!len) return tr0[x];
	if(len==1) return tr1[x];
	return (1ll*tr0[x]*f[len-2]+1ll*tr1[x]*f[len-1])%mod;
}

void pushup(int x,int l,int r){
	int mid=l+r>>1;
	tr0[x]=tr0[x<<1]+trans(x<<1|1,mid-l+1);
	if(tr0[x]>mod) tr0[x]-=mod;
	tr1[x]=tr1[x<<1]+trans(x<<1|1,mid-l+2);
	if(tr1[x]>mod) tr1[x]-=mod;
}

void build(int x,int l,int r){
	if(l==r){
		tr0[x]=read(tr1[x]);
		return ;
	}
	int mid=l+r>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	pushup(x,l,r);
}

void add(int x,int len,int v){
	tg[x]+=v;
	if(tg[x]>mod) tg[x]-=mod;
	tr0[x]=(tr0[x]+1ll*sum[len-1]*v)%mod;
	tr1[x]=(tr1[x]+1ll*(sum[len]-1+mod)*v)%mod;
}

void pushdown(int x,int l,int r){
	if(!tg[x]) return ;
	int mid=l+r>>1;
	add(x<<1,mid-l+1,tg[x]);
	add(x<<1|1,r-mid,tg[x]);
	tg[x]=0;
}

void mfy(int x,int l,int r,int p,int v){
	if(l==r){
		tr0[x]=tr1[x]=v;
		return ;
	}
	pushdown(x,l,r);
	int mid=l+r>>1;
	if(p<=mid) mfy(x<<1,l,mid,p,v);
	else mfy(x<<1|1,mid+1,r,p,v);
	pushup(x,l,r);
}

void up(int x,int l,int r,int p,int q,int v){
	if(p<=l&&r<=q){
		add(x,r-l+1,v);
		return ;
	}
	pushdown(x,l,r);
	int mid=l+r>>1;
	if(p<=mid) up(x<<1,l,mid,p,q,v);
	if(q>mid) up(x<<1|1,mid+1,r,p,q,v);
	pushup(x,l,r);
}

int que(int x,int l,int r,int p,int q){
	if(p<=l&&r<=q) return trans(x,l-p);
	pushdown(x,l,r);
	int mid=l+r>>1,res=0;
	if(p<=mid) res+=que(x<<1,l,mid,p,q);
	if(q>mid) res+=que(x<<1|1,mid+1,r,p,q);
	if(res>mod) res-=mod;
	return res;
}

signed main(){
	read(n);read(m);
	f[0]=f[1]=1;
	sum[0]=1;sum[1]=2;
	for(int i=2;i<=n;i++){
		f[i]=f[i-1]+f[i-2];
		if(f[i]>mod) f[i]-=mod;
		sum[i]=sum[i-1]+f[i];
		if(sum[i]>mod) sum[i]-=mod;
	}
	build(1,1,n);
	while(m--){
		int op;
		read(op);
		if(op==1){
			int p,v;
			read(p);read(v);
			mfy(1,1,n,p,v);
		}
		if(op==2){
			int l,r;
			read(l);read(r);
			write(que(1,1,n,l,r));puts("");
		}
		if(op==3){
			int l,r,v;
			read(l);read(r);read(v);
			up(1,1,n,l,r,v);
		}
	}
}


///ma hotel homa digar hich
#include <bits/stdc++.h>
#define pb push_back
#define F first
#define S second

using namespace std;
typedef long long ll;

int F[20000],a[200 * 10000] , mod = 1e9;
map <ll,bool> mark;
int main(){
    int n,m;
    cin >> n >> m;
    for(int i = 1; i <=n ; i++)
        cin >> a[i];
    F[0] = F[1] = 1;
    for (int i = 2; i <= 1000 ; i++)
        F[i] = (F[i - 1] + F[i - 2]) % mod;
    for(int i = 0 ; i < m ; i++){
        int t,x,v; cin >> t >> x >> v;
        if(t == 1)
           a[x] = v;
        if(t == 2){
            ll ans = 0;
            for(int j = x ; j <=v ; j++)
                ans += (F[j - x] * a[j]) % mod;
            cout << ans << endl;
        }
        if(t == 3){
            int d;cin >> d;
            for(int i = x ; i <= v ; i++)
                a[i] += d,a[i] %= mod;
        }
    }

}


///ma hotel homa digar hich
#include <bits/stdc++.h>
#define pb push_back
#define F first
#define S second

using namespace std;
typedef long long ll;

ll F[20000],a[200 * 10000] , mod = 1e9;

int main(){
    int n,m;
    cin >> n >> m;
    for(int i = 1; i <=n ; i++)
        cin >> a[i];
    F[0] = F[1] = 1;
    for (int i = 2; i <= 1000 ; i++)
        F[i] = (F[i - 1] + F[i - 2]) % mod;
    for(int i = 0 ; i < m ; i++){
        ll t,x,v; cin >> t >> x >> v;
        if(t == 1)
           a[x] = v;
        if(t == 2){
            ll ans = 0;
            for(int j = x ; j <=v ; j++)
                ans += (1ll * F[j - x] * a[j]) % mod, ans %= mod;
            cout << ans << endl;
        }
        if(t == 3){
            int d;cin >> d;
            for(int i = x ; i <= v ; i++)
                a[i] += d,a[i] %= mod;
        }
    }

}


#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 200005
#define inf 1000000007
#define mod 1000000000
#define mp make_pair
#define pb push_back
#define ll long long
#define uint unsigned int
#define pii pair<int, int>
#define ull unsigned long long
#define sz(v) ((int)(v).size())
#define gc() fgetc(stdin)
template<typename T> void read(T &a) {
	register int b = 1, c; a = 0;
	for (c=gc(); c > 57 || c < 48; c=gc()) if (c == 45) b = -1;
	for (; c >= 48 && c <= 57; c=gc()) a = a * 10 + c - 48;
	a *= b;
}

#define ADD(x, y) (((x) + (y)) % mod)
#define MUL(x, y) ((1LL * (x) * (y)) % mod)

struct mat {
	int x, y, arr[3][3];
	mat(): x(0), y(0) { arr[0][0] = arr[0][1] = arr[1][0] = arr[1][1] = 0; }
	inline void init(int a, int b) { x = a; y = b; }
	inline mat operator * (const mat &a) const {
		mat t;
		t.init(x, a.y);
		for (int i = 0; i < t.x; i++) {
			for (int j = 0; j < t.y; j++) {
				for (int k = 0; k < y; k++) {
					t.arr[i][j] = ADD(t.arr[i][j], MUL(arr[i][k], a.arr[k][j]));
				}
			}
		}
		return t;
	}
};

mat fib, pre[N];

struct SEGT {
	int sz;
	struct node {
		int sum0, sum1, val, sz;
		node():sum0(0), sum1(0), val(0) {sz = 0;}
		node(int a, int b): sum0(a), sum1(b) {}
	};
	node nodes[4 * N];
	inline void init(int n) {
		for (sz = 1; sz <= n; sz <<= 1);
	}
	inline void pushup(node &a, node b, node c) {
		mat cur;
		cur.init(2, 1);
		cur.arr[0][0] = c.sum0;
		cur.arr[1][0] = c.sum1;
		mat matrix = pre[b.sz] * cur;
		a.sum0 = ADD(b.sum0, matrix.arr[0][0]);
		a.sum1 = ADD(b.sum1, matrix.arr[1][0]);
	}
	inline void pushup(int i) {
		if (i < sz) pushup(nodes[i], nodes[i << 1], nodes[i << 1 | 1]);
	}
	inline void build(int a, int b, int i, int n, int* arr) {
		// printf("build %d %d %d\n", a, b, i);
		if (b - a == 1) {
			nodes[i].val = nodes[i].sum0 = nodes[i].sum1 = arr[i - sz];
			nodes[i].sz = (i - sz) < n;
			return;
		}
		int m = (a + b) >> 1;
		build(a, m, i << 1, n, arr);
		build(m, b, i << 1 | 1, n, arr);
		nodes[i].sz = nodes[i << 1].sz + nodes[i << 1 | 1].sz;
		nodes[i].val = ADD(nodes[i << 1].val, nodes[i << 1 | 1].val);
		pushup(i);
	}
	inline void change(int i, int val) {
		i += sz - 1;
		nodes[i].val = nodes[i].sum0 = nodes[i].sum1 = val;
		while ((i >>= 1) >= 1) pushup(i);
	}
	inline node query(int a, int b, int i, int l, int r) {
		// printf("query %d %d %d %d %d\n", a, b, i, l, r);
		if (l <= a && b <= r) return nodes[i];
		if (r <= a || b <= l) return node();
		node x, y, ans;
		int m = (a + b) >> 1;
		x = query(a, m, i << 1, l, r);
		y = query(m, b, i << 1 | 1, l, r);
		ans.sz = x.sz + y.sz;
		pushup(ans, x, y);
/*		printf("in query %d %d %d %d %d, ", a, b, i, l, r);
		printf("x = %d %d %d, ", x.sum0, x.sum1, x.sz);
		printf("y = %d %d %d, ", y.sum0, y.sum1, y.sz);
		printf("ans = %d %d %d\n", ans.sum0, ans.sum1, ans.sz);
*/		return ans;
	}
};
SEGT segt;

int n, q, arr[N];

int main() {
	// freopen("input.txt", "r", stdin);
	// freopen("output.txt", "w", stdout);
	fib.init(2, 2);
	fib.arr[0][0] = 0; fib.arr[0][1] = 1;
	fib.arr[1][0] = 1; fib.arr[1][1] = 1;
	read(n); read(q);
	pre[0].init(2, 2);
	pre[0].arr[0][0] = 1; pre[0].arr[0][1] = 0;
	pre[0].arr[1][0] = 0; pre[0].arr[1][1] = 1;
	for (int i = 1; i <= n; i++) pre[i] = pre[i-1] * fib;
	segt.init(n);
	for (int i = 0; i < n; i++) read(arr[i]);
	segt.build(0, segt.sz, 1, n, arr);
	while (q--) {
		int t;
		read(t);
		if (t == 1) {
			int a, b;
			read(a); read(b);
			segt.change(a, b);
		} else {
			int a, b;
			read(a); read(b);
			printf("%d\n", segt.query(0, segt.sz, 1, a-1, b).sum0);
		}
	}
	return 0;
}


#include<cstdio>

#define mo 1000000000
#define ran 111

int n, m;
int a[ran];
int d[ran];

int main() {
	scanf("%d%d", &n, &m);
	for(int i=1;i<=n;i++) scanf("%d", &a[i]);
	d[0] = d[1] = 1;
	for(int i=2;i<=n;i++) d[i] = (d[i-1]+d[i-2])%mo;
	for(int i=0;i<m;i++) {
		int op, x, y;
		scanf("%d%d%d", &op, &x, &y);
		if(op==1) a[x] = y;
		else {
			int res = 0;
			for(int j=x;j<=y;j++)
				res = (res+(1LL*a[j]*d[j-x])%mo)%mo;
			printf("%d\n", res);
		}
	}

	return 0;
}


	#include<bits/stdc++.h>
	#define all(v) (v).begin(),(v).end()
	#define pb push_back
	#define mp make_pair
	using namespace std;
	typedef long long ll;
	const int N=2e5+5;
	const int mod=1e9;
	int lazy[4*N];
	int pfib[N];
	int s1[4*N];
	int s2[4*N];
	int f[N];

	inline int jomle(int a,int b,int z)
	{
		if(z==1)
			return a;
		return (1LL*b*f[z-1]+1LL*a*f[z-2])%mod;
	}

	inline void pull(int v,int l,int r)
	{
		int mid=(r+l)/2;
		s1[v]=(s1[2*v]+jomle(s1[2*v+1],s2[2*v+1],mid-l+1))%mod;
		s2[v]=(s2[2*v]+jomle(s1[2*v+1],s2[2*v+1],mid-l+2))%mod;
	}

	void fix(int v,int l,int r,int x,int val)
	{
		if(x<l || r<=x)
			return;
		if(r-l==1)
		{
			s1[v]=s2[v]=val;
			return;
		}
		int mid=(r+l)/2;
		fix(2*v,l,mid,x,val);
		fix(2*v+1,mid,r,x,val);
		pull(v,l,r);
	}

	inline void add(int v,int l,int r,int val)
	{
		lazy[v]=(lazy[v]+val)%mod;
		s1[v]=(1LL*val*pfib[r-l]+1LL*s1[v])%mod;
		s2[v]=(1LL*val*(pfib[r-l+1]-1+mod)+1LL*s2[v])%mod;
	}

	inline void shift(int v,int l,int r)
	{
		int mid=(r+l)/2;
		add(2*v,l,mid,lazy[v]);
		add(2*v+1,mid,r,lazy[v]);
		lazy[v]=0;
	}

	void update(int v,int l,int r,int s,int e,int val)
	{
		if(e<=l || r<=s)
			return;
		if(s<=l && r<=e)
		{
			add(v,l,r,val);
			return;
		}
		shift(v,l,r);
		int mid=(r+l)/2;
		update(2*v,l,mid,s,e,val);
		update(2*v+1,mid,r,s,e,val);
		pull(v,l,r);
	}

	int getsum(int v,int l,int r,int s,int e)
	{
		if(e<=l || r<=s)
			return 0;
		if(s<=l && r<=e)
			return jomle(s1[v],s2[v],l-s+1);
		shift(v,l,r);
		int mid=(r+l)/2;
		return (getsum(2*v,l,mid,s,e)+getsum(2*v+1,mid,r,s,e))%mod;
	}

	int main()
	{
		ios_base::sync_with_stdio(0);cin.tie(0);
		f[1]=pfib[1]=1;
		for(int i=2;i<N;i++)
		{
			f[i]=(f[i-1]+f[i-2])%mod;
			pfib[i]=(f[i]+pfib[i-1])%mod;

		}
		int n,q;
		cin >> n >> q;
		int x;
		for(int i=1;i<=n;i++)
		{
			cin >> x;
			fix(1,1,n+1,i,x);
		}
		int t,l,r,val;
		while(q--)
		{
			cin >> t;
			if(t==1)
			{
				cin >> x >> val;
				fix(1,1,n+1,x,val);
			}
			if(t==2)
			{
				cin >> l >> r;
				cout<<getsum(1,1,n+1,l,r+1)<<"\n";
			}
			if(t==3)
			{
				cin >> l >> r >> val;
				update(1,1,n+1,l,r+1,val);
			}
		}
		return 0;
	}


#include "bits/stdc++.h"

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define get(x) scanf("%d", &x)
#define all(x) (x).begin(),(x).end()

using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
template <class T> inline void maxi(T &x,T y) {if (y > x) x = y;}
template <class T> inline void mini(T &x,T y) {if (y < x) x = y;}

const int N = 200, B = 0x7fffffff;
const int M = 1e9;
int n, m;
int a[N];
int fib[N];

int main(){
  //freopen("in.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);
  get(n), get(m);
  for (int i = 1; i <= n; i++) get(a[i]);
  fib[1] = fib[2] = 1;
  for (int i = 3; i <= n; i++) fib[i] = fib[i - 1] + fib[i - 2];
  for (int i = 1; i <= m; i++){
    int typ;
    get(typ);
    if (typ == 1){
      int x, y;
      get(x), get(y);
      a[x] = y;
    }
    else{
      int l, r;
      get(l), get(r);
      int ans = 0;
      for (int i = l, j = 1; i <= r; i++, j++){
        ans = (ans + ((fib[j] % M) * (a[i] % M)) % M) % M;
      }
      printf("%d\n", ans);
    }
  }
  return !!0;
}


#include "bits/stdc++.h"

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define get(x) scanf("%d", &x)
#define all(x) (x).begin(),(x).end()

using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
template <class T> inline void maxi(T &x,T y) {if (y > x) x = y;}
template <class T> inline void mini(T &x,T y) {if (y < x) x = y;}

const int N = 200, B = 0x7fffffff;
const int M = 1e9 + 7;
int n, m;
int a[N];
int fib[N];

int main(){
  //freopen("in.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);
  get(n), get(m);
  for (int i = 1; i <= n; i++) get(a[i]);
  fib[1] = fib[2] = 1;
  for (int i = 3; i <= n; i++) fib[i] = fib[i - 1] + fib[i - 2];
  for (int i = 1; i <= m; i++){
    int typ;
    get(typ);
    if (typ == 1){
      int x, y;
      get(x), get(y);
      a[x] = y;
    }
    else{
      int l, r;
      get(l), get(r);
      int ans = 0;
      for (int i = l, j = 1; i <= r; i++, j++){
        ans = (ans + ((fib[j] % M) * (a[i] % M)) % M) % M;
      }
      printf("%d\n", ans);
    }
  }
  return !!0;
}


#include "bits/stdc++.h"

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define get(x) scanf("%d", &x)
#define all(x) (x).begin(),(x).end()

using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
template <class T> inline void maxi(T &x,T y) {if (y > x) x = y;}
template <class T> inline void mini(T &x,T y) {if (y < x) x = y;}

const int N = 200, B = 0x7fffffff;
const int M = 1e9;
int n, m;
int a[N];
int fib[N];

int main(){
  //freopen("in.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);
  get(n), get(m);
  for (int i = 1; i <= n; i++) get(a[i]);
  fib[1] = fib[2] = 1;
  for (int i = 3; i <= n; i++){
    fib[i] = (fib[i - 1] + fib[i - 2]) % M;
  }
  for (int i = 1; i <= m; i++){
    int typ;
    get(typ);
    if (typ == 1){
      int x, y;
      get(x), get(y);
      a[x] = y;
    }
    else{
      int l, r;
      get(l), get(r);
      int ans = 0;
      for (int i = l, j = 1; i <= r; i++, j++){
        ans = (ans + ((fib[j] % M) * (a[i] % M)) % M) % M;
      }
      printf("%d\n", ans);
    }
  }
  return !!0;
}


#include "bits/stdc++.h"

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define get(x) scanf("%d", &x)
#define all(x) (x).begin(),(x).end()

using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
template <class T> inline void maxi(T &x,T y) {if (y > x) x = y;}
template <class T> inline void mini(T &x,T y) {if (y < x) x = y;}

const int N = 200, B = 0x7fffffff;
const int M = 1e9;
int n, m;
ll a[N];
ll fib[N];

int main(){
  //freopen("in.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);
  get(n), get(m);
  for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
  fib[1] = fib[2] = 1;
  for (int i = 3; i <= n; i++) fib[i] = (fib[i - 1] + fib[i - 2]) % M;
  for (int i = 1; i <= m; i++){
    int typ;
    get(typ);
    if (typ == 1){
      int x, y;
      get(x), get(y);
      a[x] = y;
    }
    else{
      int l, r;
      get(l), get(r);
      ll ans = 0;
      for (int i = l, j = 1; i <= r; i++, j++){
        ans = (ans + ((fib[j] % M) * (a[i] % M)) % M) % M;
      }
      printf("%lld\n", ans);
    }
  }
  return !!0;
}


//Legendry

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <limits>
#include <complex>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

namespace solution {
  typedef std::istringstream ISS;
  typedef std::ostringstream OSS;
  typedef std::vector<std::string> VS;
  typedef long long LL;
  typedef int INT;
  typedef std::vector<INT> VI;
  typedef std::vector<VI> VVI;
  typedef std::pair<INT,INT> II;
  typedef std::vector<II> VII;
}

namespace solution {
    class ISolution {
    public:
        virtual void init() {};
        virtual bool input() { return false; };
        virtual void output() {};
        virtual int run() = 0;
    };
+}

namespace solution {
    using namespace std;

   const LL MOD = 1000000000LL;
   const int SIZE = 2 * 100000 + 11;
   const int QUERY_SIZE = 2 * 100000 + 11;
   int n, m;
   LL A[SIZE];
  LL F[SIZE];

   void query_1() {
       int x, v;
        cin >> x >> v;
        A[x] = v;
    }

    void query_2() {
        int l, r;
       cin >> l >> r;
        int len = r - l + 1;
        LL sum = 0;
        for ( int i = 0; i < len; ++ i )
           sum = ( sum + F[i] * A[l + i] ) % MOD;
       cout << sum << endl;
   }

    void solve() {
        F[0] = F[1] = 1;
      for ( int i = 2; i < SIZE; ++ i )
            F[i] = ( F[i - 1] + F[i - 2] ) % MOD;
       for ( int i = 0; i < m; ++ i ) {
            int t;
            cin >> t;
            if ( t == 1 ) {
                query_1();
           } else if ( t == 2 ) {
                query_2();
            }
       }
    }

   class Solution: public ISolution
   {
   public:

      bool input() {
          if ( ! ( cin >> n >> m ) )
               return false;
         for ( int i = 0; i < n; ++ i )
              cin >> A[i + 1];
         return true;
     }
     int run()
	 {
           while ( init(), input() )
		    {
               solve();
                output();
           }
           return 0;
       }

   };
}

int main() {
    return solution::Solution().run();
}


//Legendry

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <limits>
#include <complex>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

namespace solution {
  typedef std::istringstream ISS;
  typedef std::ostringstream OSS;
  typedef std::vector<std::string> VS;
  typedef long long LL;
  typedef int INT;
  typedef std::vector<INT> VI;
  typedef std::vector<VI> VVI;
  typedef std::pair<INT,INT> II;
  typedef std::vector<II> VII;
}

namespace solution
{
    class ISolution
	{
    public:
        virtual void init() {};
        virtual bool input() { return false; }
        virtual void output() {};
        virtual int run() = 0;
    };
}

namespace solution
{
    using namespace std;

   const LL MOD = 1000000000LL;
   const int SIZE = 2 * 100000 + 11;
   const int QUERY_SIZE = 2 * 100000 + 11;
   int n, m;
   LL A[SIZE];
  LL F[SIZE];

   void query_1()
    {
       int x, v;
        cin >> x >> v;
        A[x] = v;
    }

    void query_2()
	 {
        int l, r;
       cin >> l >> r;
        int len = r - l + 1;
        LL sum = 0;
        for ( int i = 0; i < len; ++ i )
           sum = ( sum + F[i] * A[l + i] ) % MOD;
       cout << sum << endl;
   }

    void solve() {
        F[0] = F[1] = 1;
      for ( int i = 2; i < SIZE; ++ i )
            F[i] = ( F[i - 1] + F[i - 2] ) % MOD;
       for ( int i = 0; i < m; ++ i ) {
            int t;
            cin >> t;
            if ( t == 1 ) {
                query_1();
           } else if ( t == 2 )
		   {
                query_2();
            }
       }
    }

   class Solution: public ISolution
   {
   public:

      bool input() {
          if ( ! ( cin >> n >> m ) )
               return false;
         for ( int i = 0; i < n; ++ i )
              cin >> A[i + 1];
         return true;
     }
     int run()
	 {
           while ( init(), input() )
		    {
               solve();
                output();
           }
           return 0;
       }

   };
}

int main() {
    return solution::Solution().run();
}


/*
ID:
PROG:
LANG: C++
 */
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <sstream>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#include <climits>
#include <cstdlib>
using namespace std;

const double Pi=acos(-1.0);

typedef long long ll;
typedef pair<int, int> pii;

#define Set(a, s) memset(a, s, sizeof (a))
#define Rd(r) freopen(r, "r", stdin)
#define Wt(w) freopen(w, "w", stdout)

#define INF (1<<29)+123
#define LL_INF (1<<59)+123

#define MOD 1000000000

int main ()
{
	if (fopen("data.in", "r"))
		Rd("data.in");

	ll N, Q, arr[101], fib[101];
	scanf("%I64d", &N);
	scanf("%I64d", &Q);
	for (int i = 1; i <= N; i++)
		scanf("%I64d", &arr[i]);

	fib[1] = fib[2] = 1;
	for (int i = 3; i <= N; i++)
		fib[i] = (fib[i-1]+fib[i-2])%MOD;

	for (int i = 0; i < Q; i++) {
		int ty, c1, c2;
		scanf("%d", &ty);
		scanf("%d", &c1);
		scanf("%d", &c2);

		if (ty == 1) {
			arr[c1] = c2;
		} else if (ty == 2) {
			ll sum = 0;
			for (int j = 1; j <= c2-c1+1; j++)
				sum = (sum+(fib[j]*arr[c1+j-1])%MOD)%MOD;

			printf("%I64d\n", sum);
		}
	}

	return 0;
}


/*
ID:
PROG:
LANG: C++
 */
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <sstream>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#include <climits>
#include <cstdlib>
using namespace std;

const double Pi=acos(-1.0);

typedef long long ll;
typedef pair<int, int> pii;

#define Set(a, s) memset(a, s, sizeof (a))
#define Rd(r) freopen(r, "r", stdin)
#define Wt(w) freopen(w, "w", stdout)

#define INF (1<<29)+123
#define LL_INF (1<<59)+123

#define MOD 1000000000

int main ()
{
	if (fopen("data.in", "r"))
		Rd("data.in");

	int N, Q, arr[101], fib[101];
	scanf("%d", &N);
	scanf("%d", &Q);
	for (int i = 1; i <= N; i++)
		scanf("%d", &arr[i]);

	fib[1] = fib[2] = 1;
	for (int i = 3; i <= N; i++)
		fib[i] = fib[i-1]+fib[i-2];

	for (int i = 0; i < Q; i++) {
		int ty, c1, c2;
		scanf("%d", &ty);
		scanf("%d", &c1);
		scanf("%d", &c2);

		if (ty == 1) {
			arr[c1] = c2;
		} else if (ty == 2) {
			ll sum = 0;
			for (int j = 1; j <= c2-c1+1; j++)
				sum = (sum+fib[j]*arr[c1+j-1])%MOD;

			printf("%I64d\n", sum);
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long a[101] , f[101] ,mod = 1e9 ;
int main()
{
    int n , m ;
    cin >> n >> m ;
    for(int i = 1 ; i <= n ; i++)cin >> a[i] ;
    f[0] = f[1] = 1 ;
    for(int i = 2 ;i <= 100 ; i++){
        f[i] = f[i-1] + f[i-2] ;
        f[i] %= mod ;
    }
    int t , l , r ;
    for(int i = 1 ; i <= m ; i++){
        scanf("%d%d%d",&t,&l,&r) ;
        if(t == 1){
            a[l] = r ;
        }
        else {
            long long ans = 0 ;
            for(int x = 0 ; x <= r-l ; x++){
                ans += (f[x] * a[l+x]) ;
                ans %= mod ;
            }
            cout << ans  << endl ;
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<bool> vb;

const int MOD = 1000000007;

ll values[110];
ll fibo[110];

int main(void) {
	int n, m, i, j, t;
	scanf("%d %d", &n, &m);
	For(i, 0, n) {
		cin>>values[i];
	}
	For (i, 0, m) {
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			values[x-1] = v;
		} else {
			int l, r;
			scanf("%d %d", &l, &r);
			fibo[0] = fibo[1] = 1;
			ll sum = 0;
			l--; r--;
			For (j, l, r+1) {
				int x = j - l;
				sum = (sum + (fibo[x] * values[j])) % MOD;
				if (x >= 1) {
					fibo[x+1] = (fibo[x] + fibo[x-1]) %MOD;
				}
			}
			cout << sum << endl;
		}
	}
//
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<bool> vb;

const int MOD = 1000000000;

ll values[110];
ll fibo[110];

int main(void) {
	int n, m, i, j, t;
	scanf("%d %d", &n, &m);
	For(i, 0, n) {
		cin>>values[i];
	}
	For (i, 0, m) {
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			values[x-1] = v;
		} else {
			int l, r;
			scanf("%d %d", &l, &r);
			fibo[0] = fibo[1] = 1;
			ll sum = 0;
			l--; r--;
			For (j, l, r+1) {
				int x = j - l;
				sum = (sum + (fibo[x] * values[j])) % MOD;
				if (x >= 1) {
					fibo[x+1] = (fibo[x] + fibo[x-1]) %MOD;
				}
			}
			cout << sum << endl;
		}
	}
//
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<bool> vb;

const int MOD = 1000000007;

int values[110];
int fibo[110];

int main(void) {
	ios::sync_with_stdio(false);
	int n, m, i, j, t;
	scanf("%d %d", &n, &m);
	For(i, 0, n) {
		scanf("%d", values + i);
	}
	For (i, 0, m) {
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			values[x-1] = v;
		} else {
			int l, r;
			scanf("%d %d", &l, &r);
			fibo[0] = fibo[1] = 1;
			ll sum = 0;
			l--; r--;
			For (j, l, r+1) {
				int x = j - l;
				sum = (sum + (fibo[x] * values[j])) % MOD;
				if (x >= 1) {
					fibo[x+1] = (fibo[x] + fibo[x-1]) %MOD;
				}
			}
			cout << sum << endl;
		}
	}
//
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define CH (ch=getchar())
#define dprintf(...) fprintf(stderr,__VA_ARGS__)
#define rep(i,V)     for(__typeof(*V.begin()) i:  V)
#define For(i,a,b)   for(int i=(int)a;i<=(int)b;i++)
#define Forn(i,a,b)  for(int i=(int)a;i>=(int)b;i--)
#define pend(x)      ((x)=='\n'||(x)=='\r'||(x)=='\t'||(x)==' ')
using namespace std;
typedef long long ll;
typedef double db;
const int mo=1e9;
const int N=200005;

inline int IN(){
	char ch;CH; int f=0,x=0;
	for(;pend(ch);CH); if(ch=='-')f=1,CH;
	for(;!pend(ch);CH) x=x*10+ch-'0';
	return (f)?(-x):(x);
}

int n,m,len[N*4],add[N*4],ans,tmp,a[N];
struct node{
	int a11,a12,a21,a22;
}p[N],s[N],t[N*4];

node operator *(const node &a,const node &b){
	node c;
	c.a11=(1ll*a.a11*b.a11+1ll*a.a12*b.a21)%mo;
	c.a12=(1ll*a.a12*b.a22+1ll*a.a11*b.a12)%mo;
	c.a21=(1ll*a.a21*b.a11+1ll*a.a22*b.a21)%mo;
	c.a22=(1ll*a.a22*b.a22+1ll*a.a21*b.a12)%mo;
	return c;
}

node operator +(const node &a,const node &b){
	node c;
	c.a11=a.a11+b.a11; if(c.a11>=mo) c.a11-=mo;
	c.a12=a.a12+b.a12; if(c.a12>=mo) c.a12-=mo;
	c.a21=a.a21+b.a21; if(c.a21>=mo) c.a21-=mo;
	c.a22=a.a22+b.a22; if(c.a22>=mo) c.a22-=mo;
	return c;
}

node operator *(const node &a,const int &b){
	node c=a;
	c.a11=1ll*c.a11*b%mo;
	c.a12=1ll*c.a12*b%mo;
	c.a21=1ll*c.a21*b%mo;
	c.a22=1ll*c.a22*b%mo;
	return c;
}

void jia(int x,int v){
	if(!v) return;
	add[x]+=v; if(add[x]>=mo) add[x]-=mo;
	t[x]=t[x]+s[len[x]-1]*v;
}

#define upd(x) t[x]=t[x*2]+(p[len[x*2]]*t[x*2+1])
#define sep(x) jia(x*2,add[x]),jia(x*2+1,add[x]),add[x]=0;

void Bud(int x,int L,int R){
	len[x]=R-L+1;
	if(L==R){
		int v=a[L];
		t[x]=(node){v,0,0,v};
		return;
	}
	int md=(L+R)>>1;
	Bud(x*2,L,md);
	Bud(x*2+1,md+1,R);
	upd(x);
}

void modify(int x,int L,int R,int pos,int v){
	if(L==R){
		t[x]=(node){v,0,0,v};
		return;
	}
	sep(x);
	int md=(L+R)>>1;
	if(pos<=md) modify(x*2,L,md,pos,v);
	else modify(x*2+1,md+1,R,pos,v);
	upd(x);
}

void modify(int x,int L,int R,int ll,int rr,int v){
	if(ll<=L && R<=rr){
		jia(x,v);
		return;
	}
	sep(x);
	int md=(L+R)>>1;
	if(ll<=md) modify(x*2,L,md,ll,rr,v);
	if(md<rr)  modify(x*2+1,md+1,R,ll,rr,v);
	upd(x);
}

void ask(int x,int L,int R,int ll,int rr){
	if(ll<=L && R<=rr){
		ans+=(p[tmp]*t[x]).a11;
		if(ans>=mo) ans-=mo;
		tmp+=R-L+1;
		return;
	}
	sep(x);
	int md=(L+R)>>1;
	if(ll<=md) ask(x*2,L,md,ll,rr);
	if(md<rr)  ask(x*2+1,md+1,R,ll,rr);
}

int main(){
	scanf("%d%d",&n,&m);
	p[0]=(node){1,0,0,1};
	p[1]=(node){1,1,1,0};
	For(i,2,n) p[i]=p[i-1]*p[1];
	s[0]=p[0];
	For(i,1,n) s[i]=s[i-1]+p[i];
	For(i,1,n) scanf("%d",a+i);
	Bud(1,1,n);
	For(i,1,m){
		int ty=IN(),l=IN(),r=IN(),d;
		if(ty==1){
			modify(1,1,n,l,r);
		}else
		if(ty==2){
			ans=tmp=0;
			ask(1,1,n,l,r);
			printf("%d\n",ans);
		}else{
			d=IN();
			modify(1,1,n,l,r,d);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;

int const N = 1e2+10, mod = 1e9;

int n, m;
ll a[N];

int main()
{

		cin >> n >> m;

		for(int i = 1; i <= n; i++)
			cin >> a[i];

		for(int i = 1; i <= m; i++)
		{
			int type;
			cin >> type;
			if(type == 1)
			{
				int x, v;
				cin >> x >> v;
				a[x] = v;
			}
			if(type == 2)
			{
				int l, r;
				cin >> l >> r;
			    if(l == r) cout << a[l] << '\n';
			    else if(r == l+1) cout << (a[l] + a[r]) % mod << '\n';
			    else
			    {
			    	ll soma = (a[l] + a[l+1]) % mod;
			    	ll F1 = 1, F2 = 2;
			    	for(int j = l+2; j <= r; j++)
			    	{
			    		soma = (soma + F2 * a[j]) % mod;
			    		ll F3 = (F1 + F2) % mod;
			    		F1 = F2, F2 = F3;
			    	}
			    	cout << soma << '\n';
			    }
			}
		}

}


#include<bits/stdc++.h>
using namespace std;
const int N=200020,M=200020,mod=1000000000;
struct node
{
	int l,r;
	long long s1,s2,lazy;
}t[N<<2]={};
int n,m,a[N]={},f[N]={0,1};
void update(int k)
{
	int L=k<<1,R=(k<<1)|1;
	int d=t[L].r-t[L].l+1;
	t[k].s1=(t[L].s1+t[R].s1*f[d-1]+t[R].s2*f[d])%mod;
	t[k].s2=(t[L].s2+t[R].s1*f[d]+t[R].s2*f[d+1])%mod;
}
void make_tree(int l,int r,int k)
{
	if(l!=r)
	{
		int mid=(l+r)>>1;
		make_tree(l,mid,k<<1);
		make_tree(mid+1,r,(k<<1)|1);
		update(k);
	}
	else
		t[k].s1=0,t[k].s2=a[l];
	t[k].l=l;
	t[k].r=r;
	t[k].lazy=0;
}
void add_lazy(int k,int c)
{
	(t[k].lazy+=c)%=mod;
	(t[k].s1+=c*(f[t[k].r-t[k].l+1]-1ll))%=mod;
	(t[k].s2+=c*(f[t[k].r-t[k].l+2]-1ll))%=mod;
}
void push(int k)
{
	add_lazy(k<<1,t[k].lazy);
	add_lazy((k<<1)|1,t[k].lazy);
	t[k].lazy=0;
}
void change(int pos,int c,int k)
{
	if(t[k].l==t[k].r)
	{
		t[k].s1=0,t[k].s2=c;
		return;
	}
	push(k);
	if(t[k<<1].r>=pos)
		change(pos,c,k<<1);
	else
		change(pos,c,(k<<1)|1);
	update(k);
}
long long get_sum(int l,int r,int k)
{
	if(t[k].l>=l && t[k].r<=r)
		return (t[k].s1*f[t[k].l-l]+t[k].s2*f[t[k].l-l+1])%mod;
	push(k);
	long long s=0;
	if(t[k<<1].r>=l)
		s+=get_sum(l,r,k<<1);
	if(t[(k<<1)|1].l<=r)
		s+=get_sum(l,r,(k<<1)|1);
	return s%mod;
}
void add(int l,int r,int v,int k)
{
	if(t[k].l>=l && t[k].r<=r)
		return add_lazy(k,v);
	push(k);
	if(t[k<<1].r>=l)
		add(l,r,v,k<<1);
	if(t[(k<<1)|1].l<=r)
		add(l,r,v,(k<<1)|1);
	update(k);
}
void init()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d",&a[i]);
	for(int i=2;i<=n+10;++i)
		f[i]=(f[i-1]+f[i-2])%mod;
	make_tree(1,n,1);
}
void work()
{
	int t,l,r,x,v;
	for(int i=1;i<=m;++i)
	{
		scanf("%d",&t);
		if(t==1)
		{
			scanf("%d%d",&x,&v);
			change(x,v,1);
		}
		if(t==2)
		{
			scanf("%d%d",&l,&r);
			printf("%d\n",(int)get_sum(l,r,1));
		}
		if(t==3)
		{
			scanf("%d%d%d",&l,&r,&v);
			add(l,r,v,1);
		}
	}
}
int main()
{
	init();
	work();
	return 0;
}


//Orz Sevenkplus
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<bitset>
#define un using namespace
un std;
#define pb push_back
#define pf pop_front

#define mp make_pair

#define c0 first
#define c1 second
#define sqr(x)((x)*(x))
#define clr(x)memset(x,0,sizeof(x))
#define clr1(x)memset(x,-1,sizeof(x))
#define clr80(x)memset(x,0x80,sizeof(x))
#define clr7F(x)memset(x,0x7F,sizeof(x))

#define ll long long
#ifdef __unix__
#define LLD "%lld"
#else
#define LLD "%I64d"
#endif
#define pii pair<int,int>
#define pip pair<int,pii>
#define vi vector<int>
#define vpi vector<pii>
#define pq priority_queue

template<typename T>inline bool chkmin(T&a,T b){return a>b?a=b,1:0;}
template<typename T>inline bool chkmax(T&a,T b){return a<b?a=b,1:0;}
#define modadd(a,b,c)(((a)+(b))%(c))
#define modmul(a,b,c)((int)(((ll)(a)*(b))%(c)))

#define P 1000000000
#define N 200010

#define getint(x){\
	char __next__char__;\
	while(!isdigit(__next__char__=getchar()));x=__next__char__-48;\
	while(isdigit(__next__char__=getchar()))x=x*10+__next__char__-48;\
}
#define getint2(x1,x2){getint(x1);getint(x2);}
#define getint3(x1,x2,x3){getint(x1);getint(x2);getint(x3);}
#define getint4(x1,x2,x3,x4){getint(x1);getint(x2);getint(x3);getint(x4);}
#define getint5(x1,x2,x3,x4,x5){getint(x1);getint(x2);getint(x3);getint(x4);getint(x5);}
#define getint6(x1,x2,x3,x4,x5,x6){getint(x1);getint(x2);getint(x3);getint(x4);getint(x5);getint(x6);}

int f[N]={1,1},sum[N]={1,2},t[524290],t2[524290],tl[524290],ta[524299];
int n,m,T=1;
inline void tran(int a){
	if(!ta[a])return;
	if(tl[a]==1){
		t[a]=(t[a]+ta[a])%P;
		ta[a]=0;
		return;
	}
	t[a]=((ll)ta[a]*sum[tl[a]-1]+t[a])%P;
	t2[a]=((ll)ta[a]*sum[tl[a]-2]+t2[a])%P;
	ta[a<<1]=(ta[a<<1]+ta[a])%P,ta[a<<1^1]=(ta[a<<1^1]+ta[a])%P;
	ta[a]=0;
}
int get(int a,int b,int l,int r){
	tran(a);
	if(l==1&&r==tl[a])return t2[a];
	if(l!=0||r!=tl[a]){
		if(r<=tl[a<<1])return get(a<<1,b,l,r);
		if(l>=tl[a<<1])return get(a<<1^1,b,l-tl[a<<1],r-tl[a<<1]);
		else return (get(a<<1,b,l,tl[a<<1])+get(a<<1^1,b+tl[a<<1]-l,0,r-tl[a<<1]))%P;
	}
	return ((ll)t[a]*f[b]+(ll)t2[a]*(b?f[b-1]:0))%P;
}
inline void updt(int i){
	tran(i);
	t[i]=(get(i<<1,0,0,tl[i<<1])+get(i<<1^1,tl[i<<1],0,tl[i<<1]))%P;
	t2[i]=(get(i<<1,0,1,tl[i<<1])+get(i<<1^1,tl[i<<1]-1,0,tl[i<<1]))%P;
}
void change(int i,int a,int b,int l,int r,int d){
	tran(i);
	if(a==l&&b==r)ta[i]=d;
	else if(b<=l+r>>1)change(i<<1,a,b,l,l+r>>1,d);
	else if(a>=l+r>>1)change(i<<1^1,a,b,l+r>>1,r,d);
	else change(i<<1,a,l+r>>1,l,l+r>>1,d),change(i<<1^1,l+r>>1,b,l+r>>1,r,d);
	updt(i);
}
int main(){
	for(int i=1;++i!=N;sum[i]=(sum[i-1]+f[i])%P)f[i]=(f[i-1]+f[i-2])%P;
	getint2(n,m);
	while(T<n)T<<=1;
	for(int i=-1;++i!=n;t2[i+T]=0)getint(t[i+T]);
	for(int i=T;i--;)tl[i+T]=1;
	for(int i=T;--i;){
		tl[i]=tl[i<<1]<<1;
		updt(i);
	}
	while(m--){
		int x;
		getint(x);
		if(x==2){
			int l,r;
			getint2(l,r);
			l--;
			printf("%d\n",get(1,0,l,r));
		}else if(x==1){
			int i,v;
			getint2(i,v);
			i+=T-1;
			vector<int>Z(1,i);
			while(i>>=1)Z.pb(i);
			for(i=Z.size();i--;)tran(Z[i]);
			t[Z[0]]=v;
			for(i=0;++i!=Z.size();)updt(Z[i]);
		}else{
			int l,r,d;
			getint3(l,r,d);
			change(1,l-1,r,0,tl[1],d);
		}
	}
	return 0;
}