using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("7");
WillReturn.Add("1 2 1 0 2 1 1");
WillReturn.Add("1 2 8");
WillReturn.Add("2 3 9");
WillReturn.Add("2 4 10");
WillReturn.Add("2 5 -3");
WillReturn.Add("5 6 8");
WillReturn.Add("5 7 3");
//28
}
else if (InputPattern == "Input2") {
WillReturn.Add("20");
WillReturn.Add("0 2 0 1 2 1 0 0 3 0 1 1 1 1 0 0 3 0 1 2");
WillReturn.Add("4 9 583");
WillReturn.Add("4 6 -431");
WillReturn.Add("5 9 325");
WillReturn.Add("17 6 131");
WillReturn.Add("17 2 -520");
WillReturn.Add("2 16 696");
WillReturn.Add("5 7 662");
WillReturn.Add("17 15 845");
WillReturn.Add("7 8 307");
WillReturn.Add("13 7 849");
WillReturn.Add("9 19 242");
WillReturn.Add("20 6 909");
WillReturn.Add("7 11 -775");
WillReturn.Add("17 18 557");
WillReturn.Add("14 20 95");
WillReturn.Add("18 10 646");
WillReturn.Add("4 3 -168");
WillReturn.Add("1 3 -917");
WillReturn.Add("11 12 30");
//2184
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] mDArr;
// 隣接リスト
static Dictionary<long, List<long>> mToNodeListDict = new Dictionary<long, List<long>>();
static void Main()
{
List<string> InputList = GetInputList();
mDArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
// スコア[枝のハッシュ値]
var ScoreDict = new Dictionary<long, long>();
foreach (string EachStr in InputList.Skip(2)) {
SplitAct(EachStr);
long FromNode = wkArr[0];
long ToNode = wkArr[1];
long Score = wkArr[2];
if (mToNodeListDict.ContainsKey(FromNode) == false) {
mToNodeListDict[FromNode] = new List<long>();
}
if (mToNodeListDict.ContainsKey(ToNode) == false) {
mToNodeListDict[ToNode] = new List<long>();
}
mToNodeListDict[FromNode].Add(ToNode);
mToNodeListDict[ToNode].Add(FromNode);
ScoreDict[FromNode * 1000000 + ToNode] = Score;
ScoreDict[ToNode * 1000000 + FromNode] = Score;
}
// 枝をスコアの降順にソートしておく
foreach (long EachKey in mToNodeListDict.Keys.ToArray()) {
List<long> CurrList = mToNodeListDict[EachKey];
CurrList = CurrList.OrderByDescending(pX => ScoreDict[EachKey * 1000000 + pX]).ToList();
mToNodeListDict[EachKey] = CurrList;
}
List<JyoutaiDef> DFSResult = ExecDFS();
DFSResult.Reverse();
// 削除した辺のスコア合計の最大値[ノード][削除辺の数]なDP表
var DPDict = new Dictionary<long, Dictionary<long, long>>();
for (long I = 1; I <= mDArr.Length; I++) {
DPDict[I] = new Dictionary<long, long>();
DPDict[I][0] = 0;
}
// 根から葉に向かって配るDP
foreach (JyoutaiDef EachJyoutai in DFSResult) {
if (EachJyoutai.Node == 1) break;
long EdgeScore = ScoreDict[EachJyoutai.Node * 1000000 + EachJyoutai.ParentNode];
var CurrDPDict = new Dictionary<long, long>();
foreach (var EachPairFrom in DPDict[EachJyoutai.Node]) {
foreach (var EachPairTo in DPDict[EachJyoutai.ParentNode]) {
Action<long, long> UpdateAct = (pNewKey, pNewVal) =>
{
if (pNewKey > mDArr[EachJyoutai.ParentNode - 1]) {
return;
}
if (CurrDPDict.ContainsKey(pNewKey)) {
if (CurrDPDict[pNewKey] >= pNewVal) {
return;
}
}
CurrDPDict[pNewKey] = pNewVal;
};
// 間の辺を切断する場合
if (EdgeScore > 0) {
if (mDArr[EachJyoutai.Node - 1] > EachPairFrom.Key) {
UpdateAct(EachPairTo.Key + 1, EdgeScore + EachPairFrom.Value + EachPairTo.Value);
}
}
// 間の辺を切断しない場合
UpdateAct(EachPairTo.Key, EachPairFrom.Value + EachPairTo.Value);
}
}
var RemoveList = new List<long>();
foreach (var EachPair in CurrDPDict.OrderByDescending(pX => pX.Value).Skip(10)) {
RemoveList.Add(EachPair.Key);
}
RemoveList.ForEach(pX => CurrDPDict.Remove(pX));
DPDict[EachJyoutai.ParentNode] = CurrDPDict;
}
long Answer = 0;
foreach (var EachPair in DPDict[1]) {
Answer = Math.Max(Answer, EachPair.Value);
}
Console.WriteLine(Answer);
}
struct JyoutaiDef
{
internal long Node;
internal long ParentNode;
}
static List<JyoutaiDef> ExecDFS()
{
var WillReturn = new List<JyoutaiDef>();
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.Node = 1;
WillPush.ParentNode = -1;
Stk.Push(WillPush);
var VisitedSet = new HashSet<long>();
VisitedSet.Add(1);
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
WillReturn.Add(Popped);
if (mToNodeListDict.ContainsKey(Popped.Node)) {
foreach (long EachToNode in mToNodeListDict[Popped.Node]) {
if (VisitedSet.Add(EachToNode)) {
WillPush.Node = EachToNode;
WillPush.ParentNode = Popped.Node;
Stk.Push(WillPush);
}
}
}
}
return WillReturn;
}
}