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

//const unsigned int mod = 1000000007;
const unsigned int mod = 998244353;

struct mint {
	unsigned int x;
	mint():x(0) {}
	mint(int64_t x_) {
		int64_t v = int64_t(x_ % mod);
		if(v < 0) v += mod;
		x = (unsigned int)v;
	}
	static mint row(int v) {
		mint v_;
		v_.x = v;
		return v_;
	}
	mint operator-() const { return mint(-int64_t(x));}
	mint& operator+=(const mint a) {
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += mod-a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator*=(const mint a) {
		uint64_t z = x;
		z *= a.x;
		x = (unsigned int)(z % mod);
		return *this;
	}
	mint operator+(const mint a) const { return mint(*this) += a;}
	mint operator-(const mint a) const { return mint(*this) -= a;}
	mint operator*(const mint a) const { return mint(*this) *= a;}
	friend bool operator==(const mint &a, const mint &b) {return a.x == b.x;}
	friend bool operator!=(const mint &a, const mint &b) {return a.x != b.x;}
	mint &operator++() {
		x++;
		if(x == mod) x = 0;
		return *this;
	}
	mint &operator--() {
		if(x == 0) x = mod;
		x--;
		return *this;
	}
	mint operator++(int) {
		mint result = *this;
		++*this;
		return result;
	}
	mint operator--(int) {
		mint result = *this;
		--*this;
		return result;
	}
	mint pow(int64_t t) const {
		mint x_ = *this, r = 1;
		while(t) {
			if(t&1) r *= x_;
			x_ *= x_;
			t >>= 1;
		}
		return r;
	}
	//for prime mod
	mint inv() const { return pow(mod-2);}
	mint& operator/=(const mint a) { return *this *= a.inv();}
	mint operator/(const mint a) {return mint(*this) /= a;}
};

istream& operator>>(istream& is, mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

template <class S, class F>
struct SegTreeLP {
  using FX = function<S(S, S, int)>;
  using FA = function<S(S, F, int)>;
  using FF = function<F(F, F)>;
  int n, _n, log, _log;
  FX fx;
  FA fa;
  FF ff;
  const S es;
  const F ef;
  vector<S> dat;
  vector<F> laz;
  SegTreeLP(int n_, FX fx_, FA fa_, FF ff_, S es_, F ef_)
    : fx(fx_), fa(fa_), ff(ff_), es(es_), ef(ef_), n(1), _n(n_), log(__builtin_ctz(n_)), _log(0) {
      while(n_ > n) {
        n <<= 1;
        _log++;
      }
      dat.assign(n*2-1, es);
      laz.assign(n*2-1, ef);
      build();
  }
  SegTreeLP(vector<S> &v, FX fx_, FA fa_, FF ff_, S es_, F ef_)
    : fx(fx_), fa(fa_), ff(ff_), es(es_), ef(ef_), n(1), _n(int(v.size())), log(__builtin_ctz(_n)), _log(0) {
      while(_n > n) {
        n <<= 1;
        _log++;
      }
      dat.assign(n*2-1, es);
      laz.assign(n*2-1, ef);
      copy(v.begin(), v.end(), dat.begin()+n-1);
      build();
  }
  inline int chld(int k) {return k*2+1;}
  inline int chrd(int k) {return k*2+2;}
  void set(int i, S s) {dat[i+n-1] = s;}
  void build() {
    for(int k = n-2; k >= 0; k--) dat[k] = fx(dat[chld(k)], dat[chrd(k)], 1<<(_log-32+__builtin_clz(k+1)));
  }
  void eval(int k, int len) {
    if(laz[k] == ef) return;
    if(k < n-1) {
      laz[chld(k)] = ff(laz[chld(k)], laz[k]);
      laz[chrd(k)] = ff(laz[chrd(k)], laz[k]);
    }
    dat[k] = fa(dat[k], laz[k], len);
    laz[k] = ef;
  }
  void update(int a, int b, F x, int k, int l, int r) {
    eval(k, r-l);
    if(a <= l and r <= b) {
      laz[k] = ff(laz[k], x);
      eval(k, r-l);
    }
    else if(a < r and l < b) {
      update(a, b, x, chld(k), l, (l+r)>>1);
      update(a, b, x, chrd(k), (l+r)>>1, r);
      dat[k] = fx(dat[chld(k)], dat[chrd(k)], (r-l)>>1);
    }
  }
  void update(int a, int b, F x) {update(a, b, x, 0, 0, n);}
  S query(int a, int b, int k, int l, int r) {
    eval(k, r-l);
    if(r <= a or b <= l) return es;
    else if(a <= l and r <= b) return dat[k];
    else {
      S vl = query(a, b, chld(k), l, (l+r)>>1);
      S vr = query(a, b, chrd(k), (l+r)>>1, r);
      return fx(vl, vr, (r-l)>>1);
    }
  }
  S query(int a, int b) {return query(a, b, 0, 0, n);}
  //debug
  inline const S operator[](const int i) {return query(i, i+1);}
  void print() {for(int i = 0; i < n; i++) cout << (*this)[i] << (i == n-1?'\n':' ');}
};

#define N 200100

mint pw[N], _pw[N];
const mint _ = mint(9).inv();

int main() {
	pw[0] = 1;
	for(int i = 0; i < N-1; i++) pw[i+1] = pw[i]*10;
	_pw[0] = 1;
	_pw[1] = pw[1].inv();
	for(int i = 1; i < N-1; i++) _pw[i+1] = _pw[i]*_pw[1];
	int n, q;
	scanf("%d%d", &n, &q);
	SegTreeLP<mint, mint> seg(n, [&](mint a, mint b, int x)->mint{return a*pw[x]+b;}, [&](mint a, mint b, int x)->mint{return (pw[x]-1)*_*b;}, [](mint a, mint b)->mint{return b;}, mint(1), mint(100));
	while(q--) {
		int l, r, d;
		scanf("%d%d%d", &l, &r, &d);
		seg.update(l-1, r, d);
		printf("%u\n", ((seg.query(0, seg.n)-(pw[seg.n-n]-1)*_)*_pw[seg.n-n]).x);
	}
}

Measured memory_bytes: 9040