#include <bits/stdc++.h>

template <class M, class E, class F = std::function<M(M, M)>, class A = std::function<M(M, E)>, class G = std::function<E(E, E)>>
class LazySegmentTree {
private:
  M* data;
  E* lazy;
  F op;
  G cp;
  A act;
  M e;
  E id;
  int sz;

  void propagate(int index) {
    if (lazy[index] == id) return;
    lazy[index << 1] = cp(lazy[index << 1], lazy[index]);
    lazy[(index << 1) | 1] = cp(lazy[(index << 1) | 1], lazy[index]);
    data[index] = act(data[index], lazy[index]);
    lazy[index] = id;
  }

  void propagate_topdown(int index) {
    int h = 0;
    for (int i = 1; i < index; i <<= 1) ++h;
    for (int i = h; i; i--) propagate(index >> i); 
  }

  void recalc(int index) { while (index >>= 1) data[index] = op(act(data[index << 1], lazy[index << 1]), act(data[(index << 1) | 1], lazy[(index << 1) | 1])); }

public:
  LazySegmentTree(int sz, const F& op, const A& act, const G& cp, const M& e, const E& id) : op(op), act(act), cp(cp), e(e), id(id), sz(sz) {
    data = new M[sz << 1];
    lazy = new E[sz << 1];
    for (int i = 0; i < (sz << 1); i++) data[i] = e;
    for (int i = 0; i < (sz << 1); i++) lazy[i] = id;
  }

  void update(int left, int right, const E& x) {
    if (left < 0) left = 0;
    if (right > sz) right = sz;
    left += sz; right += sz;

    propagate_topdown(left);
    propagate_topdown(right - 1);

    for (int l = left, r = right; l < r; l >>= 1, r >>= 1) {
      if (l & 1) {
        lazy[l] = cp(lazy[l], x);
        ++l;
      }
      if (r & 1) {
        --r;
        lazy[r] = cp(lazy[r], x);
      }
    }

    recalc(left);
    recalc(right - 1);
  }

  M query(int left, int right) {
    if (left < 0) left = 0;
    if (right > sz) right = sz;
    left += sz; right += sz;

    propagate_topdown(left);
    propagate_topdown(right - 1);

    M l = e, r = e;

    for (; left < right; left >>= 1, right >>= 1) {
      if (left & 1) {
        l = op(l, act(data[left], lazy[left]));
        ++left;
      }
      if (right & 1) {
        --right;
        r = op(act(data[right], lazy[right]), r);
      }
    }

    return op(l, r);
  }

  ~LazySegmentTree() {
    delete[] data;
    delete[] lazy;
  }
  
  void debug() {
    for (int i = sz; i < sz + sz; i++) {
      std::cout << lazy[i].num << ' ' << lazy[i].d << ' ';
    }
    std::cout << std::endl;
  }
};

class ModInt {
private:
  long long number;

public:
  static constexpr long long mod = 998244353;

  constexpr ModInt(const ModInt& x) : number(x.number) {};

  constexpr ModInt(const long long number = 0) : number((mod + number) % mod) {}

  constexpr long long get() const {
    return number;
  }

  constexpr ModInt& operator=(const ModInt& rhs) & {
    number = rhs.number;
    return *this;
  }

  constexpr ModInt operator+() const {
    return ModInt(*this);
  }

  constexpr ModInt operator-() const {
    return ModInt(mod - number);
  }

  constexpr ModInt& operator+=(const ModInt& rhs) {
    number += rhs.number;
    if (number >= mod) number -= mod;
    return *this;
  }

  constexpr ModInt& operator-=(const ModInt& rhs) {
    number -= rhs.number;
    if (number < 0) number += mod;
    return *this;
  }

  constexpr ModInt& operator*=(const ModInt& rhs) {
    (number *= rhs.number) %= mod;
    return *this;
  }

  constexpr ModInt& operator/=(const ModInt& rhs) {
    (*this) *= rhs.inverse();
    return *this;
  }

