#define _USE_MATH_DEFINES
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
#include <iomanip>	
#include <deque>
#include <set>
#define rep(i,a,b) for(int i=a;i<b;++i)
#define rrep(i,a,b) for(int i=a;i>=b;--i)
#define fore(i,a) for(auto &i:a)
#define INF INT_MAX/2;
typedef long long ll;
using namespace std;
using vi = vector<int>;
using vll = vector<ll>;
ll mod = 1e9 + 7;
//ll llmax = 10000000000000000000ll;
using namespace std;
using Graph = vector<vector<int>>;
Graph G;
const int AMAX = 100000;
//四方向への移動ベクトル
const int dx[4] = { 1,0,-1,0 };
const int dy[4] = { 0,1,0,-1 };
/*
//入力
int H, W;
vector<string> field;

//探索
bool seen[510][510];	// seen[h][w] := マス(h,w)が検知済みかどうか

void dfs(int h, int w)
{
	seen[h][w] = true;

	//四方向を検索
	for (int dir = 0; dir < 4; dir++)
	{
		int nh = h + dx[dir];
		int nw = w + dy[dir];

		//場外アウトしたり、移動先が壁の場合はスルー
		if (nh < 0 || nh >= H || nw < 0 || nw <= W)continue;
		if (field[nh][nw] == '#')continue;

		//移動先が探索済みの場合
		if (seen[nh][nw])continue;

		//再帰的に探索
		dfs(nh, nw);
	}
}

/*int cnt_digit(ll N)
{
	int digit = 0;

	while (N > 0)
	{
		N /= 10;
		digit++;
	}
	return digit;
}




int n;
vll a;

ll solve(bool isp)
{
	ll sum = 0ll;
	ll ret = 0ll;

	for (int i = 0; i < n; i++)
	{
		sum += a[i];
		if (isp and sum <= 0)
		{
			ret += -sum + 1;
			sum = 1ll;
		}
		if (not isp and sum >= 0)
		{
			ret += sum + 1;
			sum = -1ll;
		}
		isp ^= 1;
	}
	return ret;
}


vector<bool> seen;
void dfs(const Graph & G, int v)
{
	seen[v] = true;	//v を訪問済みにする

	// vから行ける各頂点 next_vについて
	for (auto next_v : G[v])
	{
		if (seen[next_v])continue;	//next_vが探索済みだったらスルー
		dfs(G, next_v);//再帰的に探索
	}
}


 * 最大公約数計算
 
ll gcd(ll a, ll b)
{
	if (b == 0) {
		return a;
	}
	else {
		return gcd(b, a % b);
	}
}

ll lcm(ll a, ll b)
{
	ll g = gcd(a, b);

	return a / g * b;
}

struct union_find
{
	vector<int> par, r;
	union_find(int n)
	{
		par.resize(n);
		r.resize(n);
		init(n);
	}


void init(int n)
{
	for (int i = 0; i < n; i++) par[i] = i;
	for (int i = 0; i < n; i++) r[i] = 0;
}

int find(int x)
{
	if (par[x] == x)return x;
	else return find(par[x]);
}

void unite(int x, int y)
{
	x = find(x);
	y = find(y);

	if (r[x] < r[y])
	{
		par[x] = y;
	}
	else
	{
		par[y] = x;
		if (r[x] == r[y])
		{
			r[x]++;
		}
	}
}

bool same(int x, int y)
{
	return find(x) == find(y);
}

};


string SS, T;
string solve()
{
	
	int N = SS.length();
	int M = T.length();
	set<string> ans;
	for (int R = N; R >= M; R--)
	{
		int L = R - M;

		int ok = 1;
		for (int j = 0; j < M; j++)
		{
			if (SS[L + j] != '?' && SS[L + j] != T[j])
			{
				ok = 0;
			}

			if (ok)
			{
				string S;
				for (int i = 0; i < N;i++) S += SS[i];
				for (int i = 0; i < M; i++) S[L+i] = T[i];
				for (int i = 0; i < N; i++) if (S[i] == '?')S[i] = 'a';
				ans.insert(S);
			}
		}
		
	}
	if (ans.size() == 0)return "UNRESTORABLE";
	return *(ans.begin());

}
*/

