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

#define int long long
using ll = long long;
using ld = long double;
using intpair = pair<int, int>;
using intmap = map<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
const int MOD = 998244353;
inline int mod (ll a, int m = MOD) { return (a % m + m) % m; }
inline bool bit (ll b, ll i) { return b & (1 << i); }
inline ll ceiv (ll a, ll b) { return (a + b - 1) / b; }
//struct Fast {Fast(){cin.tie(0);ios::sync_with_stdio(0);}} fast;

#define debug(x) cerr << #x << ": " << x << '\n'
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, n, m) for (int i = (int)(n); i <= (int)(m); i++)
#define ALL(obj) (obj).begin(), (obj).end()
#define rALL(obj) (obj).rbegin(), (obj).rend()

template <class T, T (*op1)(T, T), T (*e1)(), // Monoid T
          class U, U (*op2)(U, U), U (*e2)(), // Monoid U
          T (*action)(T, U)>                  // Action b/w T - U

class LazySegmentTree {
    
private:
    vector<T> node;
    vector<U> lazy;
    int n, h;
    
    void eval(int k) {
        if(lazy[k] == e2()) return; // Propagated
        
        if(k < n) { //not reached bottom of tree
            lazy[(k << 1)|0] = op2(lazy[(k << 1)|0], lazy[k]);
            lazy[(k << 1)|1] = op2(lazy[(k << 1)|1], lazy[k]);
        }
        node[k] = action(node[k], lazy[k]);
        lazy[k] = e2();
    }
    
    void update(int idx) {
        node[idx] = op1(action(node[(idx << 1)|0], lazy[(idx << 1)|0]),
                        action(node[(idx << 1)|1], lazy[(idx << 1)|1]));
    }
    
    void propagate_from_top(int l, int r) {
        l += n, r += n - 1;
        for(int i = h; i > 0; i--) {
            eval(l >> i);
            eval(r >> i);
        }
    }
    
    void inittree(int size) {
        n = 1, h = 0;
        while(n < size) { n <<= 1; h++; }
        node.resize(n << 1, e1());
        lazy.resize(n << 1, e2());
    }
    
    void buildtree() {
        for(int i = 2*n-2; i > 0; i -= 2) {
            node[i >> 1] = op1(node[i], node[i|1]);
        }
    }
    
public:
    LazySegmentTree(int size) {
        inittree(size);
        buildtree();
    }
    
    void print(){
        for(auto p : node){
            cout << p.val << endl;
        }
    }
    
    LazySegmentTree(const vector<T> &init_v) {
        inittree(init_v.size());
        for(int i = 0; i < init_v.size(); i++) {
            node[n + i] = init_v[i];
        }
        buildtree();
    }
    
    void update(int l, int r, U val) {
        propagate_from_top(l, r);
        l += n, r += n;
        int tl = l >> 1, tr = (r - 1) >> 1;
        
        while(l < r) {
            if(l & 1) {lazy[l] = op2(lazy[l], val); l++;}
            if(r & 1) {r--; lazy[r] = op2(lazy[r], val);}
            l >>= 1; r >>= 1;
        }
        
        while(tl > 0) {
            if(lazy[tl] == e2()) update(tl);
            if(lazy[tr] == e2()) update(tr);
            tl >>= 1; tr >>= 1;
        }
    }
    
    T get(int l, int r) {
        propagate_from_top(l, r);
        l += n, r += n;
        T valL = e1(), valR = e1();
        while(l < r) {
            if(l & 1) {valL = op1(valL, action(node[l], lazy[l])); l++;}
            if(r & 1) {r--; valR = op1(action(node[r], lazy[r]), valR);}
            l >>= 1; r >>= 1;
        }
        return op1(valL, valR);
    }
    
    T get_all() {
        return get(0, n);
    }
};

int modpow(int a, int n, int m = MOD){
    ll ret = 1;
    while(n>0){
        if(n&1) ret = (ret*a) % m;
        a = (a*a) % m;
        n >>= 1;
    }
    return ret % m;
}

const int N_LIMIT = 200000;
vvi repeatmod(10, vi(N_LIMIT + 1));

void init_repeatmod() {
    reps(i, 1, 9) {
        repeatmod[i][0] = 0;
        reps(j, 1, N_LIMIT) {
            repeatmod[i][j] = (repeatmod[i][j-1] * 10 + i) % MOD;
        }
    }
}

struct S {
    int val, size;
};

S op1(S a, S b) {
    int newval = mod(a.val * modpow(10, b.size) + b.val);
    return S {newval, a.size + b.size};
}

S e1() { return S{0, 0}; };

int op2(int a, int b) { return b == -1 ? a : b; }

int e2() { return -1; }

S f(S a, int b) {
    if(b == -1) return a;
    return S {repeatmod[b][a.size], a.size};
}

signed main() {
    init_repeatmod();
    int n, Q;
    cin >> n >> Q;
    
    vector<S> initv(n, S{1,1});
    LazySegmentTree<S, op1, e1, int, op2, e2, f> lst(initv);
    
    while(Q--) {
        int l, r, d;
        cin >> l >> r >> d;
        l--;
        lst.update(l, r, d);
        printf("%lld\n", lst.get_all().val);
    }
}

Measured memory_bytes: 34264