#include <iostream>
#include <vector>

constexpr int MOD = 998244353;
std::vector<long long> sum;

template<class T, class E, class F, class G, class H> class lazy_segment_tree {
	int N = 1; // the number of leaves
	std::vector<T> value;
	std::vector<E> lazy;
	std::vector<bool> lazy_empty;

	void lazy_evaluation(const int& k, const int& l, const int& r) {
		value[k] = to_value(value[k], lazy[k], l, r);
		if (l + 1 < r) {
			lazy[k * 2] = op_lazy(lazy[k * 2], lazy[k]);
			lazy[k * 2 + 1] = op_lazy(lazy[k * 2 + 1], lazy[k]);
			lazy_empty[k * 2] = lazy_empty[k * 2 + 1] = false;
		}
		lazy[k] = id_lazy;
		lazy_empty[k] = true;
	}

public :
	const F op_value;
	const G op_lazy;
	const H to_value;
	const T id_value;
	const E id_lazy;

	lazy_segment_tree(const std::vector<T>& a, const F& f, const G& g, const H& h, const T& t, const E& e)
	: op_value(f), op_lazy(g), to_value(h), id_value(t), id_lazy(e) {
		int sz = a.size();
		while (N < sz) N *= 2;
		value.resize(N * 2, id_value);
		lazy.resize(N * 2, id_lazy);
		lazy_empty.resize(N * 2, true);
		for (int i = 0; i < sz; i++) value[N + i] = a[i];
		for (int i = N - 1; i > 0; i--) value[i] = op_value(value[i * 2], value[i * 2 + 1]);
	}
	lazy_segment_tree(const int& sz, const F& f, const G& g, const H& h, const T& t, const E& e)
	: op_value(f), op_lazy(g), to_value(h), id_value(t), id_lazy(e) {
		while (N < sz) N *= 2;
		value.resize(N * 2, id_value);
		lazy.resize(N * 2, id_lazy);
		lazy_empty.resize(N * 2, true);
	}

	void range_update(const int& L, const int& R, const E& e, const int& k = 1, const int& l = 0, int r = -1) {
		if (L == R) return;
		if (r == -1) r = N;
		if (L <= l && r <= R) {
			lazy[k] = op_lazy(lazy[k], e);
			lazy_empty[k] = false;
			lazy_evaluation(k, l, r);
		} else {
			if (!lazy_empty[k]) lazy_evaluation(k, l, r);
			int mid = (l + r) / 2;
			if (L < mid) range_update(L, R, e, k * 2, l, mid);
			else if (!lazy_empty[k * 2]) lazy_evaluation(k * 2, l, mid);
			if (mid < R) range_update(L, R, e, k * 2 + 1, mid, r);
			else if (!lazy_empty[k * 2 + 1]) lazy_evaluation(k * 2 + 1, mid, r);
			value[k] = op_value(value[k * 2], value[k * 2 + 1]);
		}
	}

	T range_fold(const int& L, const int& R, const int& k = 1, const int& l = 0, int r = -1) {
		if (r == -1) r = N;
		if (!lazy_empty[k]) lazy_evaluation(k, l, r);
		if (L <= l && r <= R) return value[k];
		int mid = (l + r) / 2;
		if (R <= mid) return range_fold(L, R, k * 2, l, mid);
		if (mid <= L) return range_fold(L, R, k * 2 + 1, mid, r);
		return op_value(range_fold(L, R, k * 2, l, mid), range_fold(L, R, k * 2 + 1, mid, r));
	}

	T operator[](const int& k) const {
		T ret = value[N + k];
		for (int i = N + k; i > 0; i /= 2) {
			if (!lazy_empty[i]) ret = to_value(ret, lazy[i], k, k + 1);
		}
		return ret;
	}
};

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
 
	int N, Q;
	std::cin >> N >> Q;
	std::vector<long long> a(N, 1);
	for (int i = N - 2; i >= 0; i--) a[i] = a[i + 1] * 10 % MOD;
 
	sum.resize(N + 1, 0);
	for (int i = N - 1; i >= 0; i--) sum[i] = (sum[i + 1] + a[i]) % MOD;
 
	auto f = [] (long long a, long long b) {return (a + b) % MOD;};
	auto g = [] (int a, int b) {return b;};
	auto h = [&] (long long a, int b, int l, int r) {
		long long ret = sum[l] - sum[r];
		if (ret < MOD) ret += MOD;
		return ret * b % MOD;
	};
	lazy_segment_tree<long long, int, decltype(f), decltype(g), decltype(h)> sg(a, f, g, h, 0, 1);
 
	while (Q--) {
		int L, R, D;
		std::cin >> L >> R >> D;
		sg.range_update(L - 1, R, D);
		std::cout << sg.range_fold(0, N) << '\n';
	}
}

Measured memory_bytes: 12664