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

const int64_t mod = 998244353ll;


vector<int64_t> ps, cps;

int64_t md(int64_t v) {
	return ((v%mod)+mod)%mod;
}

typedef int64_t ind_t; typedef int64_t data_t;
struct SegTree {
	// Base value is the "initial" value of any index.
	const data_t base_value = 0;
	// The identity value for f (0 for +, 1 for *, INF for min, etc).
	const data_t identity = 0;
	// left, right, node value, lazy delta, and left/right children.
	ind_t l, r;
	data_t val, delta = 0;
	unique_ptr<SegTree> children[2];
	SegTree(ind_t l, ind_t r) : l(l), r(r), val(base_value), delta(0) {}
	// Binary function. Max is given, min is the same. Commented additon shown.
	data_t f(data_t a, data_t b) { return (a+b)%mod; /*return a + b;*/ }
	data_t value() {
		if (delta != 0) {
			return md(md(cps[l]-cps[r+1])*delta);
		} else {
			return val;
		}
	}
	data_t middle() { return l == r-1 ? l : l + (r-l+1)/2; }
	void lazy_push() {
		ind_t mid = middle();
		if (delta != 0) {
			// Push delta into children.
			if (children[0] == nullptr)
				children[0] = unique_ptr<SegTree>(new SegTree(l, mid));
			children[0]->delta = delta;
			if (children[1] == nullptr)
				children[1] = unique_ptr<SegTree>(new SegTree(mid+1, r));
			children[1]->delta = delta;
			val  = value();
			delta = 0;
		}
	}
	data_t update(ind_t ql, ind_t qr, data_t v) {
		if (l == ql && r == qr) {
			delta = v;
			return value();
		}
		lazy_push();
		// init left and right.
		data_t left = base_value, right = base_value;
		ind_t mid = middle();
		if (children[0] != nullptr) left = children[0]->value();
		if (children[1] != nullptr) right = children[1]->value();
		// update
		if (ql <= mid) {
			if (children[0] == nullptr)
				children[0] = unique_ptr<SegTree>(new SegTree(l, mid));
			left = children[0]->update(ql, qr < mid ? qr : mid, v);
		}
		if (qr > mid) {
			if (children[1] == nullptr)
				children[1] = unique_ptr<SegTree>(new SegTree(mid+1, r));
			right = children[1]->update(ql < mid+1 ? mid+1 : ql, qr, v);
		}
		return val = f(left, right);
	}
	data_t query(ind_t ql, ind_t qr) {
		if (l == ql && r == qr)
			return value();
		lazy_push();
		data_t left = identity, right = identity;
		ind_t mid = middle();
		if (ql <= mid)
			if (children[0] == nullptr) left = base_value;
			else left = children[0]->query(ql, qr < mid ? qr : mid);
		if (qr > mid)
			if (children[1] == nullptr) right = base_value;
			else right = children[1]->query(ql < mid+1 ? mid+1 : ql, qr);
		
		return f(left, right);
	}
	void print_vals() {
		for (int i = l; i <= r; ++i)
			cout << query(i, i) << " ";
		cout << endl;
	}
	
	void print(int indent) {
		for (int i = 0 ; i < indent; ++i)
			cout << " ";
		cout << l << " " << r << " " << val << " " << delta << endl;
		if (children[0] != nullptr)
			children[0]->print(indent+2);
		if (children[1] != nullptr)
			children[1]->print(indent+2);
	}
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N, Q;
	cin >> N >> Q;
	int64_t num = 0, p = 1;
	ps.resize(N); cps.assign(N+5, 0);
	SegTree st(0, N+5);
	st.update(0, N, 1);
	for (int i = N-1; i >= 0; --i) {
		ps[i] = p;
		cps[i] += (cps[i+1]+p)%mod;
		cps[i] %= mod;
		num += p;
		num %= mod;
		p *= 10;
		p %= mod;
	}
	for (int i = 0; i < Q; ++i) {
		int64_t l, r, d;
		cin >> l >> r >> d;
		--l; --r;
		st.update(l, r, d);
		cout << st.query(0, N-1) << endl;
	}
}

Measured memory_bytes: 37588