import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Ponyless_Bon {

	public static class Node
	{
		public ArrayList<Node> children;
		public int c, d;					// used for penalty c*(d-t)^2
		
		public long[] process(int startt, int numt)
		{
			if (children.size() == 0) {				// leaf
				long[] costs = new long[numt];
				for(int i=0; i<numt; i++) {
					long diff = d-(startt+i);
					costs[i] = c*diff*diff;
				}
				return costs;
			}
			else {
				int n = children.size();
				long [][] carray = new long[n][];
				int i=0;
				for(Node child : children) {
					carray[i] = child.process(startt+1, numt+n-1);
					i++;
				}
				long [] costs = new long[numt];
				for(i=0; i<numt; i++) {
					long diff = d-(startt+i);
					long [] array = new long[n*n];
					int k=0;
//System.out.println("startt, numt, i = " + startt + " " + numt + " " + i);
					for(int child=0; child<n; child++) {
						for(int j=0; j<n; j++) {
							array[k++] = carray[child][i+j];
//System.out.print(" " + array[k-1]);
						}
//System.out.println();
					}
					costs[i] = Ponyless_Bon.Solution.assignmentProblem(array,n) + c*diff*diff; 
				}
//System.out.print("  Returning:");
//for(long val : costs) System.out.print(" " + val);
//System.out.println();
				return costs;
			}
		}
	}
	
	public static Node[] cities;
	
	public static void main(String[] args) {
		
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();					// # of cities
		cities = new Node[n+1];
		for(int i=1; i<=n; i++) {
			int c, d, parent;
			c = in.nextInt();
			d = in.nextInt();
			parent = in.nextInt();
			if (cities[i] == null) {
				cities[i] = new Node();
				cities[i].children = new ArrayList<>();
			}
			cities[i].c = c;
			cities[i].d = d;
			if (cities[parent] == null) {
				cities[parent] = new Node();
				cities[parent].children = new ArrayList<>();
			}
			cities[parent].children.add(cities[i]);
		}
		long [] ans = cities[0].process(0,1);
		System.out.println(ans[0]);
	}

	public static class Solution {
	/* code taken from https://www.geeksforgeeks.org/hungarian-algorithm-assignment-problem-set-1-introduction/ */
		  public static int n;
		  public static long cost[][]; //cost matrix
		  public static int max_match; //n workers and n jobs
		  public static long lx[], ly[]; //labels of X and Y parts
		  public static int xy[]; //xy[x] - vertex that is matched with x,
		  public static int yx[]; //yx[y] - vertex that is matched with y
		  public static boolean S[], T[]; //sets S and T in algorithm
		  public static long slack[]; //as in the algorithm description
		  public static int slackx[]; //slackx[y] such a vertex, that
		  public static int prev_ious[]; //array for memorizing alternating p

		  public static void init_labels()
		  {
		    Arrays.fill(lx, 0);
		    Arrays.fill(ly, 0);
		    for (int x = 0; x < n; x++)
		      for (int y = 0; y < n; y++)
		        lx[x] = Math.max(lx[x], cost[x][y]);
		  }


		  public static void update_labels()
		  {
		    int x, y;
		    long delta = 99999999; //init delta as infinity
		    for (y = 0; y < n; y++) //calculate delta using slack
		      if (!T[y])
		        delta = Math.min(delta, slack[y]);
		    for (x = 0; x < n; x++) //update X labels
		      if (S[x])
		        lx[x] -= delta;
		    for (y = 0; y < n; y++) //update Y labels
		      if (T[y])
		        ly[y] += delta;
		    for (y = 0; y < n; y++) //update slack array
		      if (!T[y])
		        slack[y] -= delta;
		  }

		  public static void add_to_tree(int x, int prev_iousx) 
		    //x - current vertex,prev_iousx - vertex from X before x in the alternating path,
		    //so we add edges (prev_iousx, xy[x]), (xy[x], x)
		  {
		    S[x] = true; //add x to S
		    prev_ious[x] = prev_iousx; //we need this when augmenting
		    for (int y = 0; y < n; y++) //update slacks, because we add new vertex to S
		      if (lx[x] + ly[y] - cost[x][y] < slack[y])
		      {
		        slack[y] = lx[x] + ly[y] - cost[x][y];
		        slackx[y] = x;
		      }
		  }



		  public static void augment() //main function of the algorithm
		  {
		    if (max_match == n) return; //check whether matching is already perfect
		    int x, y; //just counters and root vertex
		    int q[] = new int[n], wr = 0, rd = 0; //q - queue for bfs, wr,rd - write and read
		    //pos in queue
		    Arrays.fill(S, false); //init set S
		    Arrays.fill(T, false); //init set T
		    Arrays.fill(prev_ious, -1); //init set prev_ious - for the alternating tree
		    int root = -1;

		    for (x = 0; x < n; x++) //finding root of the tree
		    {
		      if (xy[x] == -1)
		      {
		        q[wr++] = root = x;
		        prev_ious[x] = -2;
		        S[x] = true;
		        break;
		      }
		    }
		    if (root == -1) {
		      // All vertices are already matched
		      return;
		    }
		    for (y = 0; y < n; y++) //initializing slack array
		    {
		      slack[y] = lx[root] + ly[y] - cost[root][y];
		      slackx[y] = root;
		    }

		    //second part of augment() function
		    while (true) //main cycle
		    {
		      while (rd < wr) //building tree with bfs cycle
		      {
		        x = q[rd++]; //current vertex from X part
		        for (y = 0; y < n; y++) //iterate through all edges in equality graph
		          if (cost[x][y] == lx[x] + ly[y] && !T[y])
		          {
		            if (yx[y] == -1) break; //an exposed vertex in Y found, so
		            //augmenting path exists!
		            T[y] = true; //else just add y to T,
		            q[wr++] = yx[y]; //add vertex yx[y], which is matched
		            //with y, to the queue
		            add_to_tree(yx[y], x); //add edges (x,y) and (y,yx[y]) to the tree
		          }
		        if (y < n)
		          break; //augmenting path found!
		      }
		      if (y < n)
		        break; //augmenting path found!

		      update_labels(); //augmenting path not found, so improve labeling

		      wr = rd = 0; 
		      for (y = 0; y < n; y++) 
		        //in this cycle we add edges that were added to the equality graph as a
		        //result of improving the labeling, we add edge (slackx[y], y) to the tree if
		        //and only if !T[y] && slack[y] == 0, also with this edge we add another one
		        //(y, yx[y]) or augment the matching, if y was exposed
		        if (!T[y] && slack[y] == 0)
		        {
		          if (yx[y] == -1) //exposed vertex in Y found - augmenting path exists!
		          {
		            x = slackx[y];
		            break;
		          }
		          else
		          {
		            T[y] = true; //else just add y to T,
		            if (!S[yx[y]]) 
		            {
		              q[wr++] = yx[y]; //add vertex yx[y], which is matched with
		              //y, to the queue
		              add_to_tree(yx[y], slackx[y]); //and add edges (x,y) and (y,
		              //yx[y]) to the tree
		            }
		          }
		        }
		      if (y < n) break; //augmenting path found!
		    }

		    if (y < n) //we found augmenting path!
		    {
		      max_match++; //increment matching
		      //in this cycle we inverse edges along augmenting path
		      for (int cx = x, cy = y, ty; cx != -2; cx = prev_ious[cx], cy = ty)
		      {
		        ty = xy[cx];
		        yx[cy] = cx;
		        xy[cx] = cy;
		      }
		      augment(); //recall function, go to step 1 of the algorithm
		    }
		  }//end of augment() function

		  public static int hungarian()
		  {
		    int ret = 0; //weight of the optimal matching
		    max_match = 0; //number of vertices in current matching
		    xy = new int[n];
		    yx = new int[n];
		    Arrays.fill(xy, -1);
		    Arrays.fill(yx, -1);
		    init_labels(); //step 0
		    augment(); //steps 1-3

		    for (int x = 0; x < n; x++) //forming answer there
		      ret += cost[x][xy[x]];

		    return ret;
		  }

		  public static long assignmentProblem(long Arr[], int N) {

		    n = N;
		    cost = new long[n][n];
		    lx = new long[n];
		    ly = new long[n];
		    S = new boolean[n];
		    T = new boolean[n];
		    slack = new long[n];
		    slackx = new int[n];
		    prev_ious = new int[n];

		    for(int i=0; i<n; i++)
		      for(int j=0; j<n; j++)
		        cost[i][j] = -1*Arr[i*n+j];

		    int ans = -1 * hungarian();

		    return ans;
		  }
	}
}
