// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#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 ll long long int
#define lu unsigned long long int
#define pi pair<ll, ll>
#define pll pair<ll, ll>
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define mk make_pair
#define ve vector
#define vll ve<ll>
#define vpl ve<pll>
#define lr(n) for(ll i = 0; i < n; i++)
#define ltr(i, l, r) for (ll i = l; i <= r; i++)
#define rtl(i, l, r) for (ll i = r; i >= l; i--)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define be begin
#define sz(a) (ll)(a.size())
#define con continue
#define ret return
#define endl "\n"
const ll INF = 1e18;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// order_of_key(val): returns the number of values less than val
// find_by_order(k): returns an iterator to the kth largest element (0-based)

// ll gcd(ll a, ll b){
// 	return b == 0 ? a : gcd(b, a % b);
// }

// ll mod = 1e9+7;

ll mod = 998244353;

ll mult(ll x, ll y){
    ll rem=1;
    while(y){
        if(y&1){
            rem=(rem*x)%mod;
        }
        x=(x*x)%mod;
        y>>=1;
    }
    return rem;
}


ll ten[200005]={0};
ll tnn[200005]={0};

struct segtree{
	ll size;
	ve<ll> operations;
	ve<pi> values;

	pi neutral = {INF, 0};
	ll no_operation = INF;

	pi modify_op(pi a, ll b, ll l){
		if(b == no_operation) return a;
		return {b*tnn[l]%mod, l};
	}

	pi calc_op(pi a, pi b){
		if(b == neutral) return a;
		return {(a.fi*ten[b.se]+b.fi)%mod, a.se+b.se};
	}

	void apply_mod_op(pi &a, ll b, ll l){
		a = modify_op(a, b, l);
	}

	void build(ll n, ll x, ll lx, ll rx){
		if(rx - lx == 1){
			if(lx < n){
				values[x] = {1, 1};
			}
			return;
		}
		ll m = (lx + rx) / 2;
		build(n, 2*x+1, lx, m);
		build(n, 2*x+2, m, rx);
		values[x] = calc_op(values[2*x+1], values[2*x+2]);
	}

	void init(ll n){
		size = 1;
		while(size < n) size *= 2;
		operations.assign(2*size, no_operation);
		values.assign(2*size, neutral);
		build(n, 0, 0, size);
	}

	void propogate(ll x, ll lx, ll rx){
		if(rx - lx == 1) return;
		ll m = (lx + rx) / 2;
		if(operations[x] != no_operation){
			operations[2*x+1] = operations[2*x+2] = operations[x];
			apply_mod_op(values[2*x+1], operations[x], m-lx);
			apply_mod_op(values[2*x+2], operations[x], rx-m);			
		}
		operations[x] = no_operation;
	}

	void set(ll l, ll r, ll v, ll x, ll lx, ll rx){
		propogate(x, lx, rx);
		if(lx>=r || rx<=l) return;
		if(lx>=l && rx<=r){
			operations[x] = v;
			apply_mod_op(values[x], v, rx-lx);
			return;
		}
		ll m = (lx + rx) / 2;
		set(l, r, v, 2*x+1, lx, m);
		set(l, r, v, 2*x+2, m, rx);
		values[x] = calc_op(values[2*x+1], values[2*x+2]);
	}

	void set(ll l, ll r, ll v){
		set(l, r, v, 0, 0, size);
	}
};

void solve(ll T){
	ten[0]=1;
	for(ll i=1;i<200005;i++){
		ten[i] = (ten[i-1]*10)%mod;
		tnn[i] = (ten[i]-1+mod)%mod*mult(9, mod-2)%mod;
	}

	ll n,q;
	cin>>n>>q;
	segtree seg;
	seg.init(n);
	while(q--){
		ll l,r,d;
		cin>>l>>r>>d;
		seg.set(l-1, r, d);
		cout << seg.values[0].fi << "\n";
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	// std::cout << std::unitbuf;
	ll T=1;
	// cin>>T;
	for(ll t=1;t<=T;t++){
		solve(t);
	}
	return 0;
}


Measured memory_bytes: 18780