#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N = 600000;
int n;
int A[N], B[N], val[N];
int cnt[100][100];
vector<int> entries[100][100];
int ans;
vector<int> order;
int USED[20][20];
bool can_move(int a, int b) {
  if (cnt[a][b] <= USED[a][b]) return false;
  if (USED[a][b] == 2) return false;
  if (a == b) return false;
  return true;
}
int used[100];
int used_edge[20][20];
int eval(vector<int> v, int how_much, int for_sure) {
  int res = 0;
  sort(v.begin(), v.end());
  while (for_sure) {
    res += v.back();
    v.pop_back();
    --for_sure;
  }
  reverse(v.begin(), v.end());
  for (int i = 0; i < how_much; i++) {
    res += v[i];
  }
  return res;
}
void SOLVER() {
  for (int i = 1; i <= 4; i++) {
    used[i] = 0;
  }
  for (int i = 0; i < order.size(); i++) {
    used[order[i]] = 1;
  }
  int here = 0;
  for (int i = 1; i <= 4; i++) {
    if (used[i] == 0) continue;
    for (int j = i; j <= 4; j++) {
      int thold = 0;
      thold = entries[i][j].size() - USED[i][j];
      if (thold % 2 == 1 && i != j) --thold;
      here += eval(entries[i][j], thold, USED[i][j]);
    }
  }
  ans = max(ans, here);
}
void dfs(int v) {
  SOLVER();
  for (int i = 1; i <= 4; i++) {
    if (can_move(v, i) == 0) continue;
    USED[v][i]++;
    USED[i][v]++;
    order.push_back(i);
    dfs(i);
    order.pop_back();
    USED[v][i]--;
    USED[i][v]--;
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> A[i] >> val[i] >> B[i];
    cnt[A[i]][B[i]]++;
    if (A[i] != B[i]) cnt[B[i]][A[i]]++;
    entries[A[i]][B[i]].push_back(val[i]);
    if (A[i] != B[i]) entries[B[i]][A[i]].push_back(val[i]);
  }
  for (int i = 1; i <= 4; i++) {
    for (int j = 1; j <= 4; j++) {
      sort(entries[i][j].begin(), entries[i][j].end());
    }
  }
  ans = 0;
  for (int i = 1; i <= 4; i++) {
    order.push_back(i);
    dfs(i);
    order.pop_back();
  }
  cout << ans << endl;
  return 0;
}
