#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <algorithm>
#include <utility>
#define llint long long
#define inf 1e18
#define rep(x, s, t) for(llint (x) = (s); (x) < (t); (x)++)
#define Rep(x, s, t) for(llint (x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))
#define mod 998244353

using namespace std;
typedef pair<llint, llint> P;

// range-add, range-min query

llint inv9;
llint beki[400005];
 
struct LazySegTree{
	int size;
	vector<llint> seg, delay;
	
	LazySegTree(){}
	LazySegTree(int size){
		this->size = size;
		seg.resize(1<<(size+1));
		delay.resize(1<<(size+1));
	}
	
	void init()
	{
		for(int i = 0; i < (1<<(size+1)); i++){
			seg[i] = 0;
			delay[i] = -1;
		}
	}
	
	void eval(int l, int r, int k)
	{
		//cout << "eval" << endl;
		if(delay[k] != -1){
			llint len = r-l+1;
			seg[k] = (beki[len] + mod - 1) % mod * delay[k] % mod * inv9 % mod;  //総和クエリのときは区間幅を乗じる必要がある
			if(l < r){
				delay[k*2] = delay[k];
				delay[k*2+1] = delay[k];
			}
			delay[k] = -1;
		}
		//cout << "eval" << endl;
		
	}
	
	void update(int i, llint val)
	{
		int l = 0, r = (1<<size)-1, k = 1;
		eval(l, r, k);
		for(int j = size-1; j >= 0; j--){
			k <<= 1;
			if(i & (1<<j)){
				k++;
				r = (l+r)/2;
			}
			else l = (l+r)/2+1;
			eval(l, r, k);
		}
		
		i += (1 << size);
		seg[i] = val;
		llint len = 1;
		while(i > 1){
			i /= 2;
			seg[i] = (seg[i*2] + beki[len]*seg[i*2+1]%mod) % mod;
			len *= 2;
		}
	}
	
	void add(int a, int b, int k, int l, int r, llint val)
	{
		eval(l, r, k);
		
		if(b < l || r < a) return;
		if(a <= l && r <= b){
			delay[k] = val;
			eval(l, r, k);
			return;
		}
		add(a, b, k*2, l, (l+r)/2, val);
		add(a, b, k*2+1, (l+r)/2+1, r, val);
		llint len = (r-l+1)/2;
		seg[k] = (seg[k*2] + beki[len]*seg[k*2+1]%mod) % mod;
	}
	void add(int a, int b, llint val){
		if(a > b) return;
		add(a, b, 1, 0, (1<<size)-1, val);
	}
 
	llint query(int a, int b, int k, int l, int r)
	{
		eval(l, r, k);
		
		if(b < l || r < a) return 0;
		if(a <= l && r <= b) return seg[k];
		llint lval = query(a, b, k*2, l, (l+r)/2);
		llint rval = query(a, b, k*2+1, (l+r)/2+1, r);
		llint len = (r-l+1)/2;
		return (lval + beki[len]*rval%mod) % mod;
		
	}
	llint query(int a, int b)
	{
		return query(a, b, 1, 0, (1<<size)-1);
	}
};

llint modpow(llint a, llint n)
{
	if(n == 0) return 1;
	if(n % 2){
		return ((a%mod) * (modpow(a, n-1)%mod)) % mod;
	}
	else{
		return modpow((a*a)%mod, n/2) % mod;
	}
}

llint n, Q;
llint l[200005], r[200005], d[200005];
LazySegTree seg(18);

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> Q;
	
	beki[0] = 1;
	for(int i = 1; i < 400005; i++) beki[i] = beki[i-1] * 10 % mod;
	inv9 = modpow(9, mod-2);
	
	seg.init();
	for(int i = 0; i < n; i++) seg.update(i, 1);
	
	llint l, r, d;
	for(int i = 1; i <= Q; i++){
		cin >> l >> r >> d;
		l = n - l, r = n - r;
		swap(l, r);
		seg.add(l, r, d);
		cout << seg.query(0, n-1) << "\n";
	}
	flush(cout);
	
	return 0;
}

Measured memory_bytes: 14564