#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define pp pair<pair<ll, ll>,pair<ll, ll>>
#define pll pair<ll,ll>
#define ppll pair<ll,pll>
#define pdd pair<double,double>
#define vii vector<int>
#define vll vector<ll>
#define mat vector<vector<ll>>
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define eb emplace_back
#define fi first
#define sc second
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep2(i,a,b) for(ll i=a;i<b;i++)
#define repr(i,n) for(ll i=n-1;i>=0;i--)
#define all(x) x.begin(),x.end()
#define sz(x) (ll) (x).size()
#define pq priority_queue<ll>
#define pqg priority_queue<ll,vector<ll>,greater<ll>>
#define LB(v,x) (lower_bound(v.begin(),v.end(),x)-v.begin())
#define UB(v,x) (upper_bound(v.begin(),v.end(),x)-v.begin())
#define ERASE(v) sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end())
#define int ll
// #define ll int
using namespace std;
const ll INF = 1 << 29;
const ll LLINF = (1LL << 60LL);
const ll MOD = 1000000007;
const int MAX_V = 500;
const ll mod = 998244353;
const ll MAX = 2100000;
const double pi = acos(-1);
const double eps = 1e-10;
ll dx[8] ={1,0,-1,0,1,-1,1,-1};
ll dy[8] ={0,1,0,-1,1,-1,-1,1};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }




ll s[200010];


template<class Monoid, class Action>
struct LazySegmentTree {
    using FuncMonoid = function< Monoid(Monoid, Monoid) >;
    using FuncAction = function< void(Monoid&, Action) >;
    using FuncLazy = function< void(Action&, Action) >;
    using FuncPropotional = function< Action(Action, int)>;
    FuncMonoid FM;
    FuncAction FA;
    FuncLazy FL;
    FuncPropotional FP;
    Monoid UNITY_MONOID;
    Action UNITY_LAZY;
    int size, height;
    vector<Monoid> dat;
    vector<Action> lazy;

    LazySegmentTree() { }
    LazySegmentTree(int n, const FuncMonoid fm, const FuncAction fa, const FuncLazy fl,
            const Monoid &unity_monoid, const Action &unity_lazy,
            const FuncPropotional fp = [](Action a, int b){return a;})
    : FM(fm), FA(fa), FL(fl),FP(fp), UNITY_MONOID(unity_monoid), UNITY_LAZY(unity_lazy) {
        size = 1; height = 0;
        while(size < n){ size <<= 1; height++; }
        dat.assign(size * 2, UNITY_MONOID);
        lazy.assign(size * 2, UNITY_LAZY);
    }

    void init(int n, const FuncMonoid fm, const FuncAction fa, const FuncLazy fl,
            const Monoid &unity_monoid, const Action &unity_lazy,
            const FuncPropotional fp = [](Action a, int b){return a;}) {
        FM = fm; FA = fa; FL = fl; FP = fp;
        UNITY_MONOID = unity_monoid;
        UNITY_LAZY = unity_lazy;
        size = 1; height = 0;
        while(size < n){ size <<= 1; height++; }
        dat.assign(size * 2, UNITY_MONOID);
        lazy.assign(size * 2, UNITY_LAZY);
    }

    void set(int a, const Monoid &v) { dat[a + size] = v; }
    void build() {
        for (int k = size - 1; k > 0; --k){
            dat[k] = FM(dat[k * 2], dat[k * 2 + 1]);
        }
    }

    // [a,b)
    inline void evaluate(int k, int len) {
        if(lazy[k] == UNITY_LAZY) return;
        if(k < size) FL(lazy[k * 2], lazy[k]), FL(lazy[k * 2 + 1], lazy[k]);
        FA(dat[k], FP(lazy[k], len));
        lazy[k] = UNITY_LAZY;
    }
    inline void update(int a, int b, const Action &v, int k, int l, int r){
        evaluate(k, r - l);
        if(a <= l && r <= b) FL(lazy[k], v), evaluate(k, r - l);
        else if(a < r && l < b) {
            update(a, b, v, k * 2, l, (l+r)>>1), update(a, b, v, k * 2 + 1, (l+r)>>1, r);
            dat[k] = FM(dat[k * 2], dat[k * 2 + 1]);
        }
    }
    inline void update(int a, int b, const Action &v) { update(a, b, v, 1, 0, size);}


