#include <bits/stdc++.h>
#define f first
#define s second
#define fore(i,a,b) for(int i = (a), ThxMK = (b); i < ThxMK; ++i)
#define pb push_back
#define all(s) begin(s), end(s)
#define _ ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define sz(s) int(s.size())
#define ENDL '\n'
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
using namespace std;
typedef long double ld;
typedef long long lli;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<lli> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<ii> vii;
typedef vector<string> vs;
#define deb(x) cout << #x": " << (x) << endl;

lli gcd(lli a, lli b){return (b?gcd(b,a%b):a);}
lli lcm(lli a, lli b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
int popcount(lli x) { return __builtin_popcountll(x); }

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n){return uniform_int_distribution<int>(0, n-1)(rng);}

lli poww(lli a, lli b){
	lli res =1;
	while(b){ if(b&1) res = res * a; a = a*a; b/=2; }
	return res;
}
bool isPrime(lli x){
	if(x==1 or (x%2==0 and x>2))return 0;
	for(lli i = 3; i*i<=x; i+=2)if(x%i==0)return 0;
	return 1;
}
vi sieve(int N){
	vi m(N+1,0);
	vi primes(1,2);
	for(int i = 4; i<N; i+=2)m[i]=1;
	for(int i = 3; i*i<=N; i+=2)if(!m[i])for(int j = i*i; j<N; j+=i)m[j]=1;
	for(int i = 3; i<N; i+=2)if(!m[i])primes.pb(i);
	return primes;
}
int dx[4]={0,0,1,-1}, dy[4]={1,-1,0,0};
vvi graph(int n, int m, bool dir=1){
	vv(int,v,n+1,0);
	fore(i,0,m){
		int a,b; cin>>a>>b;
		v[a].pb(b);
		if(dir)v[b].pb(a);
	}
	return v;
}

// ---- コーディングはここから！ ('-')7
using uint=unsigned;
using ull=unsigned long long;
struct modinfo{uint mod,root;};
template<modinfo const&ref>
struct modular{
	static constexpr uint const &mod=ref.mod;
	static modular root(){return modular(ref.root);}
	uint v;
	//modular(initializer_list<uint>ls):v(*ls.bg){}
	modular(lli vv=0){s(vv%mod+mod);}
	modular& s(uint vv){
		v=vv<mod?vv:vv-mod;
		return *this;
	}
	modular operator-()const{return modular()-*this;}
	modular& operator+=(const modular&rhs){return s(v+rhs.v);}
	modular&operator-=(const modular&rhs){return s(v+mod-rhs.v);}
	modular&operator*=(const modular&rhs){
		v=ull(v)*rhs.v%mod;
		return *this;
	}
	modular&operator/=(const modular&rhs){return *this*=rhs.inv();}
	modular operator+(const modular&rhs)const{return modular(*this)+=rhs;}
	modular operator-(const modular&rhs)const{return modular(*this)-=rhs;}
	modular operator*(const modular&rhs)const{return modular(*this)*=rhs;}
	modular operator/(const modular&rhs)const{return modular(*this)/=rhs;}
	modular pow(int n)const{
		modular res(1),x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}
	modular inv()const{return pow(mod-2);}

	friend modular operator+(int x,const modular&y){
		return modular(x)+y;
	}
	friend modular operator-(int x,const modular&y){
		return modular(x)-y;
	}
	friend modular operator*(int x,const modular&y){
		return modular(x)*y;
	}
	friend modular operator/(int x,const modular&y){
		return modular(x)/y;
	}
	friend ostream& operator<<(ostream&os,const modular&m){
		return os<<m.v;
	}
	friend istream& operator>>(istream&is,modular&m){
		lli x;is>>x;
		m=modular(x);
		return is;
	}
	bool operator<(const modular&r)const{return v<r.v;}
	bool operator==(const modular&r)const{return v==r.v;}
	bool operator!=(const modular&r)const{return v!=r.v;}
	explicit operator bool()const{
		return v;
	}
};

extern constexpr modinfo base{998244353,3};
//extern constexpr modinfo base{1000000007,0};
//modinfo base{1,0};
using mint=modular<base>;
mint Z = mint(0);
template<class Monoid = int, class OperatorMonoid = Monoid >
struct Treap{
	 using F = function<Monoid(Monoid,OperatorMonoid)>;
	 using G = function<OperatorMonoid(OperatorMonoid,OperatorMonoid)>;
	 const Monoid M1;
	 const OperatorMonoid OM0;
	 const F f;
	 const G g;
	 struct node{
			 int pri;
			 Monoid key;
			 OperatorMonoid lazy;
			 node *l,*r;
			 int size;
			 node() = default;
			 node(Monoid key,OperatorMonoid OM):key(key),pri(rnd(INT_MAX)),size(1),l(nullptr),r(nullptr),lazy(OM){}
	 };
	 vector<node> nodes;
	 int ptr;

