#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

using namespace __gnu_pbds; 
using namespace std;

#define int           long long
#define S             second
#define F             first
#define pb            push_back
#define all(c)        (c).begin(),(c).end()
#define rall(c)       (c).rbegin(),(c).rend() 
#define lb            lower_bound
#define ub            upper_bound
#define si(c)         (int)((c).size())
#define lcm(a, b)      (a * (b / __gcd(a,b)))  
#define inf           (int)(4e18)
#define endl          '\n'
#define mp            make_pair
#define time(s)       (double(clock()-s)/double(CLOCKS_PER_SEC))
#define debug(args...)    _F(#args, args)
#define vi            std::vector<int>
#define pii           pair<int, int> 
#define vpi           vector<pii>
#define ordered_set   tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 

clock_t start;
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());

template<typename T> void _F(const char *name, T arg1){ cerr << name << " = " << arg1 << endl;}
template<typename T, typename... Args> void _F(const char *names, T arg1, Args... args)
{ const char *name = strchr(names, ',');cerr.write(names, name-names) << " = " << arg1 << endl;_F(name+2, args...);}

template< typename T1, typename T2 > istream& operator>>(istream& in, pair<T1, T2> &q){ in >> q.F >> q.S; return in;}
template< typename T1, typename T2 > ostream& operator<<(ostream& out, pair<T1, T2> &q){ out << q.F << " " << q.S; return out;}
template< typename T1, typename T2 > pair<T1, T2> operator+(pair<T1, T2> p1, pair<T1, T2> p2){ return {p1.F+p2.F, p1.S+p2.S};}
template< typename T1, typename T2 > pair<T1, T2> operator-(pair<T1, T2> p1, pair<T1, T2> p2){ return {p1.F-p2.F, p1.S-p2.S};}
template< typename T1, typename T2 > bool operator<(pair<T1, T2> p1, pair<T1, T2> p2){ return p1 < p2 ;}

template<typename T> void Unique(vector<T> &v) {
    sort(all(v)), v.resize(distance(v.begin(), unique(all(v))));
}

const int N = 2e5+1;
const int M = 998244353;
int p[N], t[N*4], lazy[N*4];
int n, q;

int sub(int l, int r) {
	return (p[l]-p[r+1]+M)%M;
}

void build(int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = sub(tl, tl);
    } else {
        int tm = (tl + tr) / 2;
        build(v*2, tl, tm);
        build(v*2+1, tm+1, tr);
        t[v] = (t[v*2]+t[v*2+1])%M;
    }
}

void push(int v, int l, int r) {
	int m = (l+r) >> 1;
    t[v*2] = sub(l, m)*lazy[v]%M;
    lazy[v*2] = lazy[v];
    t[v*2+1] = sub(m+1, r)*lazy[v]%M;
    lazy[v*2+1] = lazy[v];
    lazy[v] = 0;
}

void update(int v, int tl, int tr, int l, int r, int d) {
    if (l > r) 
        return;
    if (l == tl && tr == r) {
        t[v] = sub(l, r)*d%M;
        lazy[v] = d;
    } else {
        int tm = (tl + tr) / 2;
        if(lazy[v])push(v, tl, tr);
        update(v*2, tl, tm, l, min(r, tm), d);
        update(v*2+1, tm+1, tr, max(l, tm+1), r, d);
        t[v] = (t[v*2] + t[v*2+1])%M;
    }
}

void solve() {
	cin >> n >> q;
	p[n] = 1;
	for(int i = n-1; i > 0; i--) {
		p[i] = p[i+1]*10%M;
	}
	for(int i = n-1; i > 0; i--) {
		p[i] += p[i+1];
		p[i] %= M;
	}
	build(1, 1, n);
	// cout << t[1] << endl;
	while(q--) {
		int l, r, d;
		cin >> l >> r >> d;
		update(1, 1, n, l, r, d);
		cout << t[1] << endl;
	}
}

signed main(){

    ios_base::sync_with_stdio(0); 
    cin.tie(0); cout.tie(0);   
    start = clock(); 

   
    int test = 1;
    // cin >> test;
    
    cout << fixed << setprecision(2);
     
    for(int i = 1; i <= test; ++i){
    	solve();
    }

    cerr << time(start);
    return 0;
}


Measured memory_bytes: 13540