#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
            while(s!=0){
                long long di=s%10;
                if(di==d)
                    amount+=power[num];
                num++;
                s/=10;
            }
            it[k][d]=amount;
            lazy[k][d]=d;
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=d;
}
void lazyupdate(long long k,long long l,long long r){
    long long rem[15];
    memset(rem,0,sizeof(rem));
    for(int i=0;i<=9;i++){
        rem[lazy[k][i]]+=it[k][i];
        it[k][i]=0;
    }
    if(l!=r){
        for(int i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k][lazy[k*2][i]];
            lazy[k*2+1][i]=lazy[k][lazy[k*2+1][i]];
        }
    }
    for(int i=0;i<=9;i++){
        it[k][i]=rem[i];
        lazy[k][i]=i;
    }
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        it[k][y]+=it[k][x];
        it[k][x]=0;
        if(l!=r){
            for(int i=0;i<=9;i++){
                if(lazy[k*2][i]==x) lazy[k*2][i]=y;
                if(lazy[k*2+1][i]==x) lazy[k*2+1][i]=y;
            }
        }
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(long long i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0LL;
    if(L<=l&&r<=R){
        long long num=0LL;
        for(long long i=1;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(long long i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(long long i=1;i<=18;i++)
        power[i]=power[i-1]*10LL;
    for(long long i=1;i<=n;i++)
        cin>>a[i];
    for(long long i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
        while(s!=0){
            long long di=s%10;
            if(di==d)
                amount+=power[num];
            num++;
            s/=10;
        }
        it[k][d]=amount;
        lazy[k][d]=d;
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=lazy[k*2][d]=lazy[k*2+1][d];
}
void lazyupdate(long long k,long long l,long long r){
    if(l!=r){
        long long rem[15];
        for(int i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k][lazy[k*2][i]];
            lazy[k*2+1][i]=lazy[k][lazy[k*2+1][i]];
            rem[lazy[k*2][i]]=it[k*2][i];
            it[k*2][i]=0;
            it[k*2][lazy[k*2][i]]+=rem[lazy[k*2][i]];
            rem[lazy[k*2+1][i]]=it[k*2+1][i];
            it[k*2+1][i]=0;
            it[k*2+1][lazy[k*2+1][i]]+=rem[lazy[k*2+1][i]];
        }
    }
    for(int i=0;i<=9;i++)
        lazy[k][i]=i;
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        it[k][y]+=it[k][x];
        if(lazy[k][x]==x)
        lazy[k][x]=y;
        it[k][x]=0;
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0;
    if(L<=l&&r<=R){
        long long num=0;
        for(int i=0;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(int i=1;i<=18;i++)
        power[i]=power[i-1]*10;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
        while(s!=0){
            long long di=s%10;
            if(di==d)
                amount+=power[num];
            num++;
            s/=10;
        }
        it[k][d]=amount;
        lazy[k][d]=d;
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=lazy[k*2][d]=lazy[k*2+1][d];
}
void lazyupdate(long long k,long long l,long long r){
    if(l!=r){
        long long rem[15];
        for(int i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k*2][lazy[k][i]];
            lazy[k*2+1][i]=lazy[k*2+1][lazy[k][i]];
            rem[i]=it[k*2][i];
            it[k*2][i]=0;
            it[k*2][lazy[k][i]]+=rem[i];
            rem[i]=it[k*2+1][i];
            it[k*2+1][i]=0;
            it[k*2+1][lazy[k][i]]+=rem[i];
        }
    }
    for(int i=0;i<=9;i++)
        lazy[k][i]=i;
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        it[k][y]+=it[k][x];
        if(lazy[k][x]==x)
        lazy[k][x]=y;
        it[k][x]=0;
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0;
    if(L<=l&&r<=R){
        long long num=0;
        for(int i=0;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(int i=1;i<=18;i++)
        power[i]=power[i-1]*10;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
        if(s==0&&d==0){
            it[k][d]=1;
            lazy[k][d]=0;
        }
        else{
            while(s!=0){
                long long di=s%10;
                if(di==d)
                    amount+=power[num];
                num++;
                s/=10;
            }
            it[k][d]=amount;
            lazy[k][d]=d;
        }
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=lazy[k*2][d];
}
void lazyupdate(long long k,long long l,long long r){
    if(l!=r){
        long long rem1[15],rem2[15];
        for(int i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k][lazy[k*2][i]];
            lazy[k*2+1][i]=lazy[k][lazy[k*2+1][i]];
        }
        memset(rem1,0,sizeof(rem1));
        for(int i=0;i<=9;i++){
            rem1[lazy[k*2][i]]+=it[k*2][i];
            it[k*2][i]=0;
        }
        for(int i=0;i<=9;i++)
            it[k*2][i]=rem1[i];
        memset(rem2,0,sizeof(rem2));
        for(int i=0;i<=9;i++){
            rem2[lazy[k*2+1][i]]+=it[k*2+1][i];
            it[k*2+1][i]=0;
        }
        for(int i=0;i<=9;i++)
            it[k*2+1][i]=rem2[i];
    }
    for(int i=0;i<=9;i++)
        lazy[k][i]=i;
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        it[k][y]+=it[k][x];
        for(int i=0;i<=9;i++){
            if(lazy[k][i]==x)
                lazy[k][i]=y;
        }
        it[k][x]=0;
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0;
    if(L<=l&&r<=R){
        long long num=0;
        for(int i=0;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(int i=1;i<=18;i++)
        power[i]=power[i-1]*10;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
        while(s!=0){
            long long di=s%10;
            if(di==d)
                amount+=power[num];
            num++;
            s/=10;
        }
        it[k][d]=amount;
        lazy[k][d]=d;
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=lazy[k*2][d]=lazy[k*2+1][d];
}
void lazyupdate(long long k,long long l,long long r){
    if(l!=r){
        long long rem[15];
        for(int i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k*2][lazy[k][i]];
            lazy[k*2+1][i]=lazy[k*2+1][lazy[k][i]];
            rem[i]=it[k*2][i];
            it[k*2][i]=0;
            it[k*2][lazy[k][i]]+=rem[i];
            rem[i]=it[k*2+1][i];
            it[k*2+1][i]=0;
            it[k*2+1][lazy[k][i]]+=rem[i];
        }
    }
    for(int i=0;i<=9;i++)
        lazy[k][i]=i;
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        it[k][y]+=it[k][x];
        if(lazy[k][x]!=x)
        lazy[k][x]=y;
        it[k][x]=0;
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0;
    if(L<=l&&r<=R){
        long long num=0;
        for(int i=0;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(int i=1;i<=18;i++)
        power[i]=power[i-1]*10;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
            while(s!=0){
                long long di=s%10;
                if(di==d)
                    amount+=power[num];
                num++;
                s/=10;
            }
            it[k][d]=amount;
            lazy[k][d]=d;
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=d;
}
void lazyupdate(long long k,long long l,long long r){
    if(l!=r){
        long long rem1[15],rem2[15];
        for(int i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k][lazy[k*2][i]];
            lazy[k*2+1][i]=lazy[k][lazy[k*2+1][i]];
        }
        for(int i=0;i<=9;i++)
            rem1[i]=0;
        for(int i=0;i<=9;i++){
            rem1[lazy[k*2][i]]+=it[k*2][i];
        }
        for(int i=0;i<=9;i++)
            it[k*2][i]=rem1[i];
        for(int i=0;i<=9;i++)
            rem2[i]=0;
        for(int i=0;i<=9;i++){
            rem2[lazy[k*2+1][i]]+=it[k*2+1][i];
        }
        for(int i=0;i<=9;i++)
            it[k*2+1][i]=rem2[i];
    }
    for(int i=0;i<=9;i++)
        lazy[k][i]=i;
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        for(int i=0;i<=9;i++){
            if(lazy[k][i]==x)
                lazy[k][i]=y;
        }
        it[k][y]+=it[k][x];
        it[k][x]=0;
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0LL;
    if(L<=l&&r<=R){
        long long num=0LL;
        for(long long i=1;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(int i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(int i=1;i<=18;i++)
        power[i]=power[i-1]*10;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int,int> ii;

long long n,q,a[500005],it[500005][15],lazy[500005][15];
long long power[20];
void build_tree(long long k,long long l,long long r,long long d){
    if(l==r){
        long long amount=0,num=0,s=a[l];
            while(s!=0){
                long long di=s%10;
                if(di==d)
                    amount+=power[num];
                num++;
                s/=10;
            }
            it[k][d]=amount;
            lazy[k][d]=d;
        return ;
    }
    long long mid=(l+r)/2;
    build_tree(k*2,l,mid,d);
    build_tree(k*2+1,mid+1,r,d);
    it[k][d]=it[k*2][d]+it[k*2+1][d];
    lazy[k][d]=d;
}
void lazyupdate(long long k,long long l,long long r){
    if(l!=r){
        long long rem1[15],rem2[15];
        for(long long i=0;i<=9;i++){
            lazy[k*2][i]=lazy[k][lazy[k*2][i]];
            lazy[k*2+1][i]=lazy[k][lazy[k*2+1][i]];
        }
        for(long long i=0;i<=9;i++)
            rem1[i]=0;
        for(long long i=0;i<=9;i++){
            rem1[lazy[k*2][i]]+=it[k*2][i];
        }
        for(long long i=0;i<=9;i++)
            it[k*2][i]=rem1[i];
        for(long long i=0;i<=9;i++)
            rem2[i]=0;
        for(long long i=0;i<=9;i++){
            rem2[lazy[k*2+1][i]]+=it[k*2+1][i];
        }
        for(long long i=0;i<=9;i++)
            it[k*2+1][i]=rem2[i];
    }
    for(long long i=0;i<=9;i++)
        lazy[k][i]=i;
}

void update(long long k,long long l,long long r,long long L,long long R,long long x,long long y){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return ;
    if(L<=l&&r<=R){
        lazy[k][x]=y;
        it[k][y]+=it[k][x];
        it[k][x]=0;
        return ;
    }
    long long mid=(l+r)/2;
    update(k*2,l,mid,L,R,x,y);
    update(k*2+1,mid+1,r,L,R,x,y);
    for(long long i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}

long long get(long long k,long long l,long long r,long long L,long long R){
    lazyupdate(k,l,r);
    if(R<l||r<L||L>R) return 0LL;
    if(L<=l&&r<=R){
        long long num=0LL;
        for(long long i=1;i<=9;i++)
            num+=it[k][i]*i;
        return num;
    }
    long long mid=(l+r)/2;
    return get(k*2,l,mid,L,R)+get(k*2+1,mid+1,r,L,R);
    for(long long i=0;i<=9;i++)
        it[k][i]=it[k*2][i]+it[k*2+1][i];
}
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>q;
    power[0]=1;
    for(long long i=1;i<=18;i++)
        power[i]=power[i-1]*10LL;
    for(long long i=1;i<=n;i++)
        cin>>a[i];
    for(long long i=0;i<=9;i++)
        build_tree(1,1,n,i);
    long long l,r,type,x,y;
    while(q--){
        cin>>type>>l>>r;
        if(type==1){
            cin>>x>>y;
            //cout<<get(1,1,n,l,r)<<"\n";
            if(x!=y)
            update(1,1,n,l,r,x,y);
            //cout<<get(1,1,n,l,r)<<"\n";
        }
        else
            cout<<get(1,1,n,l,r)<<"\n";
    }
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;

#define fi first
#define se second
typedef long long LL;
typedef long double LD;

struct change{
    int from,to;
    change(int from=0, int to=0) : from(from), to(to) {}
};

struct Tree{
    LL s[10],sum;
    queue<change> q;
};

int N,Q,a[100010]; Tree t[400010];
bool v[400010][10];

void add(change ch, int nod){
    if (v[nod][ch.from]) return;
    v[nod][ch.from]=1;
    t[nod].q.push(ch);
}

void unlazy(int nod, int l, int r){
    while (!t[nod].q.empty()){
        change ch=t[nod].q.front();
        t[nod].q.pop();
        t[nod].sum-=ch.from*t[nod].s[ch.from];
        t[nod].sum+=ch.to*t[nod].s[ch.from];
        t[nod].s[ch.to]+=t[nod].s[ch.from];
        t[nod].s[ch.from]=0;

        if (l!=r){
            add(ch,nod*2);
            add(ch,nod*2+1);
        }
    }

    memset(v[nod],0,sizeof(v[nod]));
}

void build(int nod, int l, int r){
    if (l==r){
        t[nod].sum=a[l];

        LL p10=1;
        while (a[l]){
            t[nod].s[a[l]%10]+=p10;
            a[l]/=10;
            p10*=10;
        }
        return;
    }

    int mid=(l+r)/2;
    build(nod*2,l,mid);
    build(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

void update(int nod, int l, int r, int ql, int qr, int fr, int to){
    if (ql<=l && r<=qr){
        t[nod].q.push(change(fr,to));
        return;
    }

    unlazy(nod,l,r);
    int mid=(l+r)/2;
    if (ql<=mid) update(nod*2,l,mid,ql,qr,fr,to);
    if (mid<qr)  update(nod*2+1,mid+1,r,ql,qr,fr,to);
    unlazy(nod*2,l,mid); unlazy(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

LL query(int nod, int l, int r, int ql, int qr){
    unlazy(nod,l,r);
    if (ql<=l && r<=qr)
        return t[nod].sum;

    int mid=(l+r)/2; LL res=0;
    if (ql<=mid) res+=query(nod*2,l,mid,ql,qr);
    if (mid<qr)  res+=query(nod*2+1,mid+1,r,ql,qr);
    return res;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N >> Q;

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

    build(1,1,N);

    int tp,ql,qr,fr,to;
    while (Q--){
        cin >> tp >> ql >> qr;
        if (tp==1){
            cin >> fr >> to;
            update(1,1,N,ql,qr,fr,to);
        }
        else {
            cout << query(1,1,N,ql,qr) << "\n";
        }
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;

#define fi first
#define se second
typedef long long LL;
typedef long double LD;

struct change{
    int from,to;
    change(int from=0, int to=0) : from(from), to(to) {}
};

struct Tree{
    LL s[10],sum;
    int to[10];
    bool lz;
};

int N,Q,a[100010]; Tree t[400010];

void build(int nod, int l, int r){
    for (int i=0; i<10; i++)
            t[nod].to[i]=i;

    if (l==r){
        t[nod].sum=a[l];

        LL p10=1;
        while (a[l])
            t[nod].s[a[l]%10]+=p10,a[l]/=10,p10*=10;
        return;
    }

    int mid=(l+r)/2;
    build(nod*2,l,mid);
    build(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

void unlazy(int nod, int l, int r){
    if (!t[nod].lz) return;

    LL val[10],i;
    memset(val,0,sizeof(val));
    for (i=0; i<10; i++)
        val[t[nod].to[i]]+=t[nod].s[i];
    t[nod].sum=0;
    for (i=0; i<10; i++){
        t[nod].s[i]=val[i];
        t[nod].sum+=i*val[i];
    }

    if (l!=r){
        for (i=0; i<10; i++){
            t[nod*2].to[i]=t[nod].to[t[nod*2].to[i]];
            t[nod*2+1].to[i]=t[nod].to[t[nod*2+1].to[i]];
        }
        t[nod*2].lz=t[nod*2+1].lz=1;
    }

    for (i=0; i<10; i++) t[nod].to[i]=i;
    t[nod].lz=0;
}

void update(int nod, int l, int r, int ql, int qr, int fr, int to){
    if (ql<=l && r<=qr){
        for (int i=0; i<10; i++)
           if (t[nod].to[i]==fr) t[nod].to[i]=to;

        t[nod].lz=1;
        return;
    }
    unlazy(nod,l,r);

    int mid=(l+r)/2;
    if (ql<=mid) update(nod*2,l,mid,ql,qr,fr,to);
    if (mid<qr)  update(nod*2+1,mid+1,r,ql,qr,fr,to);
    unlazy(nod*2,l,mid); unlazy(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

LL query(int nod, int l, int r, int ql, int qr){
    unlazy(nod,l,r);
    if (ql<=l && r<=qr)
        return t[nod].sum;

    int mid=(l+r)/2; LL res=0;
    if (ql<=mid) res+=query(nod*2,l,mid,ql,qr);
    if (mid<qr)  res+=query(nod*2+1,mid+1,r,ql,qr);
    return res;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N >> Q;

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

    build(1,1,N);

    int tp,ql,qr,fr,to;
    while (Q--){
        cin >> tp >> ql >> qr;
        if (tp==1){
            cin >> fr >> to;
            update(1,1,N,ql,qr,fr,to);
        }
        else {
            cout << query(1,1,N,ql,qr) << "\n";
        }
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;

#define fi first
#define se second
typedef long long LL;
typedef long double LD;

struct change{
    int from,to;
    change(int from=0, int to=0) : from(from), to(to) {}
};

struct Tree{
    LL s[10],sum;
    int to[10];
    bool lz;
};

int N,Q,a[100010]; Tree t[400010];

void build(int nod, int l, int r){
    for (int i=0; i<10; i++)
            t[nod].to[i]=i;

    if (l==r){
        t[nod].sum=a[l];

        LL p10=1;
        while (a[l])
            t[nod].s[a[l]%10]+=p10,a[l]/=10,p10*=10;
        return;
    }

    int mid=(l+r)/2;
    build(nod*2,l,mid);
    build(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

void unlazy(int nod, int l, int r){
    if (!t[nod].lz) return;

    int val[10],i;
    memset(val,0,sizeof(val));
    for (i=0; i<10; i++)
        val[t[nod].to[i]]+=t[nod].s[i];
    t[nod].sum=0;
    for (i=0; i<10; i++){
        t[nod].s[i]=val[i];
        t[nod].sum+=i*val[i];
    }

    if (l!=r){
        for (i=0; i<10; i++){
            t[nod*2].to[i]=t[nod].to[t[nod*2].to[i]];
            t[nod*2+1].to[i]=t[nod].to[t[nod*2+1].to[i]];
        }
        t[nod*2].lz=t[nod*2+1].lz=1;
    }

    for (i=0; i<10; i++) t[nod].to[i]=i;
    t[nod].lz=0;
}

void update(int nod, int l, int r, int ql, int qr, int fr, int to){
    unlazy(nod,l,r);

    if (ql<=l && r<=qr){
        for (int i=0; i<10; i++)
           if (t[nod].to[i]==fr) t[nod].to[i]=to;

        t[nod].lz=1;
        return;
    }

    int mid=(l+r)/2;
    if (ql<=mid) update(nod*2,l,mid,ql,qr,fr,to);
    if (mid<qr)  update(nod*2+1,mid+1,r,ql,qr,fr,to);
    unlazy(nod*2,l,mid); unlazy(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

LL query(int nod, int l, int r, int ql, int qr){
    unlazy(nod,l,r);
    if (ql<=l && r<=qr)
        return t[nod].sum;

    int mid=(l+r)/2; LL res=0;
    if (ql<=mid) res+=query(nod*2,l,mid,ql,qr);
    if (mid<qr)  res+=query(nod*2+1,mid+1,r,ql,qr);
    return res;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N >> Q;

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

    build(1,1,N);

    int tp,ql,qr,fr,to;
    while (Q--){
        cin >> tp >> ql >> qr;
        if (tp==1){
            cin >> fr >> to;
            update(1,1,N,ql,qr,fr,to);
        }
        else {
            cout << query(1,1,N,ql,qr) << "\n";
        }
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;

#define fi first
#define se second
typedef long long LL;
typedef long double LD;

struct change{
    int from,to;
    change(int from=0, int to=0) : from(from), to(to) {}
};

struct Tree{
    LL s[10],sum;
    queue<change> q;
};

int N,Q,a[100010]; Tree t[200010];
bool v[200010][10];

void add(change ch, int nod){
    if (v[nod][ch.from]) return;
    v[nod][ch.from]=1;
    t[nod].q.push(ch);
}

void unlazy(int nod, int l, int r){
    while (!t[nod].q.empty()){
        change ch=t[nod].q.front();
        t[nod].q.pop();
        t[nod].sum-=ch.from*t[nod].s[ch.from];
        t[nod].sum+=ch.to*t[nod].s[ch.from];
        t[nod].s[ch.to]+=t[nod].s[ch.from];
        t[nod].s[ch.from]=0;

        if (l!=r){
            add(ch,nod*2);
            add(ch,nod*2+1);
        }
    }

    memset(v[nod],0,sizeof(v[nod]));
}

void build(int nod, int l, int r){
    if (l==r){
        t[nod].sum=a[l];

        LL p10=1;
        while (a[l]){
            t[nod].s[a[l]%10]+=p10;
            a[l]/=10;
            p10*=10;
        }
        return;
    }

    int mid=(l+r)/2;
    build(nod*2,l,mid);
    build(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

void update(int nod, int l, int r, int ql, int qr, int fr, int to){
    if (ql<=l && r<=qr){
        t[nod].q.push(change(fr,to));
        return;
    }

    unlazy(nod,l,r);
    int mid=(l+r)/2;
    if (ql<=mid) update(nod*2,l,mid,ql,qr,fr,to);
    if (mid<qr)  update(nod*2+1,mid+1,r,ql,qr,fr,to);
    unlazy(nod*2,l,mid); unlazy(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

LL query(int nod, int l, int r, int ql, int qr){
    unlazy(nod,l,r);
    if (ql<=l && r<=qr)
        return t[nod].sum;

    int mid=(l+r)/2; LL res=0;
    if (ql<=mid) res+=query(nod*2,l,mid,ql,qr);
    if (mid<qr)  res+=query(nod*2+1,mid+1,r,ql,qr);
    return res;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N >> Q;

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

    build(1,1,N);

    int tp,ql,qr,fr,to;
    while (Q--){
        cin >> tp >> ql >> qr;
        if (tp==1){
            cin >> fr >> to;
            update(1,1,N,ql,qr,fr,to);
        }
        else {
            cout << query(1,1,N,ql,qr) << "\n";
        }
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;

#define fi first
#define se second
typedef long long LL;
typedef long double LD;

struct change{
    int from,to;
    change(int from=0, int to=0) : from(from), to(to) {}
};

struct Tree{
    LL s[10],sum;
    queue<change> q;
};

int N,Q,a[100010]; Tree t[400010];

void unlazy(int nod, int l, int r){
    while (!t[nod].q.empty()){
        change ch=t[nod].q.front();
        t[nod].q.pop();
        t[nod].sum-=ch.from*t[nod].s[ch.from];
        t[nod].sum+=ch.to*t[nod].s[ch.from];
        t[nod].s[ch.to]+=t[nod].s[ch.from];
        t[nod].s[ch.from]=0;

        if (l!=r){
            t[nod*2].q.push(ch);
            t[nod*2+1].q.push(ch);
        }
    }
}

void build(int nod, int l, int r){
    if (l==r){
        t[nod].sum=a[l];

        LL p10=1;
        while (a[l]){
            t[nod].s[a[l]%10]+=p10;
            a[l]/=10;
            p10*=10;
        }
        return;
    }

    int mid=(l+r)/2;
    build(nod*2,l,mid);
    build(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

void update(int nod, int l, int r, int ql, int qr, int fr, int to){
    if (ql<=l && r<=qr){
        t[nod].q.push(change(fr,to));
        return;
    }

    unlazy(nod,l,r);
    int mid=(l+r)/2;
    if (ql<=mid) update(nod*2,l,mid,ql,qr,fr,to);
    if (mid<qr)  update(nod*2+1,mid+1,r,ql,qr,fr,to);
    unlazy(nod*2,l,mid); unlazy(nod*2+1,mid+1,r);
    for (int i=0; i<10; i++)
        t[nod].s[i]=t[nod*2].s[i]+t[nod*2+1].s[i];
    t[nod].sum=t[nod*2].sum+t[nod*2+1].sum;
}

LL query(int nod, int l, int r, int ql, int qr){
    unlazy(nod,l,r);
    if (ql<=l && r<=qr)
        return t[nod].sum;

    int mid=(l+r)/2; LL res=0;
    if (ql<=mid) res+=query(nod*2,l,mid,ql,qr);
    if (mid<qr)  res+=query(nod*2+1,mid+1,r,ql,qr);
    return res;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N >> Q;

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

    build(1,1,N);

    int tp,ql,qr,fr,to;
    while (Q--){
        cin >> tp >> ql >> qr;
        if (tp==1){
            cin >> fr >> to;
            update(1,1,N,ql,qr,fr,to);
        }
        else {
            cout << query(1,1,N,ql,qr) << "\n";
        }
    }

    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

// {{{
// clang-format off
#define all(a) (a).begin(), (a).end()
#define sz(a) static_cast<int>((a).size())
#define fillchar(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for (int i = int(a); i <= int(b); ++i)
#define irep(i, a, b) for (int i = int(a); i >= int(b); --i)
#define replr(i, a, b) rep(i, a, (b)-1)
#define reprl(i, a, b) irep(i, (b)-1, a)
#define repn(i, n) rep(i, 0, (n)-1)
#define irepn(i, n) irep(i, (n)-1, 0)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define popcount __builtin_popcount
typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<double> VD;
typedef vector<bool> VB;
typedef vector<string> VS;
typedef vector<PII> VPI;
typedef vector<PLL> VPL;
typedef vector<PDD> VPD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VPI> VVPI;
typedef vector<VPL> VVPL;
template <class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& v) { return os << "(" << v.first << ", " << v.second << ")"; }
template <class T> ostream& operator<<(ostream& os, const vector<T>& v) { os << "["; repn(i, sz(v)) { if(i) os << ", "; os << v[i]; } return os << "]"; }
template <class T> bool setmax(T& _a, T _b) { if(_a < _b) { _a = _b; return true; } return false; }
template <class T> bool setmin(T& _a, T _b) { if(_b < _a) { _a = _b; return true; } return false; }
template <class T> T gcd(T _a, T _b) { return _b == 0 ? _a : gcd(_b, _a % _b); }
VI read_vi(int n = -1) { if (n < 0) scanf("%d", &n); VI a(n); repn(i, n) scanf("%d", &a[i]); return a; }
VL read_vl(int n = -1) { if (n < 0) scanf("%d", &n); VL a(n); repn(i, n) scanf("%lld", &a[i]); return a; }
VD read_vd(int n = -1) { if (n < 0) scanf("%d", &n); VD a(n); repn(i, n) scanf("%lf", &a[i]); return a; }
VPI read_vpi(int n = -1) { if (n < 0) scanf("%d", &n); VPI a(n); repn(i, n) scanf("%d%d", &a[i].fi,&a[i].se); return a; }
VPL read_vpl(int n = -1) { if (n < 0) scanf("%d", &n); VPL a(n); repn(i, n) scanf("%lld%lld", &a[i].fi,&a[i].se); return a; }
VPD read_vpd(int n = -1) { if (n < 0) scanf("%d", &n); VPD a(n); repn(i, n) scanf("%lf%lf", &a[i].fi,&a[i].se); return a; }
inline LL powmod(LL a, LL b, LL m) { LL r = 1; for(; b > 0; b >>= 1, a = a * a % m) { if(b & 1) r = r * a % m; } return r; }
// clang-format on
// }}}

struct Node {
    int buf[10];
    LL cnt[10];
};
Node tr[400040];

void update(int x) {
    repn(i, 10) tr[x].cnt[i] = tr[x * 2 + 1].cnt[i] + tr[x * 2 + 2].cnt[i];
}

void release(int x) {
    for(int y : {x * 2 + 1, x * 2 + 2}) {
        int tb[10];
        LL tc[10];
        fillchar(tc, 0);
        repn(i, 10) {
            tb[i] = tr[x].buf[tr[y].buf[i]];
            tc[tr[x].buf[i]] += tr[y].cnt[i];
        }
        memmove(tr[y].buf, tb, sizeof(tb));
        memmove(tr[y].cnt, tc, sizeof(tc));
    }
    repn(i, 10) tr[x].buf[i] = i;
}

void init(int x, int l, int r, const VL& a) {
    repn(i, 10) tr[x].buf[i] = i;
    if(l + 1 == r) {
        fillchar(tr[x].cnt, 0);
        for(LL b = 1; b <= a[l]; b *= 10) {
            tr[x].cnt[a[l] / b % 10] += b;
        }
        return;
    }
    const int m = (l + r) / 2;
    init(x * 2 + 1, l, m, a);
    init(x * 2 + 2, m, r, a);
    update(x);
}

void change(int x, int l, int r, int st, int en, int p, int q) {
    if(st <= l && r <= en) {
        repn(i, 10) if(tr[x].buf[i] == p) tr[x].buf[i] = q;
        tr[x].cnt[q] += tr[x].cnt[p], tr[x].cnt[p] = 0;
        return;
    }
    release(x);
    const int m = (l + r) / 2;
    if(st < m) change(x * 2 + 1, l, m, st, en, p, q);
    if(m < en) change(x * 2 + 2, m, r, st, en, p, q);
    update(x);
}

void query(int x, int l, int r, int st, int en, LL ans[]) {
    if(st <= l && r <= en) {
        repn(i, 10) ans[i] += tr[x].cnt[i];
        return;
    }
    release(x);
    const int m = (l + r) / 2;
    if(st < m) query(x * 2 + 1, l, m, st, en, ans);
    if(m < en) query(x * 2 + 2, m, r, st, en, ans);
}
int main() {
    int n, q;
    scanf("%d%d", &n, &q);
    VL a = read_vl(n);
    init(0, 0, n, a);
    while(q--) {
        int t;
        scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y;
            scanf("%d%d%d%d", &l, &r, &x, &y), --l;
            if(x != y) change(0, 0, n, l, r, x, y);
        } else {
            int l, r;
            scanf("%d%d", &l, &r), --l;
            LL cnt[10];
            fillchar(cnt, 0);
            query(0, 0, n, l, r, cnt);
            LL ans = 0;
            repn(i, 10) ans += i * cnt[i];
            printf("%lld\n", ans);
        }
    }
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

// {{{
// clang-format off
#define all(a) (a).begin(), (a).end()
#define sz(a) static_cast<int>((a).size())
#define fillchar(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for (int i = int(a); i <= int(b); ++i)
#define irep(i, a, b) for (int i = int(a); i >= int(b); --i)
#define replr(i, a, b) rep(i, a, (b)-1)
#define reprl(i, a, b) irep(i, (b)-1, a)
#define repn(i, n) rep(i, 0, (n)-1)
#define irepn(i, n) irep(i, (n)-1, 0)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define popcount __builtin_popcount
typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<double> VD;
typedef vector<bool> VB;
typedef vector<string> VS;
typedef vector<PII> VPI;
typedef vector<PLL> VPL;
typedef vector<PDD> VPD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VPI> VVPI;
typedef vector<VPL> VVPL;
template <class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& v) { return os << "(" << v.first << ", " << v.second << ")"; }
template <class T> ostream& operator<<(ostream& os, const vector<T>& v) { os << "["; repn(i, sz(v)) { if(i) os << ", "; os << v[i]; } return os << "]"; }
template <class T> bool setmax(T& _a, T _b) { if(_a < _b) { _a = _b; return true; } return false; }
template <class T> bool setmin(T& _a, T _b) { if(_b < _a) { _a = _b; return true; } return false; }
template <class T> T gcd(T _a, T _b) { return _b == 0 ? _a : gcd(_b, _a % _b); }
VI read_vi(int n = -1) { if (n < 0) scanf("%d", &n); VI a(n); repn(i, n) scanf("%d", &a[i]); return a; }
VL read_vl(int n = -1) { if (n < 0) scanf("%d", &n); VL a(n); repn(i, n) scanf("%lld", &a[i]); return a; }
VD read_vd(int n = -1) { if (n < 0) scanf("%d", &n); VD a(n); repn(i, n) scanf("%lf", &a[i]); return a; }
VPI read_vpi(int n = -1) { if (n < 0) scanf("%d", &n); VPI a(n); repn(i, n) scanf("%d%d", &a[i].fi,&a[i].se); return a; }
VPL read_vpl(int n = -1) { if (n < 0) scanf("%d", &n); VPL a(n); repn(i, n) scanf("%lld%lld", &a[i].fi,&a[i].se); return a; }
VPD read_vpd(int n = -1) { if (n < 0) scanf("%d", &n); VPD a(n); repn(i, n) scanf("%lf%lf", &a[i].fi,&a[i].se); return a; }
inline LL powmod(LL a, LL b, LL m) { LL r = 1; for(; b > 0; b >>= 1, a = a * a % m) { if(b & 1) r = r * a % m; } return r; }
// clang-format on
// }}}

struct Node {
    int buf[10];
    LL cnt[10];
};
Node tr[400040];

void update(int x) {
    repn(i, 10) tr[x].cnt[i] = tr[x * 2 + 1].cnt[i] + tr[x * 2 + 2].cnt[i];
}

void release(int x) {
    for(int y : {x * 2 + 1, x * 2 + 2}) {
        int tb[10];
        LL tc[10];
        fillchar(tc, 0);
        repn(i, 10) {
            tb[i] = tr[x].buf[tr[y].buf[i]];
            tc[tr[x].buf[i]] += tr[y].cnt[i];
        }
        memmove(tr[y].buf, tb, sizeof(tb));
        memmove(tr[y].cnt, tc, sizeof(tc));
    }
    repn(i, 10) tr[x].buf[i] = i;
}

void init(int x, int l, int r, const VI& a) {
    repn(i, 10) tr[x].buf[i] = i;
    if(l + 1 == r) {
        fillchar(tr[x].cnt, 0);
        for(LL b = 1; b <= a[l]; b *= 10) {
            tr[x].cnt[a[l] / b % 10] += b;
        }
        return;
    }
    const int m = (l + r) / 2;
    init(x * 2 + 1, l, m, a);
    init(x * 2 + 2, m, r, a);
    update(x);
}

void change(int x, int l, int r, int st, int en, int p, int q) {
    if(st <= l && r <= en) {
        repn(i, 10) if(tr[x].buf[i] == p) tr[x].buf[i] = q;
        tr[x].cnt[q] += tr[x].cnt[p], tr[x].cnt[p] = 0;
        return;
    }
    release(x);
    const int m = (l + r) / 2;
    if(st < m) change(x * 2 + 1, l, m, st, en, p, q);
    if(m < en) change(x * 2 + 2, m, r, st, en, p, q);
    update(x);
}

void query(int x, int l, int r, int st, int en, LL ans[]) {
    if(st <= l && r <= en) {
        repn(i, 10) ans[i] += tr[x].cnt[i];
        return;
    }
    release(x);
    const int m = (l + r) / 2;
    if(st < m) query(x * 2 + 1, l, m, st, en, ans);
    if(m < en) query(x * 2 + 2, m, r, st, en, ans);
}

int main() {
    int n, q;
    scanf("%d%d", &n, &q);
    VI a = read_vi(n);
    init(0, 0, n, a);
    while(q--) {
        int t;
        scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y;
            scanf("%d%d%d%d", &l, &r, &x, &y), --l;
            change(0, 0, n, l, r, x, y);
        } else {
            int l, r;
            scanf("%d%d", &l, &r), --l;
            LL cnt[10];
            fillchar(cnt, 0);
            query(0, 0, n, l, r, cnt);
            LL ans = 0;
            repn(i, 10) ans += i * cnt[i];
            printf("%lld\n", ans);
        }
    }
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

// {{{
// clang-format off
#define all(a) (a).begin(), (a).end()
#define sz(a) static_cast<int>((a).size())
#define fillchar(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for (int i = int(a); i <= int(b); ++i)
#define irep(i, a, b) for (int i = int(a); i >= int(b); --i)
#define replr(i, a, b) rep(i, a, (b)-1)
#define reprl(i, a, b) irep(i, (b)-1, a)
#define repn(i, n) rep(i, 0, (n)-1)
#define irepn(i, n) irep(i, (n)-1, 0)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define popcount __builtin_popcount
typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<double> VD;
typedef vector<bool> VB;
typedef vector<string> VS;
typedef vector<PII> VPI;
typedef vector<PLL> VPL;
typedef vector<PDD> VPD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VPI> VVPI;
typedef vector<VPL> VVPL;
template <class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& v) { return os << "(" << v.first << ", " << v.second << ")"; }
template <class T> ostream& operator<<(ostream& os, const vector<T>& v) { os << "["; repn(i, sz(v)) { if(i) os << ", "; os << v[i]; } return os << "]"; }
template <class T> bool setmax(T& _a, T _b) { if(_a < _b) { _a = _b; return true; } return false; }
template <class T> bool setmin(T& _a, T _b) { if(_b < _a) { _a = _b; return true; } return false; }
template <class T> T gcd(T _a, T _b) { return _b == 0 ? _a : gcd(_b, _a % _b); }
VI read_vi(int n = -1) { if (n < 0) scanf("%d", &n); VI a(n); repn(i, n) scanf("%d", &a[i]); return a; }
VL read_vl(int n = -1) { if (n < 0) scanf("%d", &n); VL a(n); repn(i, n) scanf("%lld", &a[i]); return a; }
VD read_vd(int n = -1) { if (n < 0) scanf("%d", &n); VD a(n); repn(i, n) scanf("%lf", &a[i]); return a; }
VPI read_vpi(int n = -1) { if (n < 0) scanf("%d", &n); VPI a(n); repn(i, n) scanf("%d%d", &a[i].fi,&a[i].se); return a; }
VPL read_vpl(int n = -1) { if (n < 0) scanf("%d", &n); VPL a(n); repn(i, n) scanf("%lld%lld", &a[i].fi,&a[i].se); return a; }
VPD read_vpd(int n = -1) { if (n < 0) scanf("%d", &n); VPD a(n); repn(i, n) scanf("%lf%lf", &a[i].fi,&a[i].se); return a; }
inline LL powmod(LL a, LL b, LL m) { LL r = 1; for(; b > 0; b >>= 1, a = a * a % m) { if(b & 1) r = r * a % m; } return r; }
// clang-format on
// }}}

struct Node {
    int buf[10];
    LL cnt[10];
};
Node tr[400040];

void update(int x) {
    repn(i, 10) tr[x].cnt[i] = tr[x * 2 + 1].cnt[i] + tr[x * 2 + 2].cnt[i];
}

void release(int x) {
    for(int y : {x * 2 + 1, x * 2 + 2}) {
        int tb[10];
        LL tc[10] = {0};
        repn(i, 10) {
            tb[i] = tr[x].buf[tr[y].buf[i]];
            tc[tr[x].buf[i]] += tr[y].cnt[i];
        }
        memmove(tr[y].buf, tb, sizeof(tb));
        memmove(tr[y].cnt, tc, sizeof(tc));
    }
    repn(i, 10) tr[x].buf[i] = i;
}

void init(int x, int l, int r, const VI& a) {
    repn(i, 10) tr[x].buf[i] = i;
    if(l + 1 == r) {
        fillchar(tr[x].cnt, 0);
        for(LL b = 1; b <= a[l]; b *= 10) {
            tr[x].cnt[a[l] / b % 10] += b;
        }
        return;
    }
    const int m = (l + r) / 2;
    init(x * 2 + 1, l, m, a);
    init(x * 2 + 2, m, r, a);
    update(x);
}

void change(int x, int l, int r, int st, int en, int p, int q) {
    if(st <= l && r <= en) {
        repn(i, 10) if(tr[x].buf[i] == p) tr[x].buf[i] = q;
        tr[x].cnt[q] += tr[x].cnt[p], tr[x].cnt[p] = 0;
        return;
    }
    release(x);
    const int m = (l + r) / 2;
    if(st < m) change(x * 2 + 1, l, m, st, en, p, q);
    if(m < en) change(x * 2 + 2, m, r, st, en, p, q);
    update(x);
}

void query(int x, int l, int r, int st, int en, LL ans[]) {
    if(st <= l && r <= en) {
        repn(i, 10) ans[i] += tr[x].cnt[i];
        return;
    }
    release(x);
    const int m = (l + r) / 2;
    if(st < m) query(x * 2 + 1, l, m, st, en, ans);
    if(m < en) query(x * 2 + 2, m, r, st, en, ans);
}

int main() {
    int n, q;
    scanf("%d%d", &n, &q);
    VI a = read_vi(n);
    init(0, 0, n, a);
    while(q--) {
        int t;
        scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y;
            scanf("%d%d%d%d", &l, &r, &x, &y), --l;
            change(0, 0, n, l, r, x, y);
        } else {
            int l, r;
            scanf("%d%d", &l, &r), --l;
            LL cnt[10] = {0};
            query(0, 0, n, l, r, cnt);
            LL ans = 0;
            repn(i, 10) ans += i * cnt[i];
            printf("%lld\n", ans);
        }
    }
    return 0;
}


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

typedef long long ll;

const int MN = 100010;

int N, Q;
int A[MN];

struct node {
    ll P[10];
    node() {
        memset(P, 0, sizeof(P));
    }
};

node mrg(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) ret.P[i] = a.P[i] + b.P[i];
    return ret;
}

node mul(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        ret.P[i] = a.P[ b.P[i] ];
    }
    return ret;
}

node f(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            if(a.P[j] == i) ret.P[i] += b.P[j];
        }
    }
    return ret;
}

struct BIT {
    vector<node> tree, lazy;
    void init() {
        tree = vector<node>(4 * N);
        lazy = vector<node>(4 * N);
        build(0, N - 1, 1);
    }
    void build(int l, int r, int n) {
        for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        if(l == r) {
            int p = 1;
            while(A[l]) {
                tree[n].P[ A[l] % 10 ] += p;
                A[l] /= 10;
                p *= 10;
            }
            return;
        }
        int m = (l + r)>>1;
        build(l, m, 2*n);
        build(m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    void prop(int l, int r, int n) {
        if(l != r) {
            tree[2*n] = f(lazy[n], tree[2*n]);
            lazy[2*n] = mul(lazy[2*n], lazy[n]);
            tree[2*n + 1] = f(lazy[n], tree[2*n + 1]);
            lazy[2*n + 1] = mul(lazy[2*n + 1], lazy[n]);
            for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        }
    }
    void upd(int a, int b, int x, int y, int l, int r, int n) {
        if(b < l || r < a) return;
        if(a <= l && r <= b) {
            node tmp;
            for(int i = 0; i < 10; i++) tmp.P[i] = i;
            tmp.P[x] = y;
            tree[n] = f(tmp, tree[n]);
            lazy[n] = mul(lazy[n], tmp);
            return;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        upd(a, b, x, y, l, m, 2*n);
        upd(a, b, x, y, m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    ll quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 0;
        if(a <= l && r <= b) {
            ll ret = 0;
            for(int i = 0; i < 10; i++) ret += tree[n].P[i] * i;
            return ret;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        ll L = quer(a, b, l, m, 2*n);
        ll R = quer(a, b, m + 1, r, 2*n + 1);
        return L + R;
    }
} bit;

int main() {
    scanf("%d %d", &N, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &A[i]);
    }

    bit.init();
    for(int i = 0; i < Q; i++) {
        int t; scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y; scanf("%d %d %d %d", &l, &r, &x, &y);
            l--; r--;
            bit.upd(l, r, x, y, 0, N - 1, 1);
        }
        if(t == 2) {
            int l, r; scanf("%d %d", &l, &r);
            l--; r--;
            printf("%lld\n", bit.quer(l, r, 0, N - 1, 1));
        }
    }
}


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

typedef long long ll;

const int MN = 100010;

int N, Q;
int A[MN];

struct node {
    ll P[10];
    node() {
        for(int i = 0; i < 10; i++) P[i] = 0;
    }
};

node mrg(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) ret.P[i] = a.P[i] + b.P[i];
    return ret;
}

node mul(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        ret.P[i] = a.P[ b.P[i] ];
    }
    return ret;
}

node f(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            if(a.P[j] == i) ret.P[i] += b.P[j];
        }
    }
    return ret;
}

struct BIT {
    vector<node> tree, lazy;
    void init() {
        tree = vector<node>(4 * N);
        lazy = vector<node>(4 * N);
        build(0, N - 1, 1);
    }
    void build(int l, int r, int n) {
        for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        if(l == r) {
            int p = 1;
            while(A[l]) {
                tree[n].P[ A[l] % 10 ] += p;
                A[l] /= 10;
                p *= 10;
            }
            return;
        }
        int m = (l + r)>>1;
        build(l, m, 2*n);
        build(m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    void prop(int l, int r, int n) {
        if(l != r) {
            tree[2*n] = f(lazy[n], tree[2*n]);
            lazy[2*n] = mul(lazy[n], lazy[2*n]);
            tree[2*n + 1] = f(lazy[n], tree[2*n + 1]);
            lazy[2*n + 1] = mul(lazy[n], lazy[2*n + 1]);
            for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        }
    }
    void upd(int a, int b, int x, int y, int l, int r, int n) {
        if(b < l || r < a) return;
        if(a <= l && r <= b) {
            node tmp;
            for(int i = 0; i < 10; i++) tmp.P[i] = i;
            tmp.P[x] = y;
            tree[n] = f(tmp, tree[n]);
            lazy[n] = mul(tmp, lazy[n]);
            return;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        upd(a, b, x, y, l, m, 2*n);
        upd(a, b, x, y, m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    ll quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 0;
        if(a <= l && r <= b) {
            ll ret = 0;
            for(int i = 1; i < 10; i++) ret += tree[n].P[i] * i;
            return ret;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        ll L = quer(a, b, l, m, 2*n);
        ll R = quer(a, b, m + 1, r, 2*n + 1);
        return L + R;
    }
} bit;

int main() {
    scanf("%d %d", &N, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &A[i]);
    }

    bit.init();
    for(int i = 0; i < Q; i++) {
        int t; scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y; scanf("%d %d %d %d", &l, &r, &x, &y);
            l--; r--;
            bit.upd(l, r, x, y, 0, N - 1, 1);
        }
        if(t == 2) {
            int l, r; scanf("%d %d", &l, &r);
            l--; r--;
            printf("%lld\n", bit.quer(l, r, 0, N - 1, 1));
        }
    }
}


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

typedef long long ll;

const int MN = 100010;

int N, Q;
int A[MN];

struct node {
    ll P[10];
};

node mrg(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) ret.P[i] = a.P[i] + b.P[i];
    return ret;
}

node mul(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        ret.P[i] = a.P[ b.P[i] ];
    }
    return ret;
}

node f(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        ret.P[i] = 0;
        for(int j = 0; j < 10; j++) {
            if(a.P[j] == i) ret.P[i] += b.P[j];
        }
    }
    return ret;
}

struct BIT {
    vector<node> tree, lazy;
    void init() {
        tree = vector<node>(4 * N);
        lazy = vector<node>(4 * N);
        build(0, N - 1, 1);
    }
    void build(int l, int r, int n) {
        for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        if(l == r) {
            for(int i = 0; i < 10; i++) tree[n].P[i] = 0;
            int p = 1;
            while(A[l]) {
                tree[n].P[ A[l] % 10 ] += p;
                A[l] /= 10;
                p *= 10;
            }
            return;
        }
        int m = (l + r)>>1;
        build(l, m, 2*n);
        build(m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    void prop(int l, int r, int n) {
        if(l != r) {
            tree[2*n] = f(lazy[n], tree[2*n]);
            lazy[2*n] = mul(lazy[2*n], lazy[n]);
            tree[2*n + 1] = f(lazy[n], tree[2*n + 1]);
            lazy[2*n + 1] = mul(lazy[2*n + 1], lazy[n]);
            for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        }
    }
    void upd(int a, int b, int x, int y, int l, int r, int n) {
        if(b < l || r < a) return;
        if(a <= l && r <= b) {
            node tmp;
            for(int i = 0; i < 10; i++) tmp.P[i] = i;
            tmp.P[x] = y;
            tree[n] = f(tmp, tree[n]);
            lazy[n] = mul(lazy[n], tmp);
            return;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        upd(a, b, x, y, l, m, 2*n);
        upd(a, b, x, y, m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    ll quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 0;
        if(a <= l && r <= b) {
            ll ret = 0;
            for(int i = 0; i < 10; i++) ret += tree[n].P[i] * i;
            return ret;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        ll L = quer(a, b, l, m, 2*n);
        ll R = quer(a, b, m + 1, r, 2*n + 1);
        return L + R;
    }
} bit;

int main() {
    scanf("%d %d", &N, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &A[i]);
    }

    bit.init();
    for(int i = 0; i < Q; i++) {
        int t; scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y; scanf("%d %d %d %d", &l, &r, &x, &y);
            l--; r--;
            bit.upd(l, r, x, y, 0, N - 1, 1);
        }
        if(t == 2) {
            int l, r; scanf("%d %d", &l, &r);
            l--; r--;
            printf("%lld\n", bit.quer(l, r, 0, N - 1, 1));
        }
    }
}


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

typedef long long ll;

const int MN = 100010;

int N, Q;
int A[MN];

struct node {
    ll P[10];
};

node mrg(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) ret.P[i] = a.P[i] + b.P[i];
    return ret;
}

node mul(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        ret.P[i] = a.P[ b.P[i] ];
    }
    return ret;
}

node f(node &a, node &b) {
    node ret;
    for(int i = 0; i < 10; i++) {
        ret.P[i] = 0;
        for(int j = 0; j < 10; j++) {
            if(a.P[j] == i) ret.P[i] += b.P[j];
        }
    }
    return ret;
}

struct BIT {
    vector<node> tree, lazy;
    void init() {
        tree = vector<node>(4 * N);
        lazy = vector<node>(4 * N);
        build(0, N - 1, 1);
    }
    void build(int l, int r, int n) {
        for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        if(l == r) {
            int p = 1;
            while(A[l]) {
                tree[n].P[ A[l] % 10 ] += p;
                A[l] /= 10;
                p *= 10;
            }
            return;
        }
        int m = (l + r)>>1;
        build(l, m, 2*n);
        build(m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    void prop(int l, int r, int n) {
        if(l != r) {
            tree[2*n] = f(lazy[n], tree[2*n]);
            lazy[2*n] = mul(lazy[2*n], lazy[n]);
            tree[2*n + 1] = f(lazy[n], tree[2*n + 1]);
            lazy[2*n + 1] = mul(lazy[2*n + 1], lazy[n]);
            for(int i = 0; i < 10; i++) lazy[n].P[i] = i;
        }
    }
    void upd(int a, int b, int x, int y, int l, int r, int n) {
        if(b < l || r < a) return;
        if(a <= l && r <= b) {
            tree[n].P[y] += tree[n].P[x];
            tree[n].P[x] = 0;
            node tmp;
            for(int i = 0; i < 10; i++) tmp.P[i] = i;
            tmp.P[x] = y;
            lazy[n] = mul(lazy[n], tmp);
            return;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        upd(a, b, x, y, l, m, 2*n);
        upd(a, b, x, y, m + 1, r, 2*n + 1);
        tree[n] = mrg(tree[2*n], tree[2*n + 1]);
    }
    ll quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 0;
        if(a <= l && r <= b) {
            ll ret = 0;
            for(int i = 0; i < 10; i++) ret += tree[n].P[i] * i;
            return ret;
        }
        prop(l, r, n);
        int m = (l + r)>>1;
        ll L = quer(a, b, l, m, 2*n);
        ll R = quer(a, b, m + 1, r, 2*n + 1);
        return L + R;
    }
} bit;

int main() {
    scanf("%d %d", &N, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &A[i]);
    }

    bit.init();
    for(int i = 0; i < Q; i++) {
        int t; scanf("%d", &t);
        if(t == 1) {
            int l, r, x, y; scanf("%d %d %d %d", &l, &r, &x, &y);
            l--; r--;
            bit.upd(l, r, x, y, 0, N - 1, 1);
        }
        if(t == 2) {
            int l, r; scanf("%d %d", &l, &r);
            l--; r--;
            printf("%lld\n", bit.quer(l, r, 0, N - 1, 1));
        }
    }
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    struct Node {
        int num[10];
        int nxt[10];
    } node[4 * N];

    SegmentTree() {
        for (int i = 0; i<4*N; i++) {
            for (int j = 0; j<10; j++) {
                node[i].nxt[j] = j;
            }
        }
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            for (int j = 0; j<10; j++) node[i].num[j] = 0;

            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i].num[v[j]] = node[i].num[v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    void dolazy (int i, int l, int r) {
        if (l > r) return;
        int lazy[10];
        memset(lazy, 0, sizeof(lazy));

        for (int j = 0; j<10; j++) lazy[node[i].nxt[j]] += node[i].num[j];
        for (int j = 0; j<10; j++) node[i].num[j] = lazy[j];
        if (l != r) {
            for (int j = 0; j<10; j++) {
                node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
            }
        }
        for (int j = 0; j<10; j++) node[i].nxt[j] = j;
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i].num[y] += node[i].num[x];
            node[i].num[x] = 0;

            if (l != r) {
                node[i].nxt[x] = y;
                for (int j = 0; j<10; j++) {
                    node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                    node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
                }

                node[i].nxt[x] = x;
            }
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    int get (int i, int l, int r, int a, int b) {
        if (l > r || a > r || b < l) return 0;
        dolazy(i, l, r);

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i].num[j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            if (x == y) continue;
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 100005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    struct Node {
        int num[10];
        int nxt[10];
    } node[4 * N + 1];

    SegmentTree() {
        for (int i = 0; i<=4*N; i++) {
            for (int j = 0; j<10; j++) {
                node[i].nxt[j] = j;
                node[i].num[j] = 0;
            }
        }
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i].num[v[j]] = node[i].num[v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    void dolazy (int i, int l, int r) {
        if (l > r) return;
        int lazy[10];
        memset(lazy, 0, sizeof(lazy));

        for (int j = 0; j<10; j++) lazy[node[i].nxt[j]] += node[i].num[j];
        for (int j = 0; j<10; j++) node[i].num[j] = lazy[j];
        if (l != r) {
            for (int j = 0; j<10; j++) {
                node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
            }
        }
        for (int j = 0; j<10; j++) node[i].nxt[j] = j;
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i].num[y] += node[i].num[x];
            node[i].num[x] = 0;

            if (l != r) {
                node[i].nxt[x] = y;
                for (int j = 0; j<10; j++) {
                    node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                    node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
                }

                node[i].nxt[x] = x;
            }
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    int get (int i, int l, int r, int a, int b) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return 0;

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i].num[j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            if (x == y) continue;
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    struct Node {
        int num[10];
        int nxt[10];
    } node[4 * N + 1];

    SegmentTree() {
        for (int i = 0; i<=4*N; i++) {
            for (int j = 0; j<10; j++) {
                node[i].nxt[j] = j;
                node[i].num[j] = 0;
            }
        }
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i].num[v[j]] = node[i].num[v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    void dolazy (int i, int l, int r) {
        if (l > r) return;
        int lazy[10];
        memset(lazy, 0, sizeof(lazy));

        for (int j = 0; j<10; j++) lazy[node[i].nxt[j]] += node[i].num[j];
        for (int j = 0; j<10; j++) node[i].num[j] = lazy[j];
        if (l != r) {
            for (int j = 0; j<10; j++) {
                node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
            }
        }
        for (int j = 0; j<10; j++) node[i].nxt[j] = j;
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i].num[y] += node[i].num[x];
            node[i].num[x] = 0;

            if (l != r) {
                node[i].nxt[x] = y;
                for (int j = 0; j<10; j++) {
                    node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                    node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
                }

                node[i].nxt[x] = x;
            }
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    int get (int i, int l, int r, int a, int b) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return 0;

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i].num[j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            if (x == y) continue;
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 100005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    int node[4 * N][10], lazy[4 * N][10];

    SegmentTree() {
        memset(lazy, 0, sizeof(lazy));
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            for (int j = 0; j<10; j++) node[i][j] = 0;

            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i][v[j]] = node[i][v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i][j] = node[i << 1][j] + node[i << 1 | 1][j];
    }

    void dolazy (int i, int l, int r) {
        for (int j = 0; j<10; j++) {
            if (lazy[i][j] != 0) {
                node[i][j] = node[i][j] + lazy[i][j];

                if (l != r) {
                    lazy[i << 1][j] += lazy[i][j];
                    lazy[i << 1 | 1][j] += lazy[i][j];
                }

                lazy[i][j] = 0;
            }
        }
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i][y] += node[i][x];

            if (l != r) {
                lazy[i << 1][y] += node[i][x];
                lazy[i << 1 | 1][y] += node[i][x];

                lazy[i << 1][x] -= node[i][x];
                lazy[i << 1 | 1][x] -= node[i][x];
            }

            node[i][x] = 0;
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i][j] = node[i << 1][j] + node[i << 1 | 1][j];
    }

    int get (int i, int l, int r, int a, int b) {
        if (l > r || a > r || b < l) return 0;
        dolazy(i, l, r);

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i][j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    struct Node {
        int num[10];
        int nxt[10];
    } node[4 * N];

    SegmentTree() {
        for (int i = 0; i<4*N; i++) {
            for (int j = 0; j<10; j++) {
                node[i].nxt[j] = j;
                node[i].num[j] = 0;
            }
        }
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i].num[v[j]] = node[i].num[v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    void dolazy (int i, int l, int r) {
        if (l > r) return;
        int lazy[10];
        memset(lazy, 0, sizeof(lazy));

        for (int j = 0; j<10; j++) lazy[node[i].nxt[j]] += node[i].num[j];
        for (int j = 0; j<10; j++) node[i].num[j] = lazy[j];
        if (l != r) {
            for (int j = 0; j<10; j++) {
                node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
            }
        }
        for (int j = 0; j<10; j++) node[i].nxt[j] = j;
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i].num[y] += node[i].num[x];
            node[i].num[x] = 0;

            if (l != r) {
                node[i].nxt[x] = y;
                for (int j = 0; j<10; j++) {
                    node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                    node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
                }

                node[i].nxt[x] = x;
            }
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    int get (int i, int l, int r, int a, int b) {
        if (l > r || a > r || b < l) return 0;
        dolazy(i, l, r);

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i].num[j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            if (x == y) continue;
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 100005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    int node[4 * N][10], lazy[4 * N][10];

    SegmentTree() {
        memset(lazy, 0, sizeof(lazy));
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            for (int j = 0; j<10; j++) node[i][j] = 0;

            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i][v[j]] = node[i][v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i][j] = node[i << 1][j] + node[i << 1 | 1][j];
    }

    void dolazy (int i, int l, int r) {
        for (int j = 0; j<10; j++) {
            if (lazy[i][j] != 0) {
                node[i][j] = node[i][j] + lazy[i][j];

                if (l != r) {
                    lazy[i << 1][j] += lazy[i][j];
                    lazy[i << 1 | 1][j] += lazy[i][j];
                }

                lazy[i][j] = 0;
            }
        }
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i][y] += node[i][x];

            if (l != r) {
                //lazy[i << 1][y] += node[i][x];
                //lazy[i << 1 | 1][y] += node[i][x];

                //lazy[i << 1][x] -= node[i][x];
                //lazy[i << 1 | 1][x] -= node[i][x];
                int m = (l + r) >> 1;
                update(i << 1, l, m, a, b, x, y);
                update(i << 1 | 1, m + 1, r, a, b, x, y);
            }

            node[i][x] = 0;
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i][j] = node[i << 1][j] + node[i << 1 | 1][j];
    }

    int get (int i, int l, int r, int a, int b) {
        if (l > r || a > r || b < l) return 0;
        dolazy(i, l, r);

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i][j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            if (x == y) continue;
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 100005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    int node[4 * N][10], lazy[4 * N][10];

    SegmentTree() {
        memset(lazy, 0, sizeof(lazy));
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            for (int j = 0; j<10; j++) node[i][j] = 0;

            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i][v[j]] = node[i][v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i][j] = node[i << 1][j] + node[i << 1 | 1][j];
    }

    void dolazy (int i, int l, int r) {
        for (int j = 0; j<10; j++) {
            if (lazy[i][j] != 0) {
                node[i][j] = node[i][j] + lazy[i][j];

                if (l != r) {
                    lazy[i << 1][j] += lazy[i][j];
                    lazy[i << 1 | 1][j] += lazy[i][j];
                }

                lazy[i][j] = 0;
            }
        }
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i][y] += node[i][x];

            if (l != r) {
                //lazy[i << 1][y] += node[i][x];
                //lazy[i << 1 | 1][y] += node[i][x];

                //lazy[i << 1][x] -= node[i][x];
                //lazy[i << 1 | 1][x] -= node[i][x];
                int m = (l + r) >> 1;
                update(i << 1, l, m, a, b, x, y);
                update(i << 1 | 1, m + 1, r, a, b, x, y);
            }

            node[i][x] = 0;
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i][j] = node[i << 1][j] + node[i << 1 | 1][j];
    }

    int get (int i, int l, int r, int a, int b) {
        if (l > r || a > r || b < l) return 0;
        dolazy(i, l, r);

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i][j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1005;
int a[N];

int binPow (int x, int y) {
    if (y == 0) return 1;

    int temp = binPow(x, y/2);
    if (y & 1) return x * temp * temp;
    return temp * temp;
}

class SegmentTree {
public:
    struct Node {
        int num[10];
        int nxt[10];
    } node[4 * N];

    SegmentTree() {
        for (int i = 0; i<4*N; i++) {
            for (int j = 0; j<10; j++) {
                node[i].nxt[j] = j;
                node[i].num[j] = 0;
            }
        }
    }

    void build_tree (int i, int l, int r) {
        if (l > r) return;
        if (l == r) {
            int temp = a[l];
            vector <int> v;

            while (temp > 0) {
                int rem = temp % 10;
                temp /= 10;

                v.push_back(rem);
            }

            for (int j = 0; j<v.size(); j++) node[i].num[v[j]] = node[i].num[v[j]] + binPow(10, j);

            return;
        }

        int m = (l + r) >> 1;
        build_tree(i << 1, l, m);
        build_tree(i << 1 | 1, m + 1, r);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    void dolazy (int i, int l, int r) {
        if (l > r) return;
        int lazy[10];
        memset(lazy, 0, sizeof(lazy));

        for (int j = 0; j<10; j++) lazy[node[i].nxt[j]] += node[i].num[j];
        for (int j = 0; j<10; j++) node[i].num[j] = lazy[j];
        if (l != r) {
            for (int j = 0; j<10; j++) {
                node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
            }
        }
        for (int j = 0; j<10; j++) node[i].nxt[j] = j;
    }

    void update (int i, int l, int r, int a, int b, int x, int y) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return;
        if (a <= l && r <= b) {
            node[i].num[y] += node[i].num[x];
            node[i].num[x] = 0;

            if (l != r) {
                node[i].nxt[x] = y;
                for (int j = 0; j<10; j++) {
                    node[i << 1].nxt[j] = node[i].nxt[node[i << 1].nxt[j]];
                    node[i << 1 | 1].nxt[j] = node[i].nxt[node[i << 1 | 1].nxt[j]];
                }

                node[i].nxt[x] = x;
            }
            return;
        }

        int m = (l + r) >> 1;
        update(i << 1, l, m, a, b, x, y);
        update(i << 1 | 1, m + 1, r, a, b, x, y);

        for (int j = 0; j<10; j++) node[i].num[j] = node[i << 1].num[j] + node[i << 1 | 1].num[j];
    }

    int get (int i, int l, int r, int a, int b) {
        dolazy(i, l, r);
        if (l > r || a > r || b < l) return 0;

        if (a <= l && r <= b) {
            int ans = 0;
            for (int j = 0; j<10; j++) ans = ans + node[i].num[j] * j;

            return ans;
        }

        int m = (l + r) >> 1;
        return get(i << 1, l, m, a, b) + get(i << 1 | 1, m + 1, r, a, b);
    }
};

signed main(){
    int n, q;
    scanf("%lld %lld", &n, &q);
    for (int i = 1; i<=n; i++) scanf("%lld", &a[i]);

    SegmentTree it = SegmentTree();
    it.build_tree(1, 1, n);

    while (q--) {
        int type;
        scanf("%lld", &type);

        if (type == 1) {
            int l, r, x, y;
            scanf("%lld %lld %lld %lld", &l, &r, &x, &y);
            if (x == y) continue;
            it.update(1, 1, n, l, r, x, y);
        }
        else {
            int l, r;
            scanf("%lld %lld", &l, &r);
            printf("%lld\n", it.get(1, 1, n, l, r));
        }
    }
    return 0;
}


/*************************************************************************
  >         File: E.cc
  >       Author: Yuan Lei
  >         Mail: yuanlei@indeed.com
  > Created Time: Sat May 13 19:42:08 2017
*************************************************************************/
#include <vector>
#include <cstdio>
#include <bitset>
#include <utility>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <cstring>
#include <cassert>
#include <numeric>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <iomanip>

constexpr int N = 1e5 + 5;
int a[N], f[N << 2][10];
using LL = long long;
LL s[N << 2][10];
LL answer[10];

template<class T>
void in(T& x) {
  char c;
  while (!isdigit(c = getchar()) && c != '-');
  bool flag = (c == '-');
  if (flag) c = getchar();
  x = c - '0';
  while (isdigit(c = getchar())) x = x * 10 + c - '0';
  if (flag) x *= -1;
}

template<class T>
void out(T x) {
  if (x < 0) putchar('-'), x *= -1;
  int length = 0, bit[20];
  for (; x > 0; x /= 10) bit[length++] = x % 10;
  if (!length) bit[length++] = 0;
  while (length--) putchar(bit[length] + '0');
  putchar('\n');
}

int ql, qr, from, to;

#define L (x << 1)
#define R (x << 1 | 1)
#define MID ((l + r) >> 1)
#define LC L, l, MID
#define RC R, MID + 1, r

void merge(int x, int l, int r) {
  for (int i = 0; i < 10; ++i) {
    s[x][i] = s[L][i] + s[R][i];
    f[x][i] = i;
  }
}

void build(int x, int l, int r) {
  if (l == r) {
    for (int i = 0; i < 10; ++i) s[x][i] = 0, f[x][i] = i;
    LL now = 1;
    while (a[l]) {
      int d = a[l] % 10;
      s[x][d] += now;
      now *= 10;
      a[l] /= 10;
    }
  } else {
    build(LC), build(RC);
    merge(x, l, r);
  }
}

void combine(int *a, int *b, int *c) {
  for (int i = 0; i < 10; ++i) {
    c[i] = b[a[i]];
  }
}

void push(int x, int l, int r) {
  if (l == r) return ;

  static LL sum[10];
  static int tmp[10];
  for (int i = 0; i < 10; ++i) sum[i] = 0;
  for (int i = 0; i < 10; ++i) {
    sum[f[x][i]] += s[L][i];
  }
  for (int i = 0; i < 10; ++i) {
    s[L][i] = sum[i];
  }
  combine(f[L], f[x], tmp);
  for (int i = 0; i < 10; ++i) f[L][i] = tmp[i];

  for (int i = 0; i < 10; ++i) sum[i] = 0;
  for (int i = 0; i < 10; ++i) {
    sum[f[x][i]] += s[R][i];
  }
  for (int i = 0; i < 10; ++i) {
    s[R][i] = sum[i];
  }
  combine(f[R], f[x], tmp);
  for (int i = 0; i < 10; ++i) f[R][i] = tmp[i];
}

void update(int x, int l, int r) {
  if (ql <= l && qr >= r) {
    static int A[10], B[10];
    for (int i = 0; i < 10; ++i) A[i] = i;
    s[x][to] += s[x][from];
    s[x][from] = 0;
    A[from] = to;
    combine(f[x], A, B);
    for (int i = 0; i < 10; ++i) f[x][i] = B[i];
  } else {
    push(x, l, r);
    if (ql <= MID) update(LC);
    if (qr > MID) update(RC);
    merge(x, l, r);
  }
}

void query(int x, int l, int r) {
  if (ql <= l && qr >= r) {
    for (int i = 0; i < 10; ++i) answer[i] += s[x][i];
  } else {
    push(x, l, r);
    if (ql <= MID) query(LC);
    if (qr > MID) query(RC);
    merge(x, l, r);
  }
}

int main() {
  std::cerr << "[Line #" << __LINE__ << "] fuck !!!" << std::endl;
  int n, q;
  in(n), in(q);
  for (int i = 0; i < n; ++i) in(a[i + 1]);
  build(1, 1, n);
  for (int i = 0; i < q; ++i) {
    int type;
    in(type), in(ql), in(qr);
    if (type == 1) {
      in(from), in(to);
      if (from == to) continue;
      update(1, 1, n);
    } else {
      for (int i = 0; i < 10; ++i) answer[i] = 0;
      query(1, 1, n);
      LL ans = 0;
      for (int i = 0; i < 10; ++i) ans += i * answer[i];
      out(ans);
    }
  }

  return 0;
}


/*************************************************************************
  >         File: E.cc
  >       Author: Yuan Lei
  >         Mail: yuanlei@indeed.com
  > Created Time: Sat May 13 19:42:08 2017
*************************************************************************/
#include <vector>
#include <cstdio>
#include <bitset>
#include <utility>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <cstring>
#include <cassert>
#include <numeric>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <iomanip>

constexpr int N = 1e5 + 5;
int a[N], f[N << 2][10];
using LL = long long;
LL s[N << 2][10];
LL answer[10];

template<class T>
void in(T& x) {
  char c;
  while (!isdigit(c = getchar()) && c != '-');
  bool flag = (c == '-');
  if (flag) c = getchar();
  x = c - '0';
  while (isdigit(c = getchar())) x = x * 10 + c - '0';
  if (flag) x *= -1;
}

template<class T>
void out(T x) {
  if (x < 0) putchar('-'), x *= -1;
  int length = 0, bit[20];
  for (; x > 0; x /= 10) bit[length++] = x % 10;
  if (!length) bit[length++] = 0;
  while (length--) putchar(bit[length] + '0');
  putchar('\n');
}

int ql, qr, from, to;

#define L (x << 1)
#define R (x << 1 | 1)
#define MID ((l + r) >> 1)
#define LC L, l, MID
#define RC R, MID + 1, r

void merge(int x, int l, int r) {
  for (int i = 0; i < 10; ++i) {
    s[x][i] = s[L][i] + s[R][i];
    f[x][i] = i;
  }
}

void build(int x, int l, int r) {
  if (l == r) {
    for (int i = 0; i < 10; ++i) s[x][i] = 0, f[x][i] = i;
    LL now = 1;
    while (a[l]) {
      int d = a[l] % 10;
      s[x][d] += now;
      now *= 10;
      a[l] /= 10;
    }
  } else {
    build(LC), build(RC);
    merge(x, l, r);
  }
}

void combine(int *a, int *b, int *c) {
  for (int i = 0; i < 10; ++i) {
    c[i] = b[a[i]];
  }
}

void push(int x, int l, int r) {
  if (l == r) return ;

  static LL sum[10];
  static int tmp[10];
  for (int i = 0; i < 10; ++i) sum[i] = 0;
  for (int i = 0; i < 10; ++i) {
    sum[f[x][i]] += s[L][i];
  }
  for (int i = 0; i < 10; ++i) {
    s[L][i] = sum[i];
  }
  combine(f[L], f[x], tmp);
  for (int i = 0; i < 10; ++i) f[L][i] = tmp[i];

  for (int i = 0; i < 10; ++i) sum[i] = 0;
  for (int i = 0; i < 10; ++i) {
    sum[f[x][i]] += s[R][i];
  }
  for (int i = 0; i < 10; ++i) {
    s[R][i] = sum[i];
  }
  combine(f[R], f[x], tmp);
  for (int i = 0; i < 10; ++i) f[R][i] = tmp[i];
}

void update(int x, int l, int r) {
  if (ql <= l && qr >= r) {
    static int A[10], B[10];
    for (int i = 0; i < 10; ++i) A[i] = i;
    s[x][to] += s[x][from];
    s[x][from] = 0;
    A[from] = to;
    combine(f[x], A, B);
    for (int i = 0; i < 10; ++i) f[x][i] = B[i];
  } else {
    push(x, l, r);
    if (ql <= MID) update(LC);
    if (qr > MID) update(RC);
    merge(x, l, r);
  }
}

void query(int x, int l, int r) {
  if (ql <= l && qr >= r) {
    for (int i = 0; i < 10; ++i) answer[i] += s[x][i];
  } else {
    push(x, l, r);
    if (ql <= MID) query(LC);
    if (qr > MID) query(RC);
    merge(x, l, r);
  }
}

int main() {
  std::ios::sync_with_stdio(0);
  int n, q;
  in(n), in(q);
  for (int i = 0; i < n; ++i) in(a[i + 1]);
  build(1, 1, n);
  for (int i = 0; i < q; ++i) {
    int type;
    in(type), in(ql), in(qr);
    if (type == 1) {
      in(from), in(to);
      if (from == to) continue;
      update(1, 1, n);
    } else {
      for (int i = 0; i < 10; ++i) answer[i] = 0;
      query(1, 1, n);
      LL ans = 0;
      for (int i = 0; i < 10; ++i) ans += i * answer[i];
      out(ans);
    }
  }

  return 0;
}


/*************************************************************************
  >         File: E.cc
  >       Author: Yuan Lei
  >         Mail: yuanlei@indeed.com
  > Created Time: Sat May 13 19:42:08 2017
*************************************************************************/
#include <vector>
#include <cstdio>
#include <bitset>
#include <utility>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <cstring>
#include <cassert>
#include <numeric>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <iomanip>

constexpr int N = 1e5 + 5;
int a[N], f[N << 2][10];
using LL = long long;
LL s[N << 2][10];
LL answer[10];

template<class T>
void in(T& x) {
  char c;
  while (!isdigit(c = getchar()) && c != '-');
  bool flag = (c == '-');
  if (flag) c = getchar();
  x = c - '0';
  while (isdigit(c = getchar())) x = x * 10 + c - '0';
  if (flag) x *= -1;
}

template<class T>
void out(T x) {
  if (x < 0) putchar('-'), x *= -1;
  int length = 0, bit[20];
  for (; x > 0; x /= 10) bit[length++] = x % 10;
  if (!length) bit[length++] = 0;
  while (length--) putchar(bit[length] + '0');
  putchar('\n');
}

int ql, qr, from, to;

#define L (x << 1)
#define R (x << 1 | 1)
#define MID ((l + r) >> 1)
#define LC L, l, MID
#define RC R, MID + 1, r

void merge(int x, int l, int r) {
  for (int i = 0; i < 10; ++i) {
    s[x][i] = s[L][i] + s[R][i];
    f[x][i] = i;
  }
}

void build(int x, int l, int r) {
  if (l == r) {
    for (int i = 0; i < 10; ++i) s[x][i] = 0, f[x][i] = i;
    LL now = 1;
    while (a[l]) {
      int d = a[l] % 10;
      s[x][d] += now;
      now *= 10;
      a[l] /= 10;
    }
  } else {
    build(LC), build(RC);
    merge(x, l, r);
  }
}

void combine(int *a, int *b, int *c) {
  for (int i = 0; i < 10; ++i) {
    c[i] = b[a[i]];
  }
}

void push(int x, int l, int r) {
  if (l == r) return ;

  static LL sum[10];
  static int tmp[10];
  for (int i = 0; i < 10; ++i) sum[i] = 0;
  for (int i = 0; i < 10; ++i) {
    sum[f[x][i]] += s[L][i];
  }
  for (int i = 0; i < 10; ++i) {
    s[L][i] = sum[i];
  }
  combine(f[L], f[x], tmp);
  for (int i = 0; i < 10; ++i) f[L][i] = tmp[i];

  for (int i = 0; i < 10; ++i) sum[i] = 0;
  for (int i = 0; i < 10; ++i) {
    sum[f[x][i]] += s[R][i];
  }
  for (int i = 0; i < 10; ++i) {
    s[R][i] = sum[i];
  }
  combine(f[R], f[x], tmp);
  for (int i = 0; i < 10; ++i) f[R][i] = tmp[i];
}

void update(int x, int l, int r) {
  if (ql <= l && qr >= r) {
    static int A[10], B[10];
    for (int i = 0; i < 10; ++i) A[i] = i;
    s[x][to] += s[x][from];
    s[x][from] = 0;
    A[from] = to;
    combine(f[x], A, B);
    for (int i = 0; i < 10; ++i) f[x][i] = B[i];
  } else {
    push(x, l, r);
    if (ql <= MID) update(LC);
    if (qr > MID) update(RC);
    merge(x, l, r);
  }
}

void query(int x, int l, int r) {
  if (ql <= l && qr >= r) {
    for (int i = 0; i < 10; ++i) answer[i] += s[x][i];
  } else {
    push(x, l, r);
    if (ql <= MID) query(LC);
    if (qr > MID) query(RC);
    merge(x, l, r);
  }
}

int main() {
  std::ios::sync_with_stdio(0);
  int n, q;
  std::cin >> n >> q;
  for (int i = 0; i < n; ++i) in(a[i + 1]);
  build(1, 1, n);
  for (int i = 0; i < q; ++i) {
    int type;
    in(type), in(ql), in(qr);
    if (type == 1) {
      in(from), in(to);
      if (from == to) continue;
      update(1, 1, n);
    } else {
      for (int i = 0; i < 10; ++i) answer[i] = 0;
      query(1, 1, n);
      LL ans = 0;
      for (int i = 0; i < 10; ++i) ans += i * answer[i];
      out(ans);
    }
  }

  return 0;
}