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

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;

#define fastio() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define test() int t;cin>>t;for(int test=1;test<=t;test++)
#define pb push_back
#define nl cout<<"\n"
#define all(x) x.begin(),x.end()

template<class C> void min_self( C &a, C b ){ a = min(a,b); }
template<class C> void max_self( C &a, C b ){ a = max(a,b); }

const ll MOD = 998244353;
ll mod( ll n, ll m=MOD ){ n%=m,n+=m,n%=m;return n; }

const int MAXN = 1e5+5;
const int LOGN = 21;
const ll INF = 1e14;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};

template<class T1, class T2> void add( T1 &x, T2 y, ll m = MOD )
{
	x += y;
	if( x >= m )
		x -= m;
}

template<class T1, class T2> void sub( T1 &x, T2 y, ll m = MOD )
{
	x -= y;
	if( x < 0 )
		x += m;
}

vector<ll>pow10(200004), ones(200004);

template<class T> class LazySegmentTree
{
public:
    T N, sz;
    vector<T>tree, lazy;
    LazySegmentTree( T n )
    {
    	N = n;
    	sz = 4*N;
        tree.resize(sz,0);
        lazy.resize(sz,0);
    }
    LazySegmentTree( vector<T>&a )
    {
        N = a.size();
        sz = 4*N;
        tree.resize(sz,0);
        lazy.resize(sz,0);
        build(0,0,N-1,a);
    }
    T merge( int l, int r, int m, T x, T y )
    {
        // #warning
        // Fill merge function
        ll ans = mod( mod( pow10[r-m] * x ) + y );
        return ans;
    }
    void add( T &x, T y )
    {
    	x += y;
    }
    void build( int v, int l, int r, vector<T>&a )
    {
        if( l == r )
        {
            tree[v] = a[l];
            return;
        }
        int m = l + (r-l)/2;
        build( 2*v+1, l, m, a );
        build( 2*v+2, m+1, r, a );
        tree[v] = merge( l, r, m, tree[2*v+1], tree[2*v+2] );
    }
    void push( int l, int r, int m, int v )
    {
    	if( lazy[v] != 0 )
    	{
	    	tree[2*v+1] = mod( lazy[v] * ones[m-l+1] );
	    	lazy[2*v+1] = lazy[v];

	    	tree[2*v+2] = mod( lazy[v] * ones[r-m] );
	    	lazy[2*v+2] = lazy[v];
	    }

    	lazy[v] = 0;
    }
    void range( int v, int l, int r, int ql, int qr, T val )
    {
    	if( ql > qr )
    		return;
    	if( l == ql && qr == r )
    	{
    		tree[v] = mod( val * ones[r-l+1] );
    		lazy[v] = val;
    		return;
    	}
    	int m = l + (r-l)/2;
    	push(l, r, m, v);
    	range(2*v+1, l, m, ql, min(qr,m), val);
    	range(2*v+2, m+1, r, max(m+1,ql), qr, val);
    	tree[v] = merge( l, r, m, tree[2*v+1], tree[2*v+2] );
    }
    T query( int v, int l, int r, int ql, int qr )
    {
        // #warning
        if( qr < l || ql > r )
            return 0;
        if( ql <= l && r <= qr )
            return tree[v];
        int m = l + (r-l)/2;
        push(l, r, m, v);
        return merge( l, r, m, query(2*v+1,l,m,ql,qr), query(2*v+2,m+1,r,ql,qr) );
    }
    T get( int l, int r )
    {
        return query(0,0,N-1,l,r);
    }
    void range_modify( int l, int r, T val )
    {
    	range(0,0,N-1,l,r,val);
    }
    void modify( int pos, T val )
    {
    	range_modify(pos,pos,val);
    }
};


int main() 
{
	#ifdef gupta_samarth
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
	#endif
	fastio();

	pow10[0] = 1;
	for(int i=1;i<200001;i++)
		pow10[i] = mod( 10 * pow10[i-1] );

	ones[1] = 1;
	for(int i=2;i<200001;i++)
		ones[i] = mod( ones[i-1] + pow10[i-1] );

	int n,q;
	cin>>n>>q;

	LazySegmentTree<ll> st(n);
	st.range_modify(0,n-1,1ll);

	while(q--)
	{
		int l,r,d;
		cin>>l>>r>>d;

		st.range_modify(l-1,r-1,d);

		cout<<st.get(0,n-1),nl;
	}

	cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
	return 0;
}


Measured memory_bytes: 18768