    inline Monoid get(int a, int b, int k, int l, int r) {
        evaluate(k, r - l);
        if (a <= l && r <= b) 
            return dat[k];
        else if (a < r && l < b) 
            return FM(get(a, b, k*2, l, (l+r)>>1), get(a, b, k*2+1, (l+r)>>1, r));
        else
            return UNITY_MONOID;
    }
    inline Monoid get(int a, int b) { return get(a, b, 1, 0, size); }
    inline Monoid operator[] (int a) { return get(a, a+1); }
    
    void print() {
        for (int i = 1; i <= size*2; i++) {
            cout<<i<<"("<< dat[i].fi<<" "<<dat[i].sc<<")";
            // cout << (*this)[i].fi<<" "<<(*this)[i].sc<<")";
            // if (i != size) cout << ", ";
        }
        cout<<endl;
    }

    void print_aa() {
        for (int i = 0; i < size*2; i++) {
            cout << dat[i].fi<<" "<< dat[i].sc<<")";
            // if (i != size) cout << ", ";
        }
        cout<<endl;
    }

};



ll mod_pow(ll x,ll n, ll mod){
    if(n==0) return 1;
    ll res=mod_pow(x * x % mod, n/2, mod);
    if(n & 1) res=res * x % mod;
    return res;
}


ll extgcd(ll a, ll b, ll& x, ll& y){
    ll d=a;
    if(b != 0){
        d = extgcd(b, a%b, y, x);
        y -= (a/b) * x;
    }
    else{
        x=1;y=0;
    }
    return d;
}


ll mod_inverse(ll a,ll mod){
    ll x,y;
    extgcd(a,mod,x,y);
    return (mod+x%mod)%mod;
}



void solve() {
    ll n,q;
    cin>>n>>q;

    s[0]=1;
    rep(i,200004){
        s[i+1] = s[i]*10;
        s[i+1]%=mod;
    }


    auto fm = [](pll a, pll b){ 
        if(a == pll(-1,-1)) return b;
        else if(b == pll(-1,-1) ) return a;
        else return pll( (s[b.sc] * a.fi % mod+ b.fi ) %mod,a.sc + b.sc);
        };
    auto fa = 
    [](pll &a, ll d){ 
        // a *= mod_inverse(b, MOD) % MOD で 
        // a ÷ b mod MOD を計算できる
        a.fi = (s[a.sc] - 1);
        a.fi *= mod_inverse(9,mod);
        a.fi *= d;
        a.fi %=mod; 
    };
    auto fl = [](ll &d, ll e){ d = e; };
    // auto fp = [](pll a, ll b){return pll(a.fi, a.sc*b%mod) ;};
    pll ex = {-1, -1};
    ll em = -1;
    LazySegmentTree<pll, ll> sg(n, fm, fa, fl, ex, em);


    rep(i,n) sg.set(i, pll(1,1));
    // sg.set(0,pll(1,1));
    sg.build();

    // sg.print();
    // cout<<sg.get(0,n).fi<<" "<<sg.get(0,n).sc<<endl;


    rep(query, q){
        ll l,r,d;
        cin>>l>>r>>d;
        sg.update(l-1,r,d);
        pll ans = sg.get(0,n);
        cout<<ans.fi<<endl;



        // cout<<ans.fi<<" "<<ans.sc<<endl;
        // sg.print();

        // cout<<query<<" ";
        // cout<<(ans.fi+ans.sc)%mod<<endl;
    }

}




signed main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);


    ll t=1;
    
    // cin>>t;

    rep(i,t){
        solve(); 
    }

    return 0;
}


Measured memory_bytes: 17200