	 inline node* allocate(Monoid key){return &(nodes[ptr++] = node(key,OM0));}
	 Treap(int n,const F &f,const G &g,const Monoid M1,const OperatorMonoid OM0):
			 f(f),g(g),M1(M1),OM0(OM0),ptr(0),nodes(n){}
	 node* root = nullptr;
	 int size(node* t){return t!=nullptr ? t->size :0;}
	 mint sum(node *t){return t!=nullptr ? propagate(t),get<3>(t->key):Z;}
	 mint psum(node *t){return t!=nullptr ? propagate(t),get<4>(t->key):Z;}
	 void propagate(node* t){
			 if(t == nullptr) return;
			 if(t->lazy>0){
			 	t->key = f(t->key,t->lazy);
			 	if(t->l) t->l->lazy = g(t->l->lazy,t->lazy);
			 	if(t->r) t->r->lazy = g(t->r->lazy,t->lazy);
			}

			 t->lazy = OM0;
	 }

	 node* refresh(node* t){
			 propagate(t);
			 if(t == nullptr) return t;
			 t->size = 1 + size(t->l) + size(t->r);
			 auto &[a,v,p,s,ps] = t->key;
			 ps=p+psum(t->l)+psum(t->r);
			 s=p*v;
			 s=s+sum(t->l)+sum(t->r);
			 return t;
	 }
	 pair<node* ,node* > split(node* &t, Monoid k){
			 propagate(t);
			 if(!t) return {t,t};
			 else if(t->key < k){
					 auto p = split(t->r,k);
					 t->r = p.f;
					 return {refresh(t),p.s};
			 }
			 else{
					 auto p = split(t->l,k);
					 t->l = p.s;
					 return {p.f,refresh(t)};
			 }
	 }

	 node* merge(node* a,node* b){
			 propagate(a);
			 propagate(b);
			 if(!a or !b) return a ? a : b;
			 if(a->pri < b->pri){
					 a->r = merge(a->r,b);
					 return refresh(a);
			 }
			 else{
					 b->l = merge(a,b->l);
					 return refresh(b);
			 }
	 }

	 node* count(node* t,Monoid k){
			 propagate(t);
			 if(!t) return nullptr;
			 if(k < t->key) return count(t->l,k);
			 if(k == t->key) return t;
			 return count(t->r,k);
	 }

	 node* nth(node* t, int n){
			 propagate(t);
			 if(!t) return nullptr;
			 if(n <= size(t->l)) return nth(t->l,n);
			 if(n == size(t->l) + 1) return t;
			 return nth(t->r,n - size(t->l) - 1);
	 }

	 void del(node* &t){
			 propagate(t);
			 if(!t) return;
			 if(t->l) del(t->l);
			 if(t->r) del(t->r);
			 t = nullptr;
	 }

	 bool count(Monoid k){ return count(root,k) != nullptr;}

	 node* insert(Monoid k){
			 auto [l,r] = split(root,k);
			 auto c = allocate(k);
			 return root = merge(merge(l,c),r);
	 }

	 bool erase(Monoid k,Monoid k2){
			 node *f = count(root,k);
			 if(!f) return false;
			 node *a,*b,*c,*d;
			 split(root,k,a,b);
			 split(b,k2,c,d);
			 root = merge(a,d);
			 return true;
	 }

	 Monoid nth(int n){
			 n++;
			 node* ans = nth(root,n);
			 return ans ? ans->key : M1;
	 }

	 mint solve(int l, int r, int v){
			 auto [a,b] = split(root,Monoid(l,0,Z,Z,Z));
			 auto [c,d] = split(b,Monoid(r+1,0,Z,Z,Z));
			 if(c)c->lazy = OperatorMonoid(v);
			 root=merge(a,c);
			 root=merge(root,d);
			 return sum(root);
	 }
};

void solve(){
	int n; cin>>n;
	using t=tuple<int,int,mint,mint,mint>; // pos, val, pot, sum, sump
	auto f=[](t x, int a){
			t xx = x;
			get<1>(xx)=a;
			get<3>(xx)=a*get<4>(x);
			return xx;
	};
	auto g=[](int a, int b){return b;};
	Treap<t,int> tt(int(5e6),f,g,t(0,0,Z,Z,Z),0);
	vector<mint>p(n);
	p[0]=mint(1);
	fore(i,1,n)p[i]=p[i-1]*mint(10);
	reverse(all(p));
	fore(i,0,n)tt.insert(t(i+1,1,p[i],p[i],p[i]));
	int q; cin>>q;
	while(q--){
		int l,r,v; cin>>l>>r>>v;
		auto h =tt.solve(l,r,v);
		cout<<h<<ENDL;
	}
}

int main(){_
	//int t; cin>>t; while(t--)
	solve();
}


Measured memory_bytes: 277540