//region Template
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
#ifdef LOCAL
#include <debug_prettyprint.hpp>
#else
#define debug(...) 42
#pragma GCC optimize("Ofast")
#pragma GCC target("avx")
#endif
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cout<<fixed<<setprecision(12);
#define FOR(i, n) for(int i=0; i<int(n); i++)
#define RNG(i, f, t) for(int i=int(f); i<=int(t); i++)
#define REV(i, f, t) for(int i=int(f); i>=int(t); --i)
#define ALL(v) (v).begin(), (v).end()
#define EXIT(answer) { cerr<<"EXIT #"<<__LINE__<<endl; cout<<answer<<endl; exit(0); }
#define sz(v) int(v.size())
template<int,typename T> struct MINMAX{ T val; MINMAX(T val) : val(val) {} };
template<typename T> MINMAX<1,T> MAX(T val) { return MINMAX<1,T>(val); };
template<typename T> MINMAX<2,T> MIN(T val) { return MINMAX<2,T>(val); };
template<typename T, typename U> inline T& operator|=(T &lhs, MINMAX<1,U> rhs) { return lhs = max(lhs, rhs.val); }
template<typename T, typename U> inline T& operator|=(T &lhs, MINMAX<2,U> rhs) { return lhs = min(lhs, rhs.val); }
template<typename T, typename U> istream& operator>>(istream& in, pair<T,U> &p) { in>>p.first>>p.second; return in; }
template<typename T> inline vector<T> READ(int n) { vector<T> vec(n); FOR(i,n) cin>>vec[i]; return vec; }
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T> >;
typedef signed long long int ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
//endregion


const int MAXN = 2e5+5;
const int MOD = 998244353;

struct PrefixSum {
    vl pre;
    void init(vi &vec) {
        pre.resize(vec.size());
        FOR(i,sz(vec))
            pre[i] = (vec[i] + (i==0 ? 0LL : pre[i-1])) % MOD;
    }
    ll range(int from, int to) { //from and to inclusive
        assert(from >= 0); assert(to >= from); assert(to < sz(pre));
        return ((pre[to] - (from==0 ? 0 : pre[from-1])) % MOD + MOD) %MOD;
    }
};

PrefixSum ps[11];



struct SegTree {
#define IS_LEAF(id) (id>=N)
#define LC (ID<<1)
#define RC (ID<<1|1)
    static const int INF = 1<<30;
    static const int H = 20; //TODO
    static const int N = 1<<H;
    int t[2*N]={0};
    int lazy[N];

private:
    void update(int ID) {
        assert(lazy[ID]<0);
        t[ID] = (t[LC] + t[RC]) %MOD;
    }

    void propagate(int ID, int L, int R) {
        if(IS_LEAF(ID) || lazy[ID]<0) return;
        if(!IS_LEAF(LC)) {
            lazy[LC] = lazy[ID];
            lazy[RC] = lazy[ID];
        }
        int mid = (L+R)>>1;
        t[LC] = ps[lazy[ID]].range(L, mid);
        t[RC] = ps[lazy[ID]].range(mid+1, R);
        lazy[ID] = -1;
    }
    
public:
    SegTree() {
        memset(lazy, 0xff, sizeof lazy);
    }

    void setRange(int from, int to, int val, int ID=1, int L=0, int R=N-1) {
        if(from<=L && to>=R) {
            if(!IS_LEAF(ID)) lazy[ID] = val;
            t[ID] = ps[val].range(L, R);
            return;
        }
        propagate(ID, L, R);
        int mid = (L+R)>>1;
        if(from<=mid) setRange(from, to, val, LC, L, mid);
        if(to>mid) setRange(from, to, val, RC, mid+1, R);
        update(ID);
    }

} st;

signed main() {
    FASTIO

    FOR(d,10) {
        ll mul=1;
        vi vec;
        FOR(i,MAXN) {
            vec.push_back(d*mul%MOD);
            mul = mul*10%MOD;
        }
        ps[d].init(vec);
    }

    int N,Q; cin>>N>>Q;
    st.setRange(0, N-1, 1);
    FOR(q,Q) {
        int l,r,d; cin>>l>>r>>d;
        l = N-l;
        r = N-r;
        st.setRange(r, l, d);
        cout<<st.t[1]<<endl;
    }

}

Measured memory_bytes: 32996