int N, M, Q;
vector<int> a, b, c, d;
int ans;
void dfs(vector<int>A) {
	if (A.size() == N+1) {
		int now = 0;
		rep(i, 0, Q) {
			if (A[b[i]] - A[a[i]] == c[i])now += d[i];

		}
		ans = max(ans, now);
		return;
	}
	A.push_back(A.back());
	while (A.back() <= M) {
		dfs(A);
		A.back()++;
	}

}

int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
	
	cin  >> N >> M >> Q;
	a = b = c = d = vector <int>(Q);
	rep(i, 0,Q) {
		
		cin >> a [i]>> b[i] >> c[i] >> d[i];

	}
	dfs(vector<int>(1,1));

	cout << ans << endl;

}


/*void dfs(int v,vector<bool> &seen, int &res) 
{
	bool end = true;
	for (int i = 0; i < seen.size(); i++)
	{
		if (!seen[i] && i != v)
		{
			end = false;
		}
	}
	if (end)
	{
		res++;
		return;
	}

	seen[v] = true;
	for (auto nv : G[v])
	{
		if (seen[nv])
		{
			continue;
		}
		dfs(nv, seen, res);
	}
		seen[v] = false;
	


}

int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);

	cin >> H >> W;
	field.resize(H);
	for (int h = 0; h < H; h++)
	{
		cin >> field[h];

		//s と gのマスを特定する
		int sh, sw, gh, gw;
		for (int h = 0; h < H; h++)
		{
			for (int w = 0; w < H; w++)
			{
				if (field[h][w] == 's')sh = h, sw = w;
				if (field[h][w] == 'g')gh = h, gw = w;
			}
		}

		//探索開始
		memset(seen, 0, sizeof(seen)); //seen 配列全体をfalseに初期化
		dfs(sh, sw);

		//結果
		if (seen[gh][gw])cout << "Yes" << endl;
		else cout << "No" << endl;
	}

	return 0;

}


int main()
{
	int N, M; cin >> N >> M;
	G.assign(N, vector<int>());
	for (int i = 0; i < M; i++)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	vector<bool> seen(N, false);
	int res = 0;
	dfs(0, seen, res);
	cout << res << endl;
}
*/

/*
{
	//int menseki[100][100];
	int tate[110];
	int yoko[110];
	int hantei[110];
	int W, H, N;
	cin >> W >> H >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> yoko[i] >> tate[i] >> hantei[i];
	}
	int x_max = 0;
	int y_max = 0;
	for (int i = 0; i < N; i++)
	{
		if (hantei[i] == 1)
		{
			if (x_max <= yoko[i])
			{
				x_max = yoko[i];
			}
		}
		if (hantei[i] == 2)
		{
			if (yoko[i] <= W)
			{
				W = yoko[i];
			}

		}
		if (hantei[i] == 3)
		{
			if (y_max <= tate[i])
			{
				y_max = tate[i];
			}
		}
		if (hantei[i] == 4)
		{
			if (tate[i] <= H)
			{
				H = tate[i];
			}

		}
	}

	cout << (W - x_max) * (H - y_max) << endl;
}
{
vector<vector<int>> data(3, vector<int>(3));

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cin >> data.at(i).at(j);
		}
	}
	bool flag = true;
	string ans = "No";
	for (int i = 0; i <= 100; i++)
	{
		int a[3] = { 0 };
		int b[3] = { 0 };

		a[0] = i;
		for (int j = 0; j < 3; j++)
		{
			b[j] = data.at(0).at(j) - a[0];
		}

		for (int j = 1; j < 3; j++)
		{
			a[j] = data.at(j).at(0) - b[0];
		}
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				if (data.at(i).at(j)  != a[i] + b[j])
				{
					flag = false;
					break;
				}
			}
		}
		if (flag) ans = "Yes";
	}

	cout << ans << endl;

}

*/

//vector<vector<int>> data(10, vector<int>(10));


Measured memory_bytes: 3628