// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;



const int mxN = 2e5 + 5;

const ll INF = 1e18;

int N, M, ls[mxN], rs[mxN];

ll a[mxN], dp[mxN], tree[4 * mxN], lz[4 * mxN];

vector<int> st[mxN], en[mxN];



inline void add(ll* arr, int v, ll val) {

    arr[v] += val;

}



void lazy(int node) {

    add(lz, 2 * node, lz[node]);

    add(tree, 2 * node, lz[node]);

    add(lz, 2 * node + 1, lz[node]);

    add(tree, 2 * node + 1, lz[node]);

    lz[node] = 0;

}



void update(int l, int r, int ql, int qr, ll val, int node) {

    if (ql > qr) {

        return;

    }

    if (ql > r || qr < l) {

        return;

    }

    if (ql <= l && qr >= r) {

        add(tree, node, val);

        add(lz, node, val);

        return;

    }

    lazy(node);

    int mid = l + (r - l) / 2;

    update(l, mid, ql, qr, val, 2 * node);

    update(mid + 1, r, ql, qr, val, 2 * node + 1);

    tree[node] = max(tree[2 * node], tree[2 * node + 1]);

}



ll query(int l, int r, int ql, int qr, int node) {

    if (ql > qr) {

        return -INF;

    }

    if (ql > r || qr < l) {

        return -INF;

    }

    if (ql <= l && qr >= r) {

        return tree[node];

    }

    lazy(node);

    int mid = l + (r - l) / 2;

    return max(query(l, mid, ql, qr, 2 * node), query(mid + 1, r, ql, qr, 2 * node + 1));

}



int main() {

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);



    cin >> N >> M;

    for (int i = 0; i < M; i++) {

        cin >> ls[i] >> rs[i] >> a[i];

        st[ls[i]].push_back(i);

        en[rs[i]].push_back(i);

    }

    ll ans = 0;

    dp[0] = 0;

    for (int i = 1; i <= N; i++) {

        for (int idx : st[i]) {

            update(0, N, 0, i - 1, a[idx], 1);

        }

        dp[i] = query(0, N, 0, i - 1, 1);

        ans = max(ans, dp[i]);

        update(0, N, i, i, dp[i], 1);

        for (int idx : en[i]) {

            update(0, N, 0, ls[idx] - 1, -a[idx], 1);

        }

    }

    cout << ans;



    return 0;

}

// Optimized solution to the same problem (faster):
/**

 * code generated by JHelper

 * More info: https://github.com/AlexeyDmitriev/JHelper

 * @author rahdirigs

 */



#include <bits/stdc++.h>

using namespace std;

typedef long long ll;



template <typename T> T vec_max(vector<T>& a) {

	return *(max_element(a.begin(), a.end()));

}



struct segtreelz {

	int n;

	vector<ll> tree, lazy;



	explicit segtreelz(int _n) {

		n = _n;

		tree.resize(4 * _n, 0);

		lazy.resize(4 * _n, 0);

	}



	static void add(vector<ll> &v, int node, ll val) {

		v[node] += val;

	}



	void lz(int node) {

		add(lazy, 2 * node, lazy[node]);

		add(tree, 2 * node, lazy[node]);

		add(lazy, 2 * node + 1, lazy[node]);

		add(tree, 2 * node + 1, lazy[node]);

		lazy[node] = 0;

	}



	void update(int l, int r, int ql, int qr, ll val, int node) {

		if (ql > qr) return;

		if (ql > r || qr < l) return;

		if (ql <= l && qr >= r) {

			add(tree, node, val);

			add(lazy, node, val);

			return;

		}

		lz(node);

		int mid = l + (r - l) / 2;

		update(l, mid, ql, qr, val, 2 * node);

		update(mid + 1, r, ql, qr, val, 2 * node + 1);

		tree[node] = max(tree[2 * node], tree[2 * node + 1]);

	}



	ll query(int l, int r, int ql, int qr, int node) {

		if (ql > qr) return -1e18;

		if (ql > r || qr < l) return -1e18;

		if (ql <= l && qr >= r) return tree[node];

		lz(node);

		int mid = l + (r - l) / 2;

		return max(query(l, mid, ql, qr, 2 * node), query(mid + 1, r, ql, qr, 2 * node + 1));

	}



};



const ll INF = 1e18;



class TaskW {

public:

	void solve(std::istream& in, std::ostream& out) {

		int N, M;

		in >> N >> M;

		vector<int> ls(M), rs(M);

		vector<ll> a(M), dp(N + 1, -INF);

		vector<vector<int>> st(N + 1), en(N + 1);

		for (int i = 0; i < M; i++) {

			in >> ls[i] >> rs[i] >> a[i];

			st[ls[i]].push_back(i);

			en[rs[i]].push_back(i);

		}

		dp[0] = 0;

		segtreelz root = segtreelz(4 * N + 5);

		for (int i = 1; i <= N; i++) {

			for (int idx : st[i]) {

				root.update(0, N, 0, i - 1, a[idx], 1);

			}

			dp[i] = root.query(0, N, 0, i - 1, 1);

			root.update(0, N, i, i, dp[i], 1);

			for (int idx : en[i]) {

				root.update(0, N, 0, ls[idx] - 1, -a[idx], 1);

			}

		}

		out << vec_max(dp);

	}

};



int main() {

	ios_base::sync_with_stdio(false);

	cin.tie(0);

	TaskW solver;

	std::istream& in(std::cin);

	std::ostream& out(std::cout);

	solver.solve(in, out);

	return 0;

}


// Fastest known solution for this problem: