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

//.define
// #define FILE_IN_OUT
#define RET(_x)    return cout << (_x) << '\n', 0;
#define all(_obj)  (_obj).begin(), (_obj).end()
#define loop(_n)   for (int i = 0; i < (_n); ++i)
#define sz(_obj)   static_cast<int>((_obj).size())
#ifdef SHJ_LOCAL
#define debug(_x)  std::cerr << (#_x) << " = " << (_x) << '\n' << std::flush;
#else
#define debug(_x)  {}
#endif
#define endl "\n"
template<typename P, typename Q>
P CeilDiv(P _dividend, Q _divider) {
    return static_cast<P>((_dividend - 1LL + _divider) / _divider);
}
template<typename Tp>
inline void outarr(Tp _begin, Tp _end, const char* _delim = " ") {
    for (Tp current = _begin; current != _end; ++current) {
        std::cout << *current << _delim;
    }
    std::cout << '\n';
}

//.constant
using ll  = long long;
using pii = std::pair<int, int>;
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = static_cast<const int>(1e9 + 7);

//.data
constexpr int g_mod = 998244353;
constexpr int MAXN = 200005;

int Add(int x, int y) {
    x += y;
    return x < g_mod ? x : x - g_mod;
}

int Sub(int x, int y) {
    x -= y;
    return x >= 0 ? x : x + g_mod;
}

int Mul(int x, int y) {
    return int(1LL * x * y % g_mod);
}

int pow10[MAXN];
int pref[MAXN];

class SegmentTree {
public:
    struct Node {
        int Sum = 0;
        int Push = 0;
    };

    explicit SegmentTree(int n) : tree(n << 2), size(n) {
        Build(0, 0, size - 1);
    }

    void Update(int l, int r, int x) {
        UpdateRangeImpl(0, 0, size - 1, l, r, x);
    }

    int Query() const {
        return tree[0].Sum;
    }

private:
    int Left(int v) const {
        return (v << 1) + 1;
    }

    int Right(int v) const {
        return (v << 1) + 2;
    }

    int Combine(int lhs, int rhs, int rlen) {
        return Add(Mul(lhs, pow10[rlen]), rhs);
    }

    void UpdateVertex(int v, int rlen) {
        tree[v].Sum = Combine(tree[Left(v)].Sum, tree[Right(v)].Sum, rlen);
    }

    void Push(int v, int tl, int tr) {
        if (tree[v].Push != 0) {
            const int mid = (tl + tr) >> 1;
            tree[Left(v)].Sum = Mul(tree[v].Push, pref[mid - tl]);
            tree[Right(v)].Sum = Mul(tree[v].Push, pref[tr - mid - 1]);
            tree[Left(v)].Push = tree[Right(v)].Push = tree[v].Push;
            tree[v].Push = 0;
        }
    }

    void Build(int v, int tl, int tr) {
        if (tl == tr) {
            tree[v].Sum = 1;
            return;
        }
        const int mid = (tl + tr) >> 1;
        Build(Left(v), tl, mid);
        Build(Right(v), mid + 1, tr);
        UpdateVertex(v, tr - mid);
    }

    void UpdateRangeImpl(int v, int tl, int tr, int l, int r, int x) {
        if (l > r) {
            return;
        }
        if (tl == l && r == tr) {
            tree[v].Sum = Mul(x, pref[tr - tl]);
            tree[v].Push = x;
            return;
        }
        Push(v, tl, tr);
        const int mid = (tl + tr) >> 1;
        UpdateRangeImpl(Left(v), tl, mid, l, min(mid, r), x);
        UpdateRangeImpl(Right(v), mid + 1, tr, max(l, mid + 1), r, x);
        UpdateVertex(v, tr - mid);
    }

    vector<Node> tree;
    const int size;
};

//.code
int main() {
#ifdef FILE_IN_OUT
    std::ifstream cin ("input.txt",  std::ios::in);
    std::ofstream cout("output.txt", std::ios::out);
#else
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
#endif

    pref[0] = pow10[0] = 1;
    for (int i = 1; i < MAXN; ++i) {
        pow10[i] = Mul(10, pow10[i - 1]);
        pref[i] = Add(pref[i - 1], pow10[i]);
    }
    int n, q;
    cin >> n >> q;
    SegmentTree st(n);
    while (q--) {
        int l, r, d;
        cin >> l >> r >> d;
        --l; --r;
        st.Update(l, r, d);
        cout << st.Query() << endl;
    }

#ifdef FILE_IN_OUT
    cin.close();
    cout.close();
#endif
    return 0;
}

Measured memory_bytes: 11136