#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;

typedef vector<int> vi; 
typedef vector<ll> vl; 
typedef vector<db> vd; 
typedef vector<str> vs; 
typedef vector<pi> vpi;
typedef vector<pl> vpl; 
typedef vector<pd> vpd; 

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend() 
#define rsz resize
#define ins insert 
#define ft front() 
#define bk back()
#define pf push_front 
#define pb push_back
#define eb emplace_back 
#define lb lower_bound 
#define ub upper_bound 

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MX  = 2e5+5; 
const int MOD = 998244353;
const ll  INF = 1e18; 
const ld  PI  = acos((ld)-1);

const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count()); 

template<class T> bool ckmin(T& a, const T& b) { 
	return b < a ? a = b, 1 : 0; 
}
template<class T> bool ckmax(T& a, const T& b) { 
	return a < b ? a = b, 1 : 0; 
} 

constexpr int pct(int x) { return __builtin_popcount(x); } // number of ones 
constexpr int bits(int x) { return 31-__builtin_clz(x); } // floor(log2(x)) 
template<class T> T cdiv(T a, T b) { return a/b+!(a<0||a%b == 0); } // division of a by b rounded up, assumes b > 0 

int fstTrue(function<bool(int)> f, int lo, int hi) {
	hi++; assert(lo <= hi); // assuming f is increasing
	while (lo < hi) { // find first index such that f is true 
		int mid = (lo+hi)/2; 
		f(mid) ? hi = mid : lo = mid+1; 
	} 
	return lo;
}

template<class T> void remDup(vector<T>& v) { 
	sort(all(v)); v.erase(unique(all(v)),end(v)); 
}

// DEBUG
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << h; if (sizeof...(t)) cerr << ", ";
	DBG(t...); 
}
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)

// FILE I/O
void setIn(str S) { freopen(S.c_str(),"r",stdin); }
void setOut(str S) { freopen(S.c_str(),"w",stdout); }
void setIO(str S = "") {
	ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
	// cin.exceptions(cin.failbit); 
	// throws exception when do smth illegal
	// ex. try to read letter into int
	if (sz(S)) { setIn(S+".in"), setOut(S+".out"); } // for USACO
}
	
struct mi {
 	int v; explicit operator int() const { return v; } 
	mi() { v = 0; }
	mi(ll _v):v(_v%MOD) { v += (v<0)*MOD; }
};
mi& operator+=(mi& a, mi b) { 
	if ((a.v += b.v) >= MOD) a.v -= MOD; 
	return a; 
}
mi& operator-=(mi& a, mi b) { 
	if ((a.v -= b.v) < 0) a.v += MOD; 
	return a; 
}
mi operator+(mi a, mi b) { return a += b; }
mi operator-(mi a, mi b) { return a -= b; }
mi operator*(mi a, mi b) { return mi((ll)a.v*b.v); }
mi& operator*=(mi& a, mi b) { return a = a*b; }
mi pow(mi a, ll p) { assert(p >= 0); // asserts are important! 
	return p==0?1:pow(a*a,p/2)*(p&1?a:1); 
}
mi inv(mi a) { assert(a.v != 0); return pow(a,MOD-2); }
mi operator/(mi a, mi b) { return a*inv(b); }

int N,Q;
mi pw[MX],ac[MX];

mi prop(int l, int r) {
    if (l < 0 || r < 0 || l > r || l > N) return 0;
    if (l == 0) return ac[r];
    return ac[r]-ac[l-1];
}

template<class T, int SZ> struct Lazysum { 
	static_assert(pct(SZ) == 1); // SZ must be power of 2
	const T ID = 0; T comb(T a, T b) { return a+b; }
	T sum[2*SZ];
    int lazy[2*SZ]; 
	Lazysum() { F0R(i,2*SZ) sum[i] = ID, lazy[i] = -1; }
	void push(int ind, int L, int R) { /// modify values for current node
		if (lazy[ind] == -1) return;
		if (L != R) F0R(i,2) lazy[2*ind+i] = lazy[ind]; /// prop to children
        sum[ind] = prop(N-1-R,N-1-L)*lazy[ind]; // dependent on operation
		lazy[ind] = -1; 
	} // recalc values for current node
	void pull   (int ind) { sum[ind] = comb(sum[2*ind],sum[2*ind+1]); }
	void build() { ROF(i,1,SZ) pull(i); }
    void upd(int lo,int hi,int inc,int ind=1,int L=0, int R=SZ-1) {
		push(ind,L,R); if (hi < L || R < lo) return;
		if (lo <= L && R <= hi) { 
			lazy[ind] = inc; push(ind,L,R); return; }
		int M = (L+R)/2; upd(lo,hi,inc,2*ind,L,M); 
		upd(lo,hi,inc,2*ind+1,M+1,R); pull(ind);
	}
	T qsum(int lo, int hi, int ind = 1, int L = 0, int R = SZ - 1) {
		push(ind, L, R); if (lo > R || L > hi) return 0;
		if (lo <= L && R <= hi) return sum[ind];
		int M = (L + R) / 2;
		return qsum(lo, hi, 2 * ind, L, M) + qsum(lo, hi, 2 * ind + 1, M + 1, R);
	}
};

Lazysum<mi,1<<18> ST;

int32_t main() { 
	
	setIO();

    pw[0] = 1;
    FOR(i,1,MX) pw[i] = pw[i-1]*10;
    
    ac[0] = pw[0];
    FOR(i,1,MX) ac[i] = ac[i-1]+pw[i];

    cin >> N >> Q; 

    ST.build(); ST.upd(0,N-1,1);


    while(Q--) {
        int L,R,D; cin >> L >> R >> D; --L,--R;

        ST.upd(L,R,D);

        cout << ST.qsum(0,N-1).v << "\n";
    }   

}	

Measured memory_bytes: 9248