  constexpr ModInt inverse() const {
    long long a = number, m = mod, u = 1, v = 0;

    while (m) {
      long long t = a / m;
      a -= t * m;
      u -= t * v;

      a ^= m; m ^= a; a ^= m;
      u ^= v; v ^= u; u ^= v;
    }

    return ModInt(u);
  }

  constexpr ModInt& operator++() {
    return *this += 1;
  }

  constexpr ModInt& operator--() {
    return *this -= 1;
  }

  constexpr ModInt operator++(int) {
    ModInt ret = *this;
    ++(*this);
    return ret;
  }

  constexpr ModInt operator--(int) {
    ModInt ret = *this;
    --(*this);
    return ret;
  }
};

constexpr ModInt operator+(const ModInt& lhs, const ModInt& rhs) {
  return ModInt(lhs) += rhs;
}

constexpr ModInt operator-(const ModInt& lhs, const ModInt& rhs) {
  return ModInt(lhs) -= rhs;
}

constexpr ModInt operator*(const ModInt& lhs, const ModInt& rhs) {
  return ModInt(lhs) *= rhs;
}

constexpr ModInt operator/(const ModInt& lhs, const ModInt&rhs) {
  return ModInt(lhs) /= rhs;
}

constexpr ModInt operator^(const ModInt& lhs, const long long& rhs) {
  long long b = lhs.get(), e = rhs, y = 1, mod = lhs.mod;
  bool inv = e < 0;
  if (inv) e = -e;

  while (e) {
    if(e & 1) (y *= b) %= mod;

    (b *= b) %= mod;
    e >>= 1;
  }

  return (inv ? ModInt(y).inverse() : ModInt(y));
}

std::istream& operator>>(std::istream& is, ModInt& x) {
  long long in;
  is >> in;
  x = in;
  return is;
}

std::ostream& operator<<(std::ostream& os, const ModInt& x) {
  os << x.get();
  return os;
}

const int MOD = 998244353;

using namespace std;

struct M {
  ModInt num;
  ModInt d;
  M() : num(0), d(0) {}
  M(ModInt num, ModInt d) : num(num), d(d) {}
};

bool operator==(const M& a, const M& b) {
  return a.num.get() == b.num.get() && a.d.get() == b.d.get();
}

struct E {
  int num;
  long long d;
  E() : num(0), d(MOD) {}
  E(int num) : num(num), d(MOD) {}
  E(int num, long long d) : num(num), d(d) {}
};

bool operator==(const E& f, const E& g) {
  return f.num == g.num && f.d == g.d;
}

int main() {
  int N, Q;
  cin >> N >> Q;
  
  auto op = [](const M& a, const M& b) {
    return M(a.num + b.num, a.d + b.d);
  };
  
  auto act = [](const M& x, const E& f) {
    if (f.num == 0 && f.d == MOD) return x;
    else if(f.d == MOD) return M(x.d * f.num, x.d);
    else return M(f.d * f.num % MOD, f.d);
  };
  
  auto cp = [](const E& f, const E& g) {
    if (g.num == 0 && g.d == MOD) return f;
    else if (g.d == MOD) return E(g.num, f.d);
    else return g;
  };
    
  LazySegmentTree<M, E, decltype(op), decltype(act), decltype(cp)> segTree(N, op, act, cp, M(0, 0), E(0, MOD));
  
  segTree.update(N - 1, N, E(1, 1));
  for (int i = N - 1; i > 0; i--) {
    auto s = segTree.query(i, i + 1);
    segTree.update(i - 1, i, E(0, (s.d * 10).get()));
    segTree.update(i - 1, i, E(1));
  }
  
  while (Q--) {
    int L, R, D;
    cin >> L >> R >> D;
    segTree.update(L - 1, R, D);
    cout << segTree.query(0, N).num << endl;
  }
  
  return 0;
}

Measured memory_bytes: 15648