# include <iostream>
# include <algorithm>
#include <array>
# include <cassert>
#include <cctype>
#include <climits>
#include <numeric>
# include <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <tuple>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <bitset>
# include <complex>
# include <chrono>
# include <random>
# include <limits.h>
# include <unordered_map>
# include <unordered_set>
# include <deque>
# include <cstdio>
# include <cstring>
#include <stdio.h>
#include<time.h>
#include <stdlib.h>
#include <cstdint>
#include <cfenv>
#include<fstream>
//#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
long long MOD = 1000000000 + 7;
constexpr long long INF = numeric_limits<LL>::max();
const double PI = acos(-1);
#define fir first
#define sec second
#define thi third
#define debug(x) cerr<<#x<<": "<<x<<'\n'
typedef pair<LL, LL> Pll;
typedef pair<LL, pair<LL, LL>> Ppll;
typedef pair<LL, pair<LL, bitset<100001>>> Pbll;
typedef pair<LL, pair<LL, vector<LL>>> Pvll;
typedef pair<LL, LL> Vec2;
struct Tll { LL first, second, third; };
struct Fll { LL first, second, third, fourd; };
typedef pair<LL, Tll> Ptll;
#define rep(i,rept) for(LL i=0;i<rept;i++)
#define Mfor(i,mf) for(LL i=mf-1;i>=0;i--)
LL h, w, n, m, k, t, s, p, q, last, cnt, sum, ans, d[2000][2000], a[60000], b[60000];
string str, ss;
bool f[2000][2000];
char c;
int di[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
struct Edge { LL to, cost1, cost2; };
vector<Edge>vec[200000];
vector<LL>v;
map<LL, LL>ma;
multiset<LL>st;

void YN(bool f) {
	if (f)
		cout << "YES" << endl;
	else
		cout << "NO" << endl;
}
void yn(bool f) {
	if (f)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
}
vector<int> tsort(vector<vector<Edge>>g) {
	int n = g.size();
	enum { YET, VISITED, DONE };
	vector<int> res, flg(g.size(), YET);
	static const function<bool(int)> dfs = [&](int v) {
		flg[v] = VISITED;
		for (auto &e : g[v]) {
			int w = e.to;
			if (flg[w] != DONE && (flg[w] == VISITED || !dfs(w))) return false;
		}
		flg[v] = DONE;
		res.push_back(v);
		return true;
	};
	for (int i = 0; i < n; ++i)
		if (flg[i] == YET && !dfs(i)) return{};
	reverse(res.begin(), res.end());
	return res;
}

void dijk(vector<int>ts, vector<vector<Edge>>g) {
	rep(i,2000)rep(j,2000)
		d[i][j] = INF;
	d[0][0] = 0;
	priority_queue<Ppll, vector<Ppll>, greater<Ppll>> pq;
	pq.push(Ppll(d[0][0], Pll(0, 0))); // (cost,頂点番号) 
	while (!pq.empty()) {
		Ppll pp;
		pp = pq.top();
		LL cos = pp.first, vv[2] = { pp.second.first, pp.second.second }, x = 0;
		pq.pop();
		if (d[vv[0]][vv[1]] < pp.first)continue;
		if (vv[0]== vv[1]) {
			for (int i = 0; i < g[vv[0]].size(); i++) {
				if (d[vv[0]][vv[1]] + g[vv[0]][i].cost1 + g[vv[0]][i].cost2 < d[g[vv[0]][i].to][g[vv[0]][i].to]) {
					d[g[vv[0]][i].to][g[vv[0]][i].to] =
						d[vv[0]][vv[1]] + g[vv[0]][i].cost1 + g[vv[0]][i].cost2;
					pq.push(Ppll(d[g[vv[0]][i].to][g[vv[1]][i].to], Pll(g[vv[0]][i].to, g[vv[1]][i].to)));
				}
			}

			for (int i = 0; i < g[vv[0]].size(); i++) {
				for (int j = 0; j < g[vv[1]].size(); j++) {
					if (g[vv[0]][i].to == g[vv[1]][j].to)continue;

					if (d[vv[0]][vv[1]] + g[vv[0]][i].cost1 + g[vv[1]][j].cost1 < d[g[vv[0]][i].to][g[vv[1]][j].to]) {
						d[g[vv[0]][i].to][g[vv[1]][j].to] = d[vv[0]][vv[1]] + g[vv[0]][i].cost1 + g[vv[1]][j].cost1;
						pq.push(Ppll(d[g[vv[0]][i].to][g[vv[1]][j].to], Pll(g[vv[0]][i].to, g[vv[1]][j].to)));
					}
				}
			}

		}
		else {
			if (ts[vv[1]] < ts[vv[0]])x = 1;

			LL vt[2] = { vv[0],vv[1] };
			for (int i = 0; i < g[vv[x]].size(); i++) {
				vt[x] = g[vv[x]][i].to;
				if (d[vt[0]][vt[1]] > g[vv[x]][i].cost1 + d[vv[0]][vv[1]]) {
					d[vt[0]][vt[1]] = g[vv[x]][i].cost1 + d[vv[0]][vv[1]];
					pq.push(Ppll(d[vt[0]][vt[1]], Pll(vt[0], vt[1])));
				}
			}

		}
	}
}



int main() {
	cin >> n >> m;
	vector<vector<Edge>>g(n);
	rep(i, m) {
		LL x, y, z, w;
		cin >> x >> y >> z >> w;
		x--, y--;
		g[x].push_back(Edge{ y,z,w });
	}
	dijk(tsort(g),g);
	cout << (d[n - 1][n - 1]==INF?0:d[n-1][n-1]) << endl;
	return 0;
}



Measured memory_bytes: 63588