import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
public class Dijkstra {

	public static void main(String[] args) throws IOException{

		//Scanner sc = new Scanner(System.in);
//		long startTime = System.nanoTime();
		MyScanner sc = new MyScanner();
		getShortestPath(sc);
//		long endTime = System.nanoTime();
//		long elapsedTime = endTime - startTime;
//		double seconds = elapsedTime / 1.0E09;

		//System.out.println("Total execution time: " + (seconds) );

	}

	private static void getShortestPath(MyScanner sc) throws IOException{

		HashMap<Integer, Node> nodes = new HashMap<>();
		int numNodes = sc.nextInt();
		int numEdges = sc.nextInt();

		for(int i = 0; i < numEdges; i++){
			int first = sc.nextInt();
			int second = sc.nextInt();
			int cost = sc.nextInt();
			Node firstNode = new Node(first);
			Node secondNode = new Node(second);
			if(!nodes.containsKey(first)){
				nodes.put(first, firstNode);
			}
			nodes.get(first).neighbours.add(new Edge(cost, secondNode));
			if(!nodes.containsKey(second)){
				nodes.put(second, secondNode);
			}
			nodes.get(second).neighbours.add(new Edge(cost, firstNode));

		}

		if(nodes.get(1) == null || nodes.get(numNodes) == null){
			System.out.println("-1");
		} else {
			dijkstra(numNodes, nodes);
			if(nodes.get(1).prev == null){
				System.out.println("-1");
			} else {
				printPath(nodes.get(1));

			}
		}

	}

	private static void dijkstra(int numNodes, HashMap<Integer, Node> nodes){

		Node startingNode = nodes.get(numNodes);
		PriorityQueue<Path> toVisit = new PriorityQueue<>();
		Path startingPath = getPath(nodes, startingNode.value);
		startingPath.dest = startingNode;
		toVisit.add(startingPath);
		startingNode.costFromStart = 0;
		boolean reached = false;
		while(!toVisit.isEmpty() && !reached){
			Path currentPath = toVisit.remove();
			Node currentNode = currentPath.dest;
			currentNode.visited = true;

			if(currentNode.value != 1){
				for(Edge e : currentNode.neighbours){
					int cost = e.cost;
					Node neighbour = nodes.get(e.dest.value);
					if(!e.dest.visited){
						if(currentPath.costFromStart + cost < neighbour.costFromStart){
							neighbour.costFromStart = currentNode.costFromStart + cost;
							neighbour.prev = currentNode;
							Path nextSpot = getPath(nodes, neighbour.value);
							nextSpot.dest = neighbour;
							toVisit.add(nextSpot);
						}
					}
				}
			} else {
				reached = true;
			}
		}
	}

	private static Path getPath(HashMap<Integer, Node> nodes, int dest) {
		Path result = new Path();
		Node end = nodes.get(dest);
		result.costFromStart = end.costFromStart;
		return result;
	}

	private static void printPath(Node dest) throws IOException {
		PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
		//OutputStream out = new BufferedOutputStream ( System.out );
		Node temp = dest;
		while(temp != null){
			//System.out.print(temp.value + " ");
			out.print(temp.value + " ");
			//out.write((temp.value + " ").getBytes());
			temp = temp.prev;
		}
		out.flush();
	}

	public static class Path implements Comparable<Path>{

		int costFromStart;
		LinkedList<Node> path;
		int number = 0;
		Node dest;
		public Path(){
			dest = new Node(-1);
			costFromStart = 0;
			path = new LinkedList<>();
		}

		public int numberNodes(){
			return path.size();
		}
		public void add(Node v) {
			path.addFirst(v);
		}

		@Override
		public int compareTo(Path other) {
			return costFromStart < other.costFromStart ? -1 : costFromStart > other.costFromStart ? 1 :0;
		}

	}

	private static class Node {

		int value;
		ArrayList<Edge> neighbours;
		int costFromStart = Integer.MAX_VALUE;
		Node prev = null;
		Node next = null;
		boolean visited;

		public Node(int v){
			value = v;
			neighbours = new ArrayList<Edge>();
			visited = false;
		}
	}

	private static class Edge {
		int cost;
		Node dest;

		public Edge(int cost, Node dest){
			this.cost = cost;
			this.dest = new Node(dest.value);

		}
	}

	  public static class MyScanner {
	      BufferedReader br;
	      StringTokenizer st;

	      public MyScanner() {
	         br = new BufferedReader(new InputStreamReader(System.in));
	      }

	      String next() {
	          while (st == null || !st.hasMoreElements()) {
	              try {
	                  st = new StringTokenizer(br.readLine());
	              } catch (IOException e) {
	                  e.printStackTrace();
	              }
	          }
	          return st.nextToken();
	      }

	      int nextInt() {
	          return Integer.parseInt(next());
	      }

	      long nextLong() {
	          return Long.parseLong(next());
	      }

	      double nextDouble() {
	          return Double.parseDouble(next());
	      }

	      String nextLine(){
	          String str = "";
		  try {
		     str = br.readLine();
		  } catch (IOException e) {
		     e.printStackTrace();
		  }
		  return str;
	      }

	   }

}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Dijkstra {

	public static void main(String[] args) throws FileNotFoundException{

		//Scanner sc = new Scanner(System.in);
		MyScanner sc = new MyScanner();
		getShortestPath(sc);
//		long endTime = System.nanoTime();
//		long elapsedTime = endTime - startTime;
//		double seconds = elapsedTime / 1.0E09;

		//System.out.println("Total execution time: " + (seconds) );

	}

	private static void getShortestPath(MyScanner sc){

		HashMap<Integer, Node> nodes = new HashMap<>();
		int numNodes = sc.nextInt();
		int numEdges = sc.nextInt();

		for(int i = 0; i < numEdges; i++){
			int first = sc.nextInt();
			int second = sc.nextInt();
			int cost = sc.nextInt();
			Node firstNode = new Node(first);
			Node secondNode = new Node(second);
			if(!nodes.containsKey(first)){
				nodes.put(first, firstNode);
			}
			nodes.get(first).neighbours.add(new Edge(cost, secondNode));
			if(!nodes.containsKey(second)){
				nodes.put(second, secondNode);
			}
			nodes.get(second).neighbours.add(new Edge(cost, firstNode));

		}

		if(nodes.get(1) == null || nodes.get(numNodes) == null){
			System.out.println("-1");
		} else {
			dijkstra(numNodes, nodes);
			if(nodes.get(numNodes).prev == null){
				System.out.println("-1");
			} else {
				printPath(nodes.get(numNodes));
			}
		}

	}

	private static void dijkstra(int numNodes, HashMap<Integer, Node> nodes){

		Node startingNode = nodes.get(1);
		PriorityQueue<Path> toVisit = new PriorityQueue<>();
		Path startingPath = getPath(nodes, startingNode.value);
		startingPath.dest = startingNode;
		toVisit.add(startingPath);
		startingNode.costFromStart = 0;

		while(!toVisit.isEmpty()){
			Path currentPath = toVisit.remove();
			Node currentNode = currentPath.dest;
			currentNode.visited = true;
			//if(!currentNode.visited){
				for(Edge e : currentNode.neighbours){
					int cost = e.cost;
					Node neighbour = nodes.get(e.dest.value);
					if(!e.visited){
						if(currentPath.costFromStart + cost < neighbour.costFromStart){

							neighbour.costFromStart = currentNode.costFromStart + cost;
							neighbour.prev = currentNode;
							Path nextSpot = getPath(nodes, neighbour.value);
							nextSpot.dest = neighbour;
							toVisit.add(nextSpot);
							e.visited = true;
						}
					}

				}

			//}

		}
	}

	private static Path getPath(HashMap<Integer, Node> nodes, int dest) {
		Path result = new Path();
		Node end = nodes.get(dest);
		result.costFromStart = end.costFromStart;
		if(end.costFromStart != Integer.MAX_VALUE)
			getPath(result, end);
		return result;
	}

	// helper to get path
	private static void getPath(Path result, Node end) {
		if(end.prev != null)
			getPath(result, end.prev);
		result.add(end);
	}

	// helper to print path
	private static void printPath(Node dest) {
		if(dest.prev != null) {
			printPath(dest.prev);
		}
		System.out.print(dest.value + " ");
	}

	public static class Path implements Comparable<Path>{

		int costFromStart;
		List<Node> path;
		int number = 0;
		Node dest;
		public Path(){
			dest = new Node(-1);
			costFromStart = 0;
			path = new ArrayList<>();
		}

		public int numberNodes(){
			return path.size();
		}
		public void add(Node v) {
			path.add(v);
		}

		@Override
		public int compareTo(Path other) {
			return costFromStart < other.costFromStart ? -1 : costFromStart > other.costFromStart ? 1 :0;
		}

	}

	private static class Node implements Comparable<Node> {

		int value;
		ArrayList<Edge> neighbours;
		int costFromStart = Integer.MAX_VALUE;
		Node prev = null;
		boolean visited;

		public Node(int v){
			value = v;
			neighbours = new ArrayList<Edge>();
			visited = false;
		}

		@Override
		public int compareTo(Node o) {
			if(this.costFromStart < o.costFromStart){
				return -1;
			} else if(this.costFromStart > o.costFromStart){
				return 1;
			}
			return 0;
		}

	}

	private static class Edge {
		int cost;
		Node dest;
		boolean visited = false;

		public Edge(int cost, Node dest){
			this.cost = cost;
			this.dest = new Node(dest.value);

		}
	}

	  public static class MyScanner {
	      BufferedReader br;
	      StringTokenizer st;

	      public MyScanner() {
	         br = new BufferedReader(new InputStreamReader(System.in));
	      }

	      String next() {
	          while (st == null || !st.hasMoreElements()) {
	              try {
	                  st = new StringTokenizer(br.readLine());
	              } catch (IOException e) {
	                  e.printStackTrace();
	              }
	          }
	          return st.nextToken();
	      }

	      int nextInt() {
	          return Integer.parseInt(next());
	      }

	      long nextLong() {
	          return Long.parseLong(next());
	      }

	      double nextDouble() {
	          return Double.parseDouble(next());
	      }

	      String nextLine(){
	          String str = "";
		  try {
		     str = br.readLine();
		  } catch (IOException e) {
		     e.printStackTrace();
		  }
		  return str;
	      }

	   }

}


import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Stack;
public class Dijkstra {

	public static void main(String[] args) throws FileNotFoundException{

		Scanner sc = new Scanner(System.in);

//		long startTime = System.nanoTime();
		getShortestPath(sc);
//		long endTime = System.nanoTime();
//		long elapsedTime = endTime - startTime;
//		double seconds = elapsedTime / 1.0E09;

		//System.out.println("Total execution time: " + (seconds) );

	}

	private static void getShortestPath(Scanner sc){

		HashMap<Integer, Node> nodes = new HashMap<>();
		int numNodes = sc.nextInt();
		int numEdges = sc.nextInt();

		for(int i = 0; i < numEdges; i++){
			int first = sc.nextInt();
			int second = sc.nextInt();
			int cost = sc.nextInt();
			Node firstNode = new Node(first);
			Node secondNode = new Node(second);
			if(!nodes.containsKey(first)){
				nodes.put(first, firstNode);
			}
			nodes.get(first).neighbours.add(new Edge(cost, secondNode));
			if(!nodes.containsKey(second)){
				nodes.put(second, secondNode);
			}
			nodes.get(second).neighbours.add(new Edge(cost, firstNode));

		}

		//		for(Integer i: nodes.keySet()){
		//			Node n = nodes.get(i);
		//
		//			System.out.println("node: " + n.value + " is connected to: ");
		//			for(Edge e : n.neighbours){
		//				System.out.println(e.dest.value + " " + "cost to reach it is: " + e.cost);
		//			}
		//			System.out.println();
		//			System.out.println("----------------------------");
		//
		//
		//		}

		dijkstra(numNodes, nodes);
		printPath(nodes.get(numNodes));

	}

	private static void dijkstra(int numNodes, HashMap<Integer, Node> nodes){

		Node startingNode = nodes.get(1);
		//PriorityQueue<Node> toVisit = new PriorityQueue<>();
		PriorityQueue<Path> toVisit = new PriorityQueue<>();
		Path startingPath = getPath(nodes, startingNode.value);
		startingPath.dest = startingNode;
		//toVisit.add(startingNode);
		toVisit.add(startingPath);
		startingNode.costFromStart = 0;
		boolean goalSearched = false;
		//int minCost = Integer.MAX_VALUE;

		while(!toVisit.isEmpty()){
			//Node current = toVisit.remove();
			Path currentPath = toVisit.remove();
			Node currentNode = currentPath.dest;
			currentNode.visited = true;
			//System.out.println("dequeue: " + current.value + " and cost from start: " + current.costFromStart);
			for(Edge e : currentNode.neighbours){
				int cost = e.cost;
				Node neighbour = nodes.get(e.dest.value);
				//System.out.println("attemping to visit neighbor: " + destination.value + " its cost from start is : " + destination.costFromStart);
				if(!e.visited){
					if(currentPath.costFromStart + cost < neighbour.costFromStart){

						neighbour.costFromStart = currentNode.costFromStart + cost;
						neighbour.prev = currentNode;

						if(neighbour.value == numNodes){
							//								if(minCost > destination.costFromStart){
							//									minCost = destination.costFromStart;
							//									//System.out.println("got it: " + destination.costFromStart);
							//								}
							//System.out.println("remaining in the queue: " + toVisit.size());
							//toVisit = new PriorityQueue<>();
							//System.out.println("got it: " + neighbour.value + " and cost from start: " + neighbour.costFromStart);
							//System.out.println("cost: " + neighbour.costFromStart);

						} else {

						}
						Path nextSpot = getPath(nodes, neighbour.value);
						nextSpot.dest = neighbour;
						toVisit.add(nextSpot);
						e.visited = true;
					}
				}

			}

		}

		//		//System.out.println("min cost: " + minCost);
		//		Node goal = nodes.get(5);
		//		//System.out.println("cost from start: " + goal.costFromStart);
		//		Node temp = nodes.get(5);
		//		Stack<Integer> thePath = new Stack<>();
		//		while(temp != null){
		//			//System.out.println("val: " + temp.value);
		//			thePath.push(temp.value);
		//			temp = temp.prev;
		//		}
		//
		//		while(!thePath.isEmpty()){
		//			System.out.print(thePath.pop() + " ");
		//		}

	}

	private static Path getPath(HashMap<Integer, Node> nodes, int dest) {
		Path result = new Path();
		Node end = nodes.get(dest);
		result.costFromStart = end.costFromStart;
		if(end.costFromStart != Integer.MAX_VALUE)
			getPath(result, end);
		return result;
	}

	// helper to get path
	private static void getPath(Path result, Node end) {
		if(end.prev != null)
			getPath(result, end.prev);
		result.add(end);
	}

	// helper to print path
	private static void printPath(Node dest) {
		if(dest == null){
			System.out.print("-1 ");
		} else {
			if(dest.prev != null) {
				printPath(dest.prev);
			}
			if(dest.prev == null){
				System.out.print("-1 ");
			} else {
				System.out.print(dest.value + " ");
			}
		}

	}

	public static class Path implements Comparable<Path>{

		int costFromStart;
		List<Node> path;
		int number = 0;
		Node dest;
		public Path(){
			dest = new Node(-1);
			costFromStart = 0;
			path = new ArrayList<>();
		}

		public int numberNodes(){
			return path.size();
		}
		public void add(Node v) {
			path.add(v);
		}

		@Override
		public int compareTo(Path other) {
			return costFromStart < other.costFromStart ? -1 : costFromStart > other.costFromStart ? 1 :0;
		}

	}

	private static class Node implements Comparable<Node> {

		int value;
		ArrayList<Edge> neighbours;
		int costFromStart = Integer.MAX_VALUE;
		Node prev = null;
		boolean visited;

		public Node(int v){
			value = v;
			neighbours = new ArrayList<Edge>();
			visited = false;
		}

		@Override
		public int compareTo(Node o) {
			if(this.costFromStart < o.costFromStart){
				return -1;
			} else if(this.costFromStart > o.costFromStart){
				return 1;
			}
			return 0;
		}

	}

	private static class Edge {
		int cost;
		Node dest;
		boolean visited = false;

		public Edge(int cost, Node dest){
			this.cost = cost;
			this.dest = new Node(dest.value);

		}
	}

}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
public class Dijkstra {

	public static void main(String[] args) throws FileNotFoundException{

		//Scanner sc = new Scanner(System.in);
//		long startTime = System.nanoTime();
		MyScanner sc = new MyScanner();
		getShortestPath(sc);
//		long endTime = System.nanoTime();
//		long elapsedTime = endTime - startTime;
//		double seconds = elapsedTime / 1.0E09;

		//System.out.println("Total execution time: " + (seconds) );

	}

	private static void getShortestPath(MyScanner sc){

		HashMap<Integer, Node> nodes = new HashMap<>();
		int numNodes = sc.nextInt();
		int numEdges = sc.nextInt();

		for(int i = 0; i < numEdges; i++){
			int first = sc.nextInt();
			int second = sc.nextInt();
			int cost = sc.nextInt();
			Node firstNode = new Node(first);
			Node secondNode = new Node(second);
			if(!nodes.containsKey(first)){
				nodes.put(first, firstNode);
			}
			nodes.get(first).neighbours.add(new Edge(cost, secondNode));
			if(!nodes.containsKey(second)){
				nodes.put(second, secondNode);
			}
			nodes.get(second).neighbours.add(new Edge(cost, firstNode));

		}

		if(nodes.get(1) == null || nodes.get(numNodes) == null){
			System.out.println("-1");
		} else {
			dijkstra(numNodes, nodes);
			if(nodes.get(1).prev == null){
				System.out.println("-1");
			} else {

				//printPath(nodes.get(numNodes));
				printPath(nodes.get(1));

			}
		}

	}

	private static void dijkstra(int numNodes, HashMap<Integer, Node> nodes){

		Node startingNode = nodes.get(numNodes);
		PriorityQueue<Path> toVisit = new PriorityQueue<>();
		Path startingPath = getPath(nodes, startingNode.value);
		startingPath.dest = startingNode;
		toVisit.add(startingPath);
		startingNode.costFromStart = 0;
		boolean reached = false;
		while(!toVisit.isEmpty() && !reached){
			Path currentPath = toVisit.remove();
			Node currentNode = currentPath.dest;
			currentNode.visited = true;

			if(currentNode.value != 1){
				for(Edge e : currentNode.neighbours){
					int cost = e.cost;
					Node neighbour = nodes.get(e.dest.value);
					if(!e.dest.visited){
						if(currentPath.costFromStart + cost < neighbour.costFromStart){

							neighbour.costFromStart = currentNode.costFromStart + cost;
							neighbour.prev = currentNode;
							currentNode.next = neighbour; // WRONG!
							Path nextSpot = getPath(nodes, neighbour.value);
							nextSpot.dest = neighbour;
							toVisit.add(nextSpot);
						}
					}

				}

			} else {
				reached = true;
				toVisit = new PriorityQueue<>();
				//nodes.clear();
			}

		}
	}

	private static Path getPath(HashMap<Integer, Node> nodes, int dest) {
		Path result = new Path();
		Node end = nodes.get(dest);
		result.costFromStart = end.costFromStart;
		if(end.costFromStart != Integer.MAX_VALUE)
			getPath(result, end);
		return result;
	}

	// helper to get path
	private static void getPath(Path result, Node end) {
		if(end.prev != null)
			getPath(result, end.prev);
		result.add(end);
	}

	// helper to print path
	private static void printPath(Node dest) {
		Node temp = dest;
		while(temp != null){
			System.out.print(temp.value + " ");
			temp = temp.prev;
		}
//		Stack<Node> stack = new Stack<Node>();
//		while(temp != null){
//			stack.add(temp);
//			temp = temp.prev;
//		}
//		while(!stack.isEmpty()){
//			System.out.print(stack.pop().value + " ");
//		}
		//
//		Node temp = dest;
//		while(temp.prev != null){
//			temp = temp.prev;
//		}
//		while(temp != null){
//			System.out.print(temp.value + " ");
//			temp = temp.next;
//		}
//		if(dest.prev != null) {
//			printPath(dest.prev);
//		}
//		System.out.print(dest.value + " ");
	}

	public static class Path implements Comparable<Path>{

		int costFromStart;
		LinkedList<Node> path;
		int number = 0;
		Node dest;
		public Path(){
			dest = new Node(-1);
			costFromStart = 0;
			path = new LinkedList<>();
		}

		public int numberNodes(){
			return path.size();
		}
		public void add(Node v) {
			path.addFirst(v);
		}

		@Override
		public int compareTo(Path other) {
			return costFromStart < other.costFromStart ? -1 : costFromStart > other.costFromStart ? 1 :0;
		}

	}

	private static class Node {

		int value;
		ArrayList<Edge> neighbours;
		int costFromStart = Integer.MAX_VALUE;
		Node prev = null;
		Node next = null;
		boolean visited;

		public Node(int v){
			value = v;
			neighbours = new ArrayList<Edge>();
			visited = false;
		}
	}

	private static class Edge {
		int cost;
		Node dest;

		public Edge(int cost, Node dest){
			this.cost = cost;
			this.dest = new Node(dest.value);

		}
	}

	  public static class MyScanner {
	      BufferedReader br;
	      StringTokenizer st;

	      public MyScanner() {
	         br = new BufferedReader(new InputStreamReader(System.in));
	      }

	      String next() {
	          while (st == null || !st.hasMoreElements()) {
	              try {
	                  st = new StringTokenizer(br.readLine());
	              } catch (IOException e) {
	                  e.printStackTrace();
	              }
	          }
	          return st.nextToken();
	      }

	      int nextInt() {
	          return Integer.parseInt(next());
	      }

	      long nextLong() {
	          return Long.parseLong(next());
	      }

	      double nextDouble() {
	          return Double.parseDouble(next());
	      }

	      String nextLine(){
	          String str = "";
		  try {
		     str = br.readLine();
		  } catch (IOException e) {
		     e.printStackTrace();
		  }
		  return str;
	      }

	   }

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
public class DijkstraArrayList {

	public static void main(String[] args) throws IOException{

		//Scanner sc = new Scanner(System.in);
		//		long startTime = System.nanoTime();
		MyScanner sc = new MyScanner();
		getShortestPath(sc);
		//		long endTime = System.nanoTime();
		//		long elapsedTime = endTime - startTime;
		//		double seconds = elapsedTime / 1.0E09;

		//System.out.println("Total execution time: " + (seconds) );

	}

	private static void getShortestPath(MyScanner sc) throws IOException{

		int numNodes = sc.nextInt();
		int numEdges = sc.nextInt();
		Node[] nodes = new Node[numNodes + 1];

		for(int i = 0; i < numEdges; i++){
			int first = sc.nextInt();
			int second = sc.nextInt();
			int cost = sc.nextInt();
			Node firstNode = new Node(first);
			Node secondNode = new Node(second);
			if(nodes[first] == null){
				nodes[first] = firstNode;
			}
			nodes[first].neighbours.add(new Edge(cost, secondNode));
			if(nodes[second] == null){
				nodes[second] = secondNode;
			}
			nodes[second].neighbours.add(new Edge(cost, firstNode));

		}

		if(nodes[1] == null || nodes[numNodes] == null){
			System.out.println("-1");
		} else {
			dijkstra(numNodes, nodes);
			if(nodes[1].prev == null){
				System.out.println("-1");
			} else {
				printPath(nodes[1]);

			}
		}

	}

	private static void dijkstra(int numNodes, Node[] nodes){

		Node startingNode = nodes[numNodes];
		PriorityQueue<Path> toVisit = new PriorityQueue<>();
		Path startingPath = getPath(nodes, startingNode.value);
		startingPath.dest = startingNode;
		toVisit.add(startingPath);
		startingNode.costFromStart = 0;
		boolean reached = false;
		while(!toVisit.isEmpty() && !reached){
			Path currentPath = toVisit.remove();
			Node currentNode = currentPath.dest;
			currentNode.visited = true;

			if(currentNode.value != 1){
				for(Edge e : currentNode.neighbours){
					int cost = e.cost;
					Node neighbour = nodes[e.dest.value];
					if(!e.dest.visited){
						if(currentPath.costFromStart + cost < neighbour.costFromStart){
							neighbour.costFromStart = currentNode.costFromStart + cost;
							neighbour.prev = currentNode;
							Path nextSpot = getPath(nodes, neighbour.value);
							nextSpot.dest = neighbour;
							toVisit.add(nextSpot);
						}
					}
				}
			} else {
				reached = true;
			}
		}
	}

	private static Path getPath(Node[] nodes, int dest) {
		Path result = new Path();
		Node end = nodes[dest];
		result.costFromStart = end.costFromStart;
		return result;
	}

	private static void printPath(Node dest) throws IOException {
		PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
		//OutputStream out = new BufferedOutputStream ( System.out );
		Node temp = dest;
		while(temp != null){
			//System.out.print(temp.value + " ");
			out.print(temp.value + " ");
			//out.write((temp.value + " ").getBytes());
			temp = temp.prev;
		}
		out.flush();
	}

	public static class Path implements Comparable<Path>{

		int costFromStart;
		LinkedList<Node> path;
		int number = 0;
		Node dest;
		public Path(){
			dest = new Node(-1);
			costFromStart = 0;
			path = new LinkedList<>();
		}

		public int numberNodes(){
			return path.size();
		}
		public void add(Node v) {
			path.addFirst(v);
		}

		@Override
		public int compareTo(Path other) {
			return costFromStart < other.costFromStart ? -1 : costFromStart > other.costFromStart ? 1 :0;
		}

	}

	private static class Node {

		int value;
		ArrayList<Edge> neighbours;
		int costFromStart = Integer.MAX_VALUE;
		Node prev = null;
		Node next = null;
		boolean visited;

		public Node(int v){
			value = v;
			neighbours = new ArrayList<Edge>();
			visited = false;
		}
	}

	private static class Edge {
		int cost;
		Node dest;

		public Edge(int cost, Node dest){
			this.cost = cost;
			this.dest = new Node(dest.value);

		}
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine(){
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

}


import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;

public class DijkstraAlt {

	static List<Node> nodes;

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		int n = 0;
		int m = 0;
		n = sc.nextInt();
		m = sc.nextInt();

		nodes = new ArrayList<Node>();
		HashSet<Node> setNodes = new HashSet<Node>();
		for (int i = 0; i < n; i++) {
			nodes.add(new Node(i));
		}

		for (int i = 0; i < m; i++) {
			int source = sc.nextInt() - 1;
			int destination = sc.nextInt() - 1;
			int weight = sc.nextInt();
			nodes.get(source).addNeighbour(nodes.get(destination), weight);
			nodes.get(destination).addNeighbour(nodes.get(source), weight);
		}

		nodes.get(0).pathDistance = 0;
		PriorityQueue<Node> pq = new PriorityQueue<>(1, new Comparator<Node>() {
			@Override
			public int compare(Node n1, Node n2) {
				return n1.pathDistance - n2.pathDistance;
			}
		});

		// Dijkstra's algorithm
		pq.add(nodes.get(0));
		while(!pq.isEmpty()) {
			Node node = pq.poll();
			if (setNodes.contains(node)) continue;
			setNodes.add(node);
			for (Node neighbour : node.neighbours.keySet()) {
				// Evaluate shortest paths
				int distance = node.neighbours.get(neighbour);
				if (!setNodes.contains(neighbour) && neighbour.pathDistance > node.pathDistance + distance) {
					neighbour.pathDistance = node.pathDistance + distance;
					neighbour.previous = node;
					pq.add(neighbour);
				}
			}
		}

		Node currentNode = nodes.get(n);
		if (currentNode.previous == null) {
			System.out.println("-1");
		}
		else {
			StringBuilder sb = new StringBuilder();
			StringBuilder sb2;
			while (currentNode != null) {
				sb2 = new StringBuilder(String.valueOf(currentNode.number + 1)).append(" ");
				sb2.reverse();
				sb.append(sb2);
				currentNode = currentNode.previous;
			}
			System.out.println(sb.reverse().toString());
		}
	}

	public static class Node {
		public Map<Node, Integer> neighbours;
		public Node previous;
		public int pathDistance;
		public int number;
		public Node(int number) {
			neighbours = new HashMap<>();
			pathDistance = Integer.MAX_VALUE;
			this.number = number;
		}

		void addNeighbour(Node destination, int weight) {
			if (neighbours.containsKey(destination) && neighbours.get(destination) <= weight) {
				return;
			}
			neighbours.put(destination, weight);
		}
	}
}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
public class Dijkstra {

	public static void main(String[] args) throws FileNotFoundException{

		//Scanner sc = new Scanner(System.in);
//		long startTime = System.nanoTime();
		MyScanner sc = new MyScanner();
		getShortestPath(sc);
//		long endTime = System.nanoTime();
//		long elapsedTime = endTime - startTime;
//		double seconds = elapsedTime / 1.0E09;

		//System.out.println("Total execution time: " + (seconds) );

	}

	private static void getShortestPath(MyScanner sc){

		HashMap<Integer, Node> nodes = new HashMap<>();
		int numNodes = sc.nextInt();
		int numEdges = sc.nextInt();

		for(int i = 0; i < numEdges; i++){
			int first = sc.nextInt();
			int second = sc.nextInt();
			int cost = sc.nextInt();
			Node firstNode = new Node(first);
			Node secondNode = new Node(second);
			if(!nodes.containsKey(first)){
				nodes.put(first, firstNode);
			}
			nodes.get(first).neighbours.add(new Edge(cost, secondNode));
			if(!nodes.containsKey(second)){
				nodes.put(second, secondNode);
			}
			nodes.get(second).neighbours.add(new Edge(cost, firstNode));

		}

		if(nodes.get(1) == null || nodes.get(numNodes) == null){
			System.out.println("-1");
		} else {
			dijkstra(numNodes, nodes);
			if(nodes.get(numNodes).prev == null){
				System.out.println("-1");
			} else {

				printPath(nodes.get(numNodes));
			}
		}

	}

	private static void dijkstra(int numNodes, HashMap<Integer, Node> nodes){

		Node startingNode = nodes.get(1);
		PriorityQueue<Path> toVisit = new PriorityQueue<>();
		Path startingPath = getPath(nodes, startingNode.value);
		startingPath.dest = startingNode;
		toVisit.add(startingPath);
		startingNode.costFromStart = 0;
		boolean reached = false;
		while(!toVisit.isEmpty() && !reached){
			Path currentPath = toVisit.remove();
			Node currentNode = currentPath.dest;
			currentNode.visited = true;

			if(currentNode.value != numNodes){
				for(Edge e : currentNode.neighbours){
					int cost = e.cost;
					Node neighbour = nodes.get(e.dest.value);
					if(!e.dest.visited){
						if(currentPath.costFromStart + cost < neighbour.costFromStart){

							neighbour.costFromStart = currentNode.costFromStart + cost;
							neighbour.prev = currentNode;
							currentNode.next = neighbour; // WRONG!
							Path nextSpot = getPath(nodes, neighbour.value);
							nextSpot.dest = neighbour;
							toVisit.add(nextSpot);
						}
					}

				}

			} else {
				reached = true;
				toVisit = new PriorityQueue<>();
				//nodes.clear();
			}

		}
	}

	private static Path getPath(HashMap<Integer, Node> nodes, int dest) {
		Path result = new Path();
		Node end = nodes.get(dest);
		result.costFromStart = end.costFromStart;
		if(end.costFromStart != Integer.MAX_VALUE)
			getPath(result, end);
		return result;
	}

	// helper to get path
	private static void getPath(Path result, Node end) {
		if(end.prev != null)
			getPath(result, end.prev);
		result.add(end);
	}

	// helper to print path
	private static void printPath(Node dest) {
//		Node temp = dest;
//		Stack<Node> stack = new Stack<Node>();
//		while(temp != null){
//			stack.add(temp);
//			temp = temp.prev;
//		}
//		while(!stack.isEmpty()){
//			System.out.print(stack.pop().value + " ");
//		}
		Node temp = dest;
		while(temp.prev != null){
			temp = temp.prev;
		}
		while(temp != null){
			System.out.print(temp.value + " ");
			temp = temp.next;
		}
//		if(dest.prev != null) {
//			printPath(dest.prev);
//		}
//		System.out.print(dest.value + " ");
	}

	public static class Path implements Comparable<Path>{

		int costFromStart;
		List<Node> path;
		int number = 0;
		Node dest;
		public Path(){
			dest = new Node(-1);
			costFromStart = 0;
			path = new ArrayList<>();
		}

		public int numberNodes(){
			return path.size();
		}
		public void add(Node v) {
			path.add(v);
		}

		@Override
		public int compareTo(Path other) {
			return costFromStart < other.costFromStart ? -1 : costFromStart > other.costFromStart ? 1 :0;
		}

	}

	private static class Node {

		int value;
		ArrayList<Edge> neighbours;
		int costFromStart = Integer.MAX_VALUE;
		Node prev = null;
		Node next = null;
		boolean visited;

		public Node(int v){
			value = v;
			neighbours = new ArrayList<Edge>();
			visited = false;
		}
	}

	private static class Edge {
		int cost;
		Node dest;

		public Edge(int cost, Node dest){
			this.cost = cost;
			this.dest = new Node(dest.value);

		}
	}

	  public static class MyScanner {
	      BufferedReader br;
	      StringTokenizer st;

	      public MyScanner() {
	         br = new BufferedReader(new InputStreamReader(System.in));
	      }

	      String next() {
	          while (st == null || !st.hasMoreElements()) {
	              try {
	                  st = new StringTokenizer(br.readLine());
	              } catch (IOException e) {
	                  e.printStackTrace();
	              }
	          }
	          return st.nextToken();
	      }

	      int nextInt() {
	          return Integer.parseInt(next());
	      }

	      long nextLong() {
	          return Long.parseLong(next());
	      }

	      double nextDouble() {
	          return Double.parseDouble(next());
	      }

	      String nextLine(){
	          String str = "";
		  try {
		     str = br.readLine();
		  } catch (IOException e) {
		     e.printStackTrace();
		  }
		  return str;
	      }

	   }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Dikstra {

    public static void main(String[] args) {
        Scanner in = new Scanner();
        int verticies = in.nextInt();
        int edges = in.nextInt();

        Node[] list = new Node[verticies];
        list[0] = new Node(1, 0);
        for(int i = 1; i < verticies; i++){
            list[i] = new Node(i + 1, Integer.MAX_VALUE);
        }
        for(int i = 0; i < edges; i++){
            int curr = in.nextInt();
            int next = in.nextInt();
            int weight = in.nextInt();
            // list[next - 1].setWeight(list[curr - 1].weight + weight);
            list[curr - 1].addNeighbor(list[next - 1], weight);
            list[next - 1].addNeighbor(list[curr - 1], weight);
        }

        PriorityQueue<Node> queue = new PriorityQueue<Node>();
        queue.offer(list[0]);
        System.err.println("arrived");
        while(!queue.isEmpty()){
            Node curr = queue.poll();
            if(curr == list[verticies - 1]){
                break;
            }

            for(int i = 0; i < curr.neighborNum; i++){
                boolean update =
                    curr.neighbors.get(i).setWeight(curr.weight + curr.edges.get(i), curr);
                if(update){
                    queue.offer(curr.neighbors.get(i));
                }
            }
        }
        System.err.println("arrived2");
        Node temp = list[verticies - 1];
        String output = "";
        while(temp != list[0]){
            output = " " + temp.num + output;
            temp = temp.previous;
            if(temp == null){
                output = "-1";
                break;
            }
        }
        if(!output.equals("-1")){
            output = 1 + output;
        }
        System.out.println(output);
        if(verticies == 100000 && edges == 99999) {
            System.out.println(Arrays.toString(list));
        }
//// final long dist[] = new long[verticies];
//// Arrays.fill(dist, 10000000);
//// dist[0] = 0;
//// int[] prev = new int[verticies];
//
// System.out.println(Arrays.toString(list));
// PriorityQueue<Node> queue = new PriorityQueue<Node>();
//// for(Node i : list){
//// queue.offer(i);
//// }
//// System.out.println(queue.toString());
// queue.offer(list[0]);
//
// while(!queue.isEmpty()){
// Node curr = queue.poll();
//
// if(curr == list[verticies - 1]){
// // output = output + curr.num;
// break;
// }
// // output = output + curr.num + " ";
// System.out.println("current:" + curr.num + " " + curr.neighbors.toString());
// for(Node i : curr.neighbors){
//
// queue.offer(i);
// if(i.previous == null){
// i.previous = curr;
// }else if(i.weight -i.previous.weight > curr.weight){
// System.out.println("first: " + i.previous.weight);
// i.previous = curr;
// System.out.println("new: " + i.previous.weight);
// }
//
// }
// }
// System.out.println(list[verticies - 1].previous.num);
// String output = "";
// Node temp = list[verticies - 1];
// while(temp != list[0]){
// output = " " + temp.num + output;
// temp = temp.previous;
// }
// output = 1 + output;
// System.out.println(output);

    }

    public static class Node implements Comparable {
        int                num;
        long               weight;
        ArrayList<Node>    neighbors;
        ArrayList<Integer> edges;
        Node               previous;
        boolean            visited;
        int                neighborNum;

        public Node(int nodeNum, long nodeWeight) {
            num = nodeNum;
            weight = nodeWeight;
            neighbors = new ArrayList<Node>();
            edges = new ArrayList<Integer>();
            neighborNum = 0;
        }

        public void addNeighbor(Node neighbor, int edgeWeight) {
            neighbors.add(neighbor);
            edges.add(edgeWeight);
            neighborNum++;
        }

        public boolean setWeight(long nodeWeight, Node back) {
            if(nodeWeight < weight){
                weight = nodeWeight;
                previous = back;
                return true;
            }
            return false;
        }

        public void setPrevious(Node prev) {
            previous = prev;
        }

        public String toString() {
            return "" + num;
        }

        @Override
        public int compareTo(Object other) {
            Node temp = (Node)other;
            if(temp.weight != weight){
                return (int)(weight - temp.weight);
            }
            return num - temp.num;
        }
    }

    // -----------Scanner class for faster input----------
    /*
     * Provides similar API as java.util.Scanner but does not use regular
     * expression engine.
     */
    public static class Scanner {
        BufferedReader  br;
        StringTokenizer st;

        public Scanner(Reader in) {
            br = new BufferedReader(in);
        }

        public Scanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while(st == null || !st.hasMoreElements()){

                try{
                    st = new StringTokenizer(br.readLine());
                }catch(IOException e){
                    e.printStackTrace();
                }

            }

            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        // Slightly different from java.util.Scanner.nextLine(),
        // which returns any remaining characters in current line,
        // if any.
        String readNextLine() {
            String str = "";
            try{
                str = br.readLine();
            }catch(IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Dikstra {

    public static void main(String[] args) {
        Scanner in = new Scanner();
        int verticies = in.nextInt();
        long edges = in.nextInt();

        Node[] list = new Node[verticies];
        list[0] = new Node(1, 0);
        for(int i = 1; i < verticies; i++){
            list[i] = new Node(i + 1, Long.MAX_VALUE);
        }
        for(long i = 0; i < edges; i++){
            int curr = in.nextInt();
            int next = in.nextInt();
            int weight = in.nextInt();
            // list[next - 1].setWeight(list[curr - 1].weight + weight);
            list[curr - 1].addNeighbor(list[next - 1], weight);
            list[next - 1].addNeighbor(list[curr - 1], weight);
        }

        PriorityQueue<Node> queue = new PriorityQueue<Node>();
        queue.offer(list[0]);
        System.err.println("arrived");
        while(!queue.isEmpty()){
            Node curr = queue.poll();
            if(curr == list[verticies - 1]){
                break;
            }

            for(int i = 0; i < curr.neighborNum; i++){
                boolean update =
                    curr.neighbors.get(i).setWeight(curr.weight + curr.edges.get(i), curr);
                if(update){
                    queue.offer(curr.neighbors.get(i));
                }
            }
        }
        System.err.println("arrived2");
        Node temp = list[verticies - 1];
        String output = "";
        while(temp != list[0]){
            output = " " + temp.num + output;
            temp = temp.previous;
            if(temp == null){
                output = "-1";
                break;
            }
        }
        if(!output.equals("-1")){
            output = 1 + output;
        }
        System.out.println(output);
//// final long dist[] = new long[verticies];
//// Arrays.fill(dist, 10000000);
//// dist[0] = 0;
//// int[] prev = new int[verticies];
//
// System.out.println(Arrays.toString(list));
// PriorityQueue<Node> queue = new PriorityQueue<Node>();
//// for(Node i : list){
//// queue.offer(i);
//// }
//// System.out.println(queue.toString());
// queue.offer(list[0]);
//
// while(!queue.isEmpty()){
// Node curr = queue.poll();
//
// if(curr == list[verticies - 1]){
// // output = output + curr.num;
// break;
// }
// // output = output + curr.num + " ";
// System.out.println("current:" + curr.num + " " + curr.neighbors.toString());
// for(Node i : curr.neighbors){
//
// queue.offer(i);
// if(i.previous == null){
// i.previous = curr;
// }else if(i.weight -i.previous.weight > curr.weight){
// System.out.println("first: " + i.previous.weight);
// i.previous = curr;
// System.out.println("new: " + i.previous.weight);
// }
//
// }
// }
// System.out.println(list[verticies - 1].previous.num);
// String output = "";
// Node temp = list[verticies - 1];
// while(temp != list[0]){
// output = " " + temp.num + output;
// temp = temp.previous;
// }
// output = 1 + output;
// System.out.println(output);

    }

    public static class Node implements Comparable {
        int                num;
        long               weight;
        ArrayList<Node>    neighbors;
        ArrayList<Long> edges;
        Node               previous;
        boolean            visited;
        int                neighborNum;

        public Node(int nodeNum, long nodeWeight) {
            num = nodeNum;
            weight = nodeWeight;
            neighbors = new ArrayList<Node>();
            edges = new ArrayList<Long>();
            neighborNum = 0;
        }

        public void addNeighbor(Node neighbor, long edgeWeight) {
            neighbors.add(neighbor);
            edges.add(edgeWeight);
            neighborNum++;
        }

        public boolean setWeight(long nodeWeight, Node back) {
            if(nodeWeight < weight){
                weight = nodeWeight;
                previous = back;
                return true;
            }
            return false;
        }

        public void setPrevious(Node prev) {
            previous = prev;
        }

        public String toString() {
            return "" + num;
        }

        @Override
        public int compareTo(Object other) {
            Node temp = (Node)other;
            if(temp.weight != weight){
                return (int)(weight - temp.weight);
            }
            return num - temp.num;
        }
    }

    // -----------Scanner class for faster input----------
    /*
     * Provides similar API as java.util.Scanner but does not use regular
     * expression engine.
     */
    public static class Scanner {
        BufferedReader  br;
        StringTokenizer st;

        public Scanner(Reader in) {
            br = new BufferedReader(in);
        }

        public Scanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while(st == null || !st.hasMoreElements()){

                try{
                    st = new StringTokenizer(br.readLine());
                }catch(IOException e){
                    e.printStackTrace();
                }

            }

            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        // Slightly different from java.util.Scanner.nextLine(),
        // which returns any remaining characters in current line,
        // if any.
        String readNextLine() {
            String str = "";
            try{
                str = br.readLine();
            }catch(IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define boost ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin.exceptions(cin.failbit)
#define check(x) cout << #x << " : " << (x) << endl
#define all(v) v.begin(),v.end()
#define endl '\n'
#define show(a) for(auto i:a) cout<<i<<" ";cout<<endl
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int , int > mypair;
typedef priority_queue <mypair> max_heap;
typedef priority_queue <mypair, vector<mypair>, greater<mypair> > min_heap;
const ll inf=1e16;
const int mod=1e9+7;
const int N=5e5+10;

// Be careful range [L,R] give input [L,R+1] range is  >=L and <R in each function in Node
struct Node {
	Node *l = 0, *r = 0;
	int lo, hi;
	ll mset = inf, madd = 0, val = -inf;
	Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of -inf
	Node(vector<ll> & v, int lo, int hi) : lo(lo), hi(hi) {
		if (lo + 1 < hi) {
			int mid = lo + (hi - lo)/2;
			l = new Node(v, lo, mid); r = new Node(v, mid, hi);
			val = max(l->val, r->val);
		}
		else val = v[lo];
	}
	ll query(int L, int R) {  // range of i : L <= i < R
		if (R <= lo || hi <= L) return -inf;
		if (L <= lo && hi <= R) return val;
		push();
		return max(l->query(L, R), r->query(L, R));
	}
	void set(int L, int R, ll x) {  // range of i : L <= i < R
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) mset = val = x, madd = 0;
		else {
			push(), l->set(L, R, x), r->set(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void add(int L, int R, ll x) { // range of i : L <= i < R
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) {
			if (mset != inf) mset += x;
			else madd += x;
			val += x;
		}
		else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void push() {
		if (!l) {
			int mid = lo + (hi - lo)/2;
			l = new Node(lo, mid); r = new Node(mid, hi);
		}
		if (mset != inf)
			l->set(lo,hi,mset), r->set(lo,hi,mset), mset = inf;
		else if (madd)
			l->add(lo,hi,madd), r->add(lo,hi,madd), madd = 0;
	}
};

int main()
{
	boost;
	int n;
	cin>>n;
	std::vector<ll> p(n),a(n+1,0);
	for(auto &i:p) cin>>i;
	for(int i=0;i<n;i++)
	{
		ll x;
		cin>>x;
		a[p[i]]=x;
	}
	auto pref=a;
	for(int i=1;i<=n;i++) pref[i]+=pref[i-1];
	for(auto &i:pref) i=-i;
	Node *tree =new Node(pref,0,int(pref.size()));
	ll ans=inf;
	for(int i=0;i<n-1;i++)
	{
		(*tree).add(p[i],n+1,a[p[i]]);  // range of i : L <= i < R
		(*tree).add(0,p[i],-a[p[i]]);  // // range of i : L <= i < R
		ans=min(ans,abs((*tree).query(0,n+1)));  // range of i : L <= i < R
	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define boost ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin.exceptions(cin.failbit)
#define check(x) cout << #x << " : " << (x) << endl
#define all(v) v.begin(),v.end()
#define endl '\n'
#define show(a) for(auto i:a) cout<<i<<" ";cout<<endl
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int , int > mypair;
typedef priority_queue <mypair> max_heap;
typedef priority_queue <mypair, vector<mypair>, greater<mypair> > min_heap;
const ll inf=1e16;
const int mod=1e9+7;
const int N=5e5+10;

#pragma once

#include "../various/BumpAllocator.h"

struct Node {
	Node *l = 0, *r = 0;
	int lo, hi;
	ll mset = inf, madd = 0, val = -inf;
	Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of -inf
	Node(vector<ll> & v, int lo, int hi) : lo(lo), hi(hi) {
		if (lo + 1 < hi) {
			int mid = lo + (hi - lo)/2;
			l = new Node(v, lo, mid); r = new Node(v, mid, hi);
			val = max(l->val, r->val);
		}
		else val = v[lo];
	}
	ll query(int L, int R) {
		if (R <= lo || hi <= L) return -inf;
		if (L <= lo && hi <= R) return val;
		push();
		return max(l->query(L, R), r->query(L, R));
	}
	void set(int L, int R, ll x) {
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) mset = val = x, madd = 0;
		else {
			push(), l->set(L, R, x), r->set(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void add(int L, int R, ll x) {
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) {
			if (mset != inf) mset += x;
			else madd += x;
			val += x;
		}
		else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void push() {
		if (!l) {
			int mid = lo + (hi - lo)/2;
			l = new Node(lo, mid); r = new Node(mid, hi);
		}
		if (mset != inf)
			l->set(lo,hi,mset), r->set(lo,hi,mset), mset = inf;
		else if (madd)
			l->add(lo,hi,madd), r->add(lo,hi,madd), madd = 0;
	}
};

int main()
{
	boost;
	int n;
	cin>>n;
	std::vector<ll> p(n),a(n+1,0);
	for(auto &i:p) cin>>i;
	for(int i=0;i<n;i++)
	{
		ll x;
		cin>>x;
		a[p[i]]=x;
	}
	auto pref=a;
	for(int i=1;i<=n;i++) pref[i]+=pref[i-1];
	for(auto &i:pref) i=-i;
	Node *tree =new Node(pref,0,int(pref.size()));
	//show(pref);
	//check((*tree).query(0,n));
	ll ans=inf;
	//for(int i=0;i<=n;i++) cout<<(*tree).query(i,i+1)<<" ";cout<<endl;
	for(int i=0;i<n-1;i++)
	{
		(*tree).add(p[i],n+1,a[p[i]]);
		(*tree).add(0,p[i],-a[p[i]]);
		//for(int i=0;i<=n;i++) cout<<(*tree).query(i,i+1)<<" ";cout<<endl;
		ans=min(ans,abs((*tree).query(0,n+1)));
	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define boost ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin.exceptions(cin.failbit)
#define check(x) cout << #x << " : " << (x) << endl
#define all(v) v.begin(),v.end()
#define endl '\n'
#define show(a) for(auto i:a) cout<<i<<" ";cout<<endl
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int , int > mypair;
typedef priority_queue <mypair> max_heap;
typedef priority_queue <mypair, vector<mypair>, greater<mypair> > min_heap;
const ll inf=1e16;
const int mod=1e9+7;
const int N=5e5+10;

struct Node {
	Node *l = 0, *r = 0;
	int lo, hi;
	ll mset = inf, madd = 0, val = -inf;
	Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of -inf
	Node(vector<ll> & v, int lo, int hi) : lo(lo), hi(hi) {
		if (lo + 1 < hi) {
			int mid = lo + (hi - lo)/2;
			l = new Node(v, lo, mid); r = new Node(v, mid, hi);
			val = max(l->val, r->val);
		}
		else val = v[lo];
	}
	ll query(int L, int R) {
		if (R <= lo || hi <= L) return -inf;
		if (L <= lo && hi <= R) return val;
		push();
		return max(l->query(L, R), r->query(L, R));
	}
	void set(int L, int R, ll x) {
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) mset = val = x, madd = 0;
		else {
			push(), l->set(L, R, x), r->set(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void add(int L, int R, ll x) {
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) {
			if (mset != inf) mset += x;
			else madd += x;
			val += x;
		}
		else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void push() {
		if (!l) {
			int mid = lo + (hi - lo)/2;
			l = new Node(lo, mid); r = new Node(mid, hi);
		}
		if (mset != inf)
			l->set(lo,hi,mset), r->set(lo,hi,mset), mset = inf;
		else if (madd)
			l->add(lo,hi,madd), r->add(lo,hi,madd), madd = 0;
	}
};

int main()
{
	boost;
	int n;
	cin>>n;
	std::vector<ll> p(n),a(n+1,0);
	for(auto &i:p) cin>>i;
	for(int i=0;i<n;i++)
	{
		ll x;
		cin>>x;
		a[p[i]]=x;
	}
	auto pref=a;
	for(int i=1;i<=n;i++) pref[i]+=pref[i-1];
	for(auto &i:pref) i=-i;
	Node *tree =new Node(pref,0,int(pref.size()));
	//show(pref);
	//check((*tree).query(0,n));
	ll ans=inf;
	//for(int i=0;i<=n;i++) cout<<(*tree).query(i,i+1)<<" ";cout<<endl;
	for(int i=0;i<n-1;i++)
	{
		(*tree).add(p[i],n+1,a[p[i]]);
		(*tree).add(0,p[i],-a[p[i]]);
		//for(int i=0;i<=n;i++) cout<<(*tree).query(i,i+1)<<" ";cout<<endl;
		ans=min(ans,abs((*tree).query(0,n+1)));
	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define boost ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin.exceptions(cin.failbit)
#define check(x) cout << #x << " : " << (x) << endl
#define all(v) v.begin(),v.end()
#define endl '\n'
#define show(a) for(auto i:a) cout<<i<<" ";cout<<endl
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int , int > mypair;
typedef priority_queue <mypair> max_heap;
typedef priority_queue <mypair, vector<mypair>, greater<mypair> > min_heap;
const ll inf=1e16;
const int mod=1e9+7;
const int N=5e5+10;

struct Node {
	Node *l = 0, *r = 0;
	int lo, hi;
	ll mset = inf, madd = 0, val = -inf;
	Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of -inf
	Node(vector<ll> & v, int lo, int hi) : lo(lo), hi(hi) {
		if (lo + 1 < hi) {
			int mid = lo + (hi - lo)/2;
			l = new Node(v, lo, mid); r = new Node(v, mid, hi);
			val = max(l->val, r->val);
		}
		else val = v[lo];
	}
	ll query(int L, int R) {
		if (R <= lo || hi <= L) return -inf;
		if (L <= lo && hi <= R) return val;
		push();
		return max(l->query(L, R), r->query(L, R));
	}
	void set(int L, int R, int x) {
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) mset = val = x, madd = 0;
		else {
			push(), l->set(L, R, x), r->set(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void add(int L, int R, int x) {
		if (R <= lo || hi <= L) return;
		if (L <= lo && hi <= R) {
			if (mset != inf) mset += x;
			else madd += x;
			val += x;
		}
		else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = max(l->val, r->val);
		}
	}
	void push() {
		if (!l) {
			int mid = lo + (hi - lo)/2;
			l = new Node(lo, mid); r = new Node(mid, hi);
		}
		if (mset != inf)
			l->set(lo,hi,mset), r->set(lo,hi,mset), mset = inf;
		else if (madd)
			l->add(lo,hi,madd), r->add(lo,hi,madd), madd = 0;
	}
};

int main()
{
	boost;
	int n;
	cin>>n;
	std::vector<ll> p(n),a(n+1,0);
	for(auto &i:p) cin>>i;
	for(int i=0;i<n;i++)
	{
		ll x;
		cin>>x;
		a[p[i]]=x;
	}
	auto pref=a;
	for(int i=1;i<=n;i++) pref[i]+=pref[i-1];
	for(auto &i:pref) i=-i;
	Node *tree =new Node(pref,0,int(pref.size()));
	//show(pref);
	//check((*tree).query(0,n));
	ll ans=inf;
	//for(int i=0;i<=n;i++) cout<<(*tree).query(i,i+1)<<" ";cout<<endl;
	for(int i=0;i<n-1;i++)
	{
		(*tree).add(p[i],n+1,a[p[i]]);
		(*tree).add(0,p[i],-a[p[i]]);
		//for(int i=0;i<=n;i++) cout<<(*tree).query(i,i+1)<<" ";cout<<endl;
		ans=min(ans,abs((*tree).query(0,n+1)));
	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
#define adj_list vector<vi>
#define endl "\n"
#define INF_INT 2e9
#define INF_LL 2e18
#define matmax 25
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pi pair<int, int>
#define pii pair<int, pair<int, int> >
#define pl pair<ll, ll>
#define pll pair<ll, pair<ll, ll> >
#define vi vector<int>
#define vl vector<ll>
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long int ll;

int lsone(int n)
{
	return (n&-n);
}

ll pow1(ll a, ll b)
{
	if (b == 0)
		return 1ll;
	else if (b == 1)
		return a;
	else
	{
		ll x = pow1(a, b/2);
		x *= x;
		x %= mod;
		if (b%2)
		{
			x *= a;
			x %= mod;
		}
		return x;
	}
}

ll n, p[210000], a[210000], st[810000], aux[810000];

void update(int a, int b, int index, int l, int r, ll add) {
	if (a > r or b < l)
		return;
	if (l <= a and b <= r) {
		aux[index] += add;
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
		}
		update(a, (a+b)/2, 2*index, l, r, add);
		update((a+b)/2+1, b, 2*index+1, l, r, add);
		st[index] = min(st[2*index]+aux[2*index], st[2*index+1]+aux[2*index+1]);
	}
}

ll query(int a, int b, int index, int l, int r) {
	if (a > r or b < l)
		return 1e18;
	if (l <= a and b <= r) {
		return st[index] + aux[index];
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
			st[index] = min(st[2*index]+aux[2*index], st[2*index+1]+aux[2*index+1]);
		}
		return min(query(a, (a+b)/2, 2*index, l, r), query((a+b)/2+1, b, 2*index+1, l, r));
	}
}

int main()
{
	fastio;
	cin>>n;
	for (int i = 1; i <= n; i++) {
		cin>>p[i];
	}

	for (int i = 1; i <= n; i++) {
		cin>>a[p[i]];
	}

	for (int i = 1; i <= n; i++) {
		update(0, n, 1, p[i], n, a[p[i]]);
	}

	ll ans = 1e18;

	for (int i = 1; i < n; i++) {
		update(0, n, 1, 0, p[i]-1, a[p[i]]);
		update(0, n, 1, p[i], n, -a[p[i]]);
		ans = min(ans, query(0, n, 1, 0, n));
	}

	cout<<ans<<"\n";

	return 0;
}


#include <bits/stdc++.h>
#define adj_list vector<vi>
#define endl "\n"
#define INF_INT 2e9
#define INF_LL 2e18
#define matmax 25
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pi pair<int, int>
#define pii pair<int, pair<int, int> >
#define pl pair<ll, ll>
#define pll pair<ll, pair<ll, ll> >
#define vi vector<int>
#define vl vector<ll>
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long int ll;

int lsone(int n)
{
	return (n&-n);
}

ll pow1(ll a, ll b)
{
	if (b == 0)
		return 1ll;
	else if (b == 1)
		return a;
	else
	{
		ll x = pow1(a, b/2);
		x *= x;
		x %= mod;
		if (b%2)
		{
			x *= a;
			x %= mod;
		}
		return x;
	}
}

ll n, p[210000], a[210000], st[810000], aux[810000];

void update(int a, int b, int index, int l, int r, int add) {
	if (a > r or b < l)
		return;
	if (l <= a and b <= r) {
		aux[index] += add;
		return;
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
		}
		update(a, (a+b)/2, 2*index, l, r, add);
		update((a+b)/2+1, b, 2*index+1, l, r, add);
		st[index] = min(st[2*index]+aux[2*index], st[2*index+1]+aux[2*index+1]);
	}
}

ll query(int a, int b, int index, int l, int r) {
	if (a > r or b < l)
		return 1e18;
	if (l <= a and b <= r) {
		return st[index] + aux[index];
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
		}
		return min(query(a, (a+b)/2, 2*index, l, r), query((a+b)/2+1, b, 2*index+1, l, r));
	}
}

int main()
{
	fastio;
	cin>>n;
	for (int i = 1; i <= n; i++) {
		cin>>p[i];
	}

	for (int i = 1; i <= n; i++) {
		cin>>a[p[i]];
	}

	for (int i = 1; i <= n; i++) {
		update(0, n, 1, p[i], n, a[p[i]]);
	}

	ll ans = 1e18;

	for (int i = 1; i < n; i++) {
		update(0, n, 1, 0, p[i]-1, a[p[i]]);
		update(0, n, 1, p[i], n, -a[p[i]]);
		ans = min(ans, query(0, n, 1, 0, n));
	}

	cout<<ans<<"\n";

	return 0;
}


#include <bits/stdc++.h>
#define adj_list vector<vi>
#define endl "\n"
#define INF_INT 2e9
#define INF_LL 2e18
#define matmax 25
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pi pair<int, int>
#define pii pair<int, pair<int, int> >
#define pl pair<ll, ll>
#define pll pair<ll, pair<ll, ll> >
#define vi vector<int>
#define vl vector<ll>
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long int ll;

int lsone(int n)
{
	return (n&-n);
}

ll pow1(ll a, ll b)
{
	if (b == 0)
		return 1ll;
	else if (b == 1)
		return a;
	else
	{
		ll x = pow1(a, b/2);
		x *= x;
		x %= mod;
		if (b%2)
		{
			x *= a;
			x %= mod;
		}
		return x;
	}
}

ll n, p[210000], a[210000], st[810000], aux[810000];

void update(int a, int b, int index, int l, int r, int add) {
	if (a > r or b < l)
		return;
	if (l <= a and b <= r) {
		aux[index] += add;
		return;
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
		}
		update(a, (a+b)/2, 2*index, l, r, add);
		update((a+b)/2+1, b, 2*index+1, l, r, add);
		st[index] = min(st[2*index]+aux[2*index], st[2*index+1]+aux[2*index+1]);
	}
}

ll query(int a, int b, int index, int l, int r) {
	if (a > r or b < l)
		return 1e18;
	if (l <= a and b <= r) {
		return st[index] + aux[index];
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
		}
		return min(query(a, (a+b)/2, 2*index, l, r), query((a+b)/2+1, b, 2*index+1, l, r));
	}
}

int main()
{
	fastio;
	cin>>n;
	for (int i = 1; i <= n; i++) {
		cin>>p[i];
	}

	for (int i = 1; i <= n; i++) {
		cin>>a[p[i]];
	}

	for (int i = 1; i <= n; i++) {
		update(1, n, 1, p[i], n, a[p[i]]);
	}

	ll ans = 1e18;

	for (int i = 1; i < n; i++) {
		update(1, n, 1, 1, p[i]-1, a[p[i]]);
		update(1, n, 1, p[i], n, -a[p[i]]);
		ans = min(ans, query(1, n, 1, 1, n));
	}

	cout<<ans<<"\n";

	return 0;
}


#include <bits/stdc++.h>
#define adj_list vector<vi>
#define endl "\n"
#define INF_INT 2e9
#define INF_LL 2e18
#define matmax 25
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pi pair<int, int>
#define pii pair<int, pair<int, int> >
#define pl pair<ll, ll>
#define pll pair<ll, pair<ll, ll> >
#define vi vector<int>
#define vl vector<ll>
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long int ll;

int lsone(int n)
{
	return (n&-n);
}

ll pow1(ll a, ll b)
{
	if (b == 0)
		return 1ll;
	else if (b == 1)
		return a;
	else
	{
		ll x = pow1(a, b/2);
		x *= x;
		x %= mod;
		if (b%2)
		{
			x *= a;
			x %= mod;
		}
		return x;
	}
}

ll n, p[210000], a[210000], st[810000], aux[810000];

void update(int a, int b, int index, int l, int r, int add) {
	if (a > r or b < l)
		return;
	if (l <= a and b <= r) {
		aux[index] += add;
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
		}
		update(a, (a+b)/2, 2*index, l, r, add);
		update((a+b)/2+1, b, 2*index+1, l, r, add);
		st[index] = min(st[2*index]+aux[2*index], st[2*index+1]+aux[2*index+1]);
	}
}

ll query(int a, int b, int index, int l, int r) {
	if (a > r or b < l)
		return 1e18;
	if (l <= a and b <= r) {
		return st[index] + aux[index];
	} else {
		if (aux[index] != 0) {
			update(a, (a+b)/2, 2*index, a, (a+b)/2, aux[index]);
			update((a+b)/2+1, b, 2*index+1, (a+b)/2+1, b, aux[index]);
			aux[index] = 0;
			st[index] = min(st[2*index]+aux[2*index], st[2*index+1]+aux[2*index+1]);
		}
		return min(query(a, (a+b)/2, 2*index, l, r), query((a+b)/2+1, b, 2*index+1, l, r));
	}
}

int main()
{
	fastio;
	cin>>n;
	for (int i = 1; i <= n; i++) {
		cin>>p[i];
	}

	for (int i = 1; i <= n; i++) {
		cin>>a[p[i]];
	}

	for (int i = 1; i <= n; i++) {
		update(0, n, 1, p[i], n, a[p[i]]);
	}

	ll ans = 1e18;

	for (int i = 1; i < n; i++) {
		update(0, n, 1, 0, p[i]-1, a[p[i]]);
		update(0, n, 1, p[i], n, -a[p[i]]);
		ans = min(ans, query(0, n, 1, 0, n));
	}

	cout<<ans<<"\n";

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
ll pm[200005],a[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
  while (p > 1) p >>= 1, t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
      apply(i<<1, d[0][i],0);
      apply(i<<1|1, d[1][i],1);
      d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) apply(l++, value,tp);
    if (r&1) apply(--r, value,tp);
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) res = min(res, t[l++]);
    if (r&1) res = min(t[--r], res);
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    bool nflag = false;
    if(n0==182534){
        nflag = true;
    }
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        if(nflag&&myans<0){
            printf("ER: %lld %d\n",myans,i);
        }
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[200005];
int pm[200005],a[200005];

void apply(int p, ll value) {
  t[p] += value;
  if (p < n) d[p] += value;
}

void build(int p) {
  while (p > 1) p >>= 1, t[p] = min(t[p<<1], t[p<<1|1]) + d[p];
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[i] != 0) {
      apply(i<<1, d[i]);
      apply(i<<1|1, d[i]);
      d[i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) apply(l++, value);
    if (r&1) apply(--r, value);
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) res = min(res, t[l++]);
    if (r&1) res = min(t[--r], res);
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    for(int i = 1; i<=n0; i++)
        scanf("%d",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%d",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
ll pm[200005],a[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
  while (p > 1) p >>= 1, t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
      apply(i<<1, d[0][i],0);
      apply(i<<1|1, d[1][i],1);
      d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) apply(l++, value,tp);
    if (r&1) apply(--r, value,tp);
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) res = min(res, t[l++]);
    if (r&1) res = min(t[--r], res);
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
ll pm[200005],a[200005],rpm[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
    while (p > 1){
        p >>= 1;
        t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
    }
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
        apply(i<<1, d[0][i],0);
        apply(i<<1|1, d[1][i],1);
        d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1){
        apply(l, value,tp);
        l++;
    }
    if (r&1){
        --r;
        apply(r, value,tp);
    }
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1){
        res = min(res, t[l]);
        l++;
    }
    if (r&1){
        --r;
        res = min(t[r], res);
    }
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    bool nflag = false;
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        rpm[pm[i]] = i;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[rpm[i]];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
int pm[200005],a[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
  while (p > 1) p >>= 1, t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
      apply(i<<1, d[0][i],0);
      apply(i<<1|1, d[1][i],1);
      d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) apply(l++, value,tp);
    if (r&1) apply(--r, value,tp);
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) res = min(res, t[l++]);
    if (r&1) res = min(t[--r], res);
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    for(int i = 1; i<=n0; i++)
        scanf("%d",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%d",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
ll pm[200005],a[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
  while (p > 1) p >>= 1, t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
      apply(i<<1, d[0][i],0);
      apply(i<<1|1, d[1][i],1);
      d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) apply(l++, value,tp);
    if (r&1) apply(--r, value,tp);
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) res = min(res, t[l++]);
    if (r&1) res = min(t[--r], res);
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    if(n0==182534){
        printf("%d %d\n",n,h);
        return 0;
    }
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
ll pm[200005],a[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
    while (p > 1){
        p >>= 1;
        t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
    }
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
        apply(i<<1, d[0][i],0);
        apply(i<<1|1, d[1][i],1);
        d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1){
        apply(l, value,tp);
        l++;
    }
    if (r&1){
        --r;
        apply(r, value,tp);
    }
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1){
        res = min(res, t[l]);
        l++;
    }
    if (r&1){
        --r;
        res = min(t[r], res);
    }
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    bool nflag = false;
    if(n0==182534){
        nflag = true;
    }
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        if(nflag&&myans<0){
            printf("ER: %lld %d\n",myans,i);
        }
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n,h;
ll t[400005];
ll d[2][200005];
ll pm[200005],a[200005];

void apply(int p, ll value, int tp) {
  t[p] += value;
  if (p < n) d[tp][p] += value;
}

void build(int p) {
  while (p > 1) p >>= 1, t[p] = min(t[p<<1], t[p<<1|1]) + d[0][p]+d[1][p];
}

void push(int p) {
  for (int s = h; s > 0; --s) {
    int i = p >> s;
    if (d[0][i] != 0||d[1][i]!=0) {
      apply(i<<1, d[0][i],0);
      apply(i<<1|1, d[1][i],1);
      d[0][i] = d[1][i] = 0;
    }
  }
}

void inc(int l, int r, ll value) {
  l += n, r += n;
  int l0 = l, r0 = r;
  int tp = (value>0)?0:1;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) apply(l++, value,tp);
    if (r&1) apply(--r, value,tp);
  }
  build(l0);
  build(r0 - 1);
}

ll query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  ll res = 3000000000000000ll;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l&1) res = min(res, t[l++]);
    if (r&1) res = min(t[--r], res);
  }
  return res;
}

int main(){
    int n0;
    scanf("%d",&n0);
    n = n0+1;
    h = sizeof(int) * 8 - __builtin_clz(n);
    bool nflag = false;
    if(n0==182534){
        nflag = true;
    }
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&pm[i]);
    for(int i = 1; i<=n0; i++)
        scanf("%lld",&a[i]);
    t[n] = 0;
    for(int i = 1; i<=n0; i++)
        t[n+i] = t[n+i-1]+a[i];
    for(int i = n-1; i>0; i--)
        t[i] = min(t[i<<1],t[i<<1|1]);
    ll ans = 3000000000000000ll;
    for(int i = 1; i<n0; i++){
        inc(0,pm[i],a[i]);
        inc(pm[i],n,-a[i]);
        ll myans = query(0,n);
        if(nflag&&myans<0){
            printf("ER: %lld\n",myans);
        }
        ans = min(ans,myans);
    }
    printf("%lld\n",ans);
    return 0;
}


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

#include <x86intrin.h>
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define pf push_front
#define ppb pop_back
#define mp make_pair
#define bpp __builtin_popcountll
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define in insert
#define ppf pop_front
#define endl '\n'
#define int long long

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

const int mod = (int)1e9 + 7;
const int N = (int)3e5 + 123;
const ll inf = (ll)1e18 + 1;

const double pi = acos (-1.0);
const double eps = 1e-7;
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

int n, p[N], a[N], pref2[N], suff1[N], res[N], t[4 * N], used[4 * N], add[4 * N];

inline void push (int v, int tl, int tr) {
   t[v] += add[v];
   if (tl != tr) {
      add[v + v] += add[v];
      add[v + v + 1] += add[v];
   }
   add[v] = 0;
}

void update (int pos, int v = 1, int tl = 1, int tr = n) {
   push (v, tl, tr);
   if (tl == tr) {
      used[v] = 1;
      return;
   }
   int tm = tl + tr >> 1;
   if (pos <= tm) update (pos, v + v, tl, tm);
   else update (pos, v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = (used[v + v] | used[v + v + 1]);
}

void build (int v = 1, int tl = 1, int tr = n) {
   if (tl == tr) {
      t[v] = pref2[tl - 1];
      return;
   }
   int tm = tl + tr >> 1;
   build (v + v, tl, tm);
   build (v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = (used[v + v] | used[v + v + 1]);
}

void upd (int l, int r, int val, int v = 1, int tl = 1, int tr = n) {
   if (tl > r || tr < l) return;
   if (l <= tl && tr <= r) {
      add[v] += val;
      push (v, tl, tr);
      return;
   }
   int tm = tl + tr >> 1;
   upd (l, r, val, v + v, tl, tm);
   upd (l, r, val, v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = (used[v + v] | used[v + v + 1]);
}

inline void boost () {
   ios_base :: sync_with_stdio (NULL);
   cin.tie (NULL), cout.tie (NULL);
}

inline void Solve () {
   cin >> n;
   for (int i = 1; i <= n; i ++) cin >> p[i];
   for (int i = 1; i <= n; i ++) cin >> a[i], pref2[p[i]] += a[i];
   for (int i = 1; i <= n; i ++) pref2[i] += pref2[i - 1], res[i] = pref2[i - 1];
   build ();
   ll ans = inf;
   int sum = 0;
   for (int i = 1; i < n; i ++) {
      sum += a[i];
      upd (1, p[i] - 1, a[i]);
      upd (p[i] + 1, n, -a[i]);
      update (p[i]);
      if (t[1] >= 0) ans = min (ans, t[1]);
      ans = min (ans, sum);
   }
   cout << ans;
}

main () {
// freopen (".in", "r", stdin);
// freopen (".out", "w", stdout);
   boost ();
   int tt = 1;
   //cin >> tt;
   while (tt --) {
      Solve ();
   }
   return 0;
}


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

#include <x86intrin.h>
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define pf push_front
#define ppb pop_back
#define mp make_pair
#define bpp __builtin_popcountll
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define in insert
#define ppf pop_front
#define endl '\n'
#define int long long

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

const int mod = (int)1e9 + 7;
const int N = (int)3e5 + 123;
const ll inf = (ll)1e18 + 1;

const double pi = acos (-1.0);
const double eps = 1e-7;
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

int n, p[N], a[N], pref2[N], suff1[N], res[N], t[4 * N], used[4 * N], add[4 * N];

inline void push (int v, int tl, int tr) {
   if (!add[v] || !used[v]) return;
   t[v] += add[v];
   if (tl != tr) {
      add[v + v] += add[v];
      add[v + v + 1] += add[v];
   }
   add[v] = 0;
}

void update (int pos, int v = 1, int tl = 1, int tr = n) {
   push (v, tl, tr);
   if (tl == tr) {
      used[v] = 1;
      return;
   }
   int tm = tl + tr >> 1;
   if (pos <= tm) update (pos, v + v, tl, tm);
   else update (pos, v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = (used[v + v] | used[v + v + 1]);
}

void build (int v = 1, int tl = 1, int tr = n) {
   if (tl == tr) {
      t[v] = pref2[tl - 1];
      return;
   }
   int tm = tl + tr >> 1;
   build (v + v, tl, tm);
   build (v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = (used[v + v] | used[v + v + 1]);
}

void upd (int l, int r, int val, int v = 1, int tl = 1, int tr = n) {
   push (v, tl, tr);
   if (tl > r || tr < l) return;
   if (l <= tl && tr <= r) {
      add[v] += val;
      push (v, tl, tr);
      return;
   }
   int tm = tl + tr >> 1;
   upd (l, r, val, v + v, tl, tm);
   upd (l, r, val, v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = (used[v + v] | used[v + v + 1]);
}

inline void boost () {
   ios_base :: sync_with_stdio (NULL);
   cin.tie (NULL), cout.tie (NULL);
}

inline void Solve () {
   cin >> n;
   for (int i = 1; i <= n; i ++) cin >> p[i];
   for (int i = 1; i <= n; i ++) cin >> a[i], pref2[p[i]] += a[i];
   for (int i = 1; i <= n; i ++) pref2[i] += pref2[i - 1], res[i] = pref2[i - 1];
   build ();
   ll ans = inf;
   int sum = 0;
   for (int i = 1; i < n; i ++) {
      sum += a[i];
      update (p[i]);
      upd (1, p[i], a[i]);
      upd (p[i], n, -a[i]);
      if (t[1] >= 0) ans = min (ans, t[1]);
      ans = min (ans, sum);
   }
   cout << ans;
}

main () {
// freopen (".in", "r", stdin);
// freopen (".out", "w", stdout);
   boost ();
   int tt = 1;
   //cin >> tt;
   while (tt --) {
      Solve ();
   }
   return 0;
}


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

#include <x86intrin.h>
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define pf push_front
#define ppb pop_back
#define mp make_pair
#define bpp __builtin_popcountll
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define in insert
#define ppf pop_front
#define endl '\n'
#define int long long

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

const int mod = (int)1e9 + 7;
const int N = (int)3e5 + 123;
const ll inf = (ll)1e18 + 1;

const double pi = acos (-1.0);
const double eps = 1e-7;
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

int n, p[N], a[N], pref2[N], suff1[N], res[N], t[4 * N], used[4 * N], add[4 * N];

inline void push (int v, int tl, int tr) {
   t[v] += add[v];
   if (tl != tr) {
      add[v + v] += add[v];
      add[v + v + 1] += add[v];
   }
   add[v] = 0;
}

void update (int pos, int v = 1, int tl = 1, int tr = n) {
   push (v, tl, tr);
   if (tl == tr) {
      used[v] = 1;
      return;
   }
   int tm = tl + tr >> 1;
   if (pos <= tm) update (pos, v + v, tl, tm);
   else update (pos, v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = used[v + v] | used[v + v + 1];
}

void build (int v = 1, int tl = 1, int tr = n) {
   if (tl == tr) {
      t[v] = pref2[tl - 1];
      return;
   }
   int tm = tl + tr >> 1;
   build (v + v, tl, tm);
   build (v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
}

void upd (int l, int r, int val, int v = 1, int tl = 1, int tr = n) {
   if (tl > r || tr < l) return;
   if (l <= tl && tr <= r) {
      add[v] += val;
      push (v, tl, tr);
      return;
   }
   int tm = tl + tr >> 1;
   upd (l, r, val, v + v, tl, tm);
   upd (l, r, val, v + v + 1, tm + 1, tr);
}

inline void boost () {
   ios_base :: sync_with_stdio (NULL);
   cin.tie (NULL), cout.tie (NULL);
}

inline void Solve () {
   cin >> n;
   for (int i = 1; i <= n; i ++) cin >> p[i];
   for (int i = 1; i <= n; i ++) cin >> a[i], pref2[p[i]] += a[i];
   for (int i = 1; i <= n; i ++) pref2[i] += pref2[i - 1], res[i] = pref2[i - 1];
   build ();
   ll ans = inf;
   for (int i = 1; i < n; i ++) {
      upd (1, p[i] - 1, a[i]);
      upd (p[i] + 1, n, -a[i]);
      update (p[i]);
      if (t[1] >= 0) ans = min (ans, t[1]);
   }
   cout << ans;
}

main () {
// freopen (".in", "r", stdin);
// freopen (".out", "w", stdout);
   boost ();
   int tt = 1;
   //cin >> tt;
   while (tt --) {
      Solve ();
   }
   return 0;
}


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

#include <x86intrin.h>
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define pf push_front
#define ppb pop_back
#define mp make_pair
#define bpp __builtin_popcountll
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define in insert
#define ppf pop_front
#define endl '\n'
#define int long long

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

const int mod = (int)1e9 + 7;
const int N = (int)3e5 + 123;
const ll inf = (ll)1e18 + 1;

const double pi = acos (-1.0);
const double eps = 1e-7;
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};

int n, p[N], a[N], pref2[N], suff1[N], res[N], t[4 * N], used[4 * N], add[4 * N];

inline void push (int v, int tl, int tr) {
   t[v] += add[v];
   if (tl != tr) {
      add[v + v] += add[v];
      add[v + v + 1] += add[v];
   }
   add[v] = 0;
}

void update (int pos, int v = 1, int tl = 1, int tr = n) {
   push (v, tl, tr);
   if (tl == tr) {
      used[v] = 1;
      return;
   }
   int tm = tl + tr >> 1;
   if (pos <= tm) update (pos, v + v, tl, tm);
   else update (pos, v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
   used[v] = used[v + v] | used[v + v + 1];
}

void build (int v = 1, int tl = 1, int tr = n) {
   if (tl == tr) {
      t[v] = pref2[tl - 1];
      return;
   }
   int tm = tl + tr >> 1;
   build (v + v, tl, tm);
   build (v + v + 1, tm + 1, tr);
   t[v] = min ((used[v + v] ? t[v + v] : inf), (used[v + v + 1] ? t[v + v + 1] : inf));
}

void upd (int l, int r, int val, int v = 1, int tl = 1, int tr = n) {
   if (tl > r || tr < l) return;
   if (l <= tl && tr <= r) {
      add[v] += val;
      push (v, tl, tr);
      return;
   }
   int tm = tl + tr >> 1;
   upd (l, r, val, v + v, tl, tm);
   upd (l, r, val, v + v + 1, tm + 1, tr);
}

inline void boost () {
   ios_base :: sync_with_stdio (NULL);
   cin.tie (NULL), cout.tie (NULL);
}

inline void Solve () {
   cin >> n;
   for (int i = 1; i <= n; i ++) cin >> p[i];
   for (int i = 1; i <= n; i ++) cin >> a[i], pref2[p[i]] += a[i];
   for (int i = 1; i <= n; i ++) pref2[i] += pref2[i - 1], res[i] = pref2[i - 1];
   build ();
   ll ans = inf;
   int sum = 0;
   for (int i = 1; i < n; i ++) {
      sum += a[i];
      upd (1, p[i] - 1, a[i]);
      upd (p[i] + 1, n, -a[i]);
      update (p[i]);
      if (t[1] >= 0) ans = min (ans, t[1]);
      ans = min (ans, sum);
   }
   cout << ans;
}

main () {
// freopen (".in", "r", stdin);
// freopen (".out", "w", stdout);
   boost ();
   int tt = 1;
   //cin >> tt;
   while (tt --) {
      Solve ();
   }
   return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 220000;

int p[N], a[N];

struct Node {
	long long Min, add;
} node[1 << 20];

inline void update(int id, long long add) {
	node[id].Min += add, node[id].add += add;
}

inline void down(int id) {
	if (node[id].add) {
		update(id + id, node[id].add);
		update(id + id + 1, node[id].add);
		node[id].add = 0;
	}
}

inline void up(int id) {
	node[id].Min = min(node[id + id].Min, node[id + id + 1].Min);
}

inline void modify(int id, int st, int en, int l, int r, long long add) {
	if (l > r) return;
	if (l <= st && en <= r) {
		update(id, add);
		return;
	}
	down(id);
	int mid = st + en >> 1;
	if (l <= mid) modify(id + id, st, mid, l, r, add);
	if (r > mid) modify(id + id + 1, mid + 1, en, l, r, add);
	up(id);
}

int main() {

	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);

	int n; cin >> n;
	for (int i = 1; i <= n; i++) cin >> p[i];
	for (int i = 1; i <= n; i++) cin >> a[p[i]];

	for (int i = 1; i <= n; i++) modify(1, 1, n, i, n, a[i]);

	long long ans = 1LL << 60;
	for (int i = 1; i < n; i++) {
		modify(1, 1, n, p[i], n, -a[p[i]]);
		modify(1, 1, n, 1, p[i] - 1, a[p[i]]);
		ans = min(ans, (long long)node[1].Min);cerr<<ans<<endl;
	}
	if (n == 1) ans = 0;
	long long sum = 0;
	for (int i = 1; i < n; i++) {
		sum += a[p[i]];
		ans = min(ans, sum);
	}
	cout << ans << "\n";

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MX 200050
typedef long long ll;
int p[MX], a[MX];
ll b[MX], val[MX * 4], add[MX * 4];
int pos[MX], cost[MX];

void up(int u) {
	val[u] = min(val[u + u], val[u + u + 1]);
}

void renew(int u, ll x) {
	val[u] += x;
	add[u] += x;
}

void down(int u) {
	if(!add[u]) return;
	renew(u + u, add[u]);
	renew(u + u + 1, add[u]);
	add[u] = 0;
}

void build(int u, int l, int r) {
	if(l == r) {
		val[u] = b[l];
		return;
	}
	int mid = l + r >> 1;
	build(u + u, l, mid);
	build(u + u + 1, mid + 1, r);
	up(u);
}

void modify(int u, int l, int r, int st, int ed, ll x) {
	if(st > ed) return;
	if (st <= l && r <= ed) {
		renew(u, x);
		return;
	}
	int mid = l + r >> 1;
	down(u);
	if (st <= mid) modify(u + u, l, mid, st, ed, x);
	if (mid < ed) modify(u + u + 1, mid + 1, r, st, ed, x);
	up(u);
}

ll query(int u, int l, int r, int st, int ed) {
	if(st > ed) return LLONG_MAX;
	if (st <= l && r <= ed) return val[u];
	int mid = l + r >> 1;
	ll ret = LLONG_MAX;
	down(u);
	if (st <= mid) ret = min(ret, query(u + u, l, mid, st, ed));
	if (mid < ed) ret = min(ret, query(u + u + 1, mid + 1, r, st, ed));
	return ret;
}

int main() {
	int n; scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d", p + i);
		pos[p[i]] = i;
	}
	for(int i = 1; i <= n; i++) {
		scanf("%d", a + i);
		cost[p[i]] = a[i];
	}
	for(int i = 1; i <= n; i++) b[i] = b[i - 1] + a[i];
	build(1, 1, n);
	ll res = LLONG_MAX;
	for(int i = 1; i <= n; i++) {
		res = min(res, query(1, 1, n, 1, n - 1));
		modify(1, 1, n, 1, pos[i] - 1, cost[i]);
		modify(1, 1, n, pos[i], n, -cost[i]);
	}
	res = min(res, query(1, 1, n, 1, n - 1));
	printf("%lld\n", res);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const long long inf = 1e18;
const int MAXN = 200005;
ll p[MAXN], a[MAXN];

ll xmin[MAXN], dn[MAXN];
ll sum[MAXN];

void up(int u) {
	xmin[u] = min(xmin[u + u], xmin[u + u + 1]);
}

void renew(int u, ll x) {
	xmin[u] += x, dn[u] += x;
}

void down(int u) {
	if (!dn[u]) return;
	renew(u + u, dn[u]);
	renew(u + u + 1, dn[u]);
	dn[u] = 0;
}

void build(int u, int l, int r, ll *a) {
	dn[u] = 0;
	if (l == r) {
		xmin[u] = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(u + u, l, mid, a);
	build(1 + u + u, mid + 1, r, a);
	up(u);
}

void modify(int u, int l, int r, int ll, int rr, int x) {
	if (ll <= l && r <= rr) {
		renew(u, x);
		return;
	}
	int mid = l + r >> 1;
	down(u);
	if (ll <= mid) modify(u + u, l, mid, ll, rr, x);
	if (mid < rr) modify(u + u + 1, mid + 1, r, ll, rr, x);
	up(u);
}

ll query(int u, int l, int r, int ll, int rr) {
	if (ll <= l && r <= rr) return xmin[u];
	int mid = l + r >> 1;
	long long ret = inf;
	down(u);
	if (ll <= mid) ret = min(ret, query(u + u, l, mid, ll, rr));
	if (mid < rr) ret = min(ret, query(u + u + 1, mid + 1, r, ll, rr));
	return ret;
}

int pos[MAXN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; i ++) cin >> p[i];
	for(int i = 0; i < n; i ++){
		pos[p[i]] = i;
	}
	for(int i = 0; i < n; i ++) cin >> a[i];
	ll cur = 0;
	for(int i = 0; i < n - 1; i ++){
		cur += a[i];
		sum[i + 1] = cur;
	}
	build(1, 1, n - 1, sum);
	ll ans = inf;
	ans = min(ans, query(1, 1, n - 1, 1, n - 1));
	for(int i = 1; i <= n; i ++){
		int tmp = pos[i];
		if(tmp >= 1) modify(1, 1, n - 1, 1, tmp, a[tmp]);
		if(n - 1 >= tmp + 1) modify(1, 1, n - 1, tmp + 1, n - 1, -a[tmp]);
		ans = min(ans, query(1, 1, n - 1, 1, n - 1));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const long long inf = 1e18;
const int MAXN = 100005;
ll p[MAXN], a[MAXN];

ll xmin[MAXN], dn[MAXN];
ll sum[MAXN];

void up(int u) {
	xmin[u] = min(xmin[u + u], xmin[u + u + 1]);
}

void renew(int u, ll x) {
	xmin[u] += x, dn[u] += x;
}

void down(int u) {
	if (!dn[u]) return;
	renew(u + u, dn[u]);
	renew(u + u + 1, dn[u]);
	dn[u] = 0;
}

void build(int u, int l, int r, ll *a) {
	dn[u] = 0;
	if (l == r) {
		xmin[u] = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(u + u, l, mid, a);
	build(1 + u + u, mid + 1, r, a);
	up(u);
}

void modify(int u, int l, int r, int ll, int rr, int x) {
	if (ll <= l && r <= rr) {
		renew(u, x);
		return;
	}
	int mid = l + r >> 1;
	down(u);
	if (ll <= mid) modify(u + u, l, mid, ll, rr, x);
	if (mid < rr) modify(u + u + 1, mid + 1, r, ll, rr, x);
	up(u);
}

ll query(int u, int l, int r, int ll, int rr) {
	if (ll <= l && r <= rr) return xmin[u];
	int mid = l + r >> 1;
	long long ret = inf;
	down(u);
	if (ll <= mid) ret = min(ret, query(u + u, l, mid, ll, rr));
	if (mid < rr) ret = min(ret, query(u + u + 1, mid + 1, r, ll, rr));
	return ret;
}

int pos[MAXN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; i ++) cin >> p[i];
	for(int i = 0; i < n; i ++){
		pos[p[i]] = i;
	}
	for(int i = 0; i < n; i ++) cin >> a[i];
	ll cur = 0;
	for(int i = 0; i < n - 1; i ++){
		cur += a[i];
		sum[i + 1] = cur;
	}
	build(1, 1, n - 1, sum);
	ll ans = inf;
	for(int i = 1; i <= n; i ++){
		int tmp = pos[i];
		if(tmp >= 1) modify(1, 1, n - 1, 1, tmp, a[tmp]);
		if(n - 1 >= tmp + 1) modify(1, 1, n - 1, tmp + 1, n - 1, -a[tmp]);
		ans = min(ans, query(1, 1, n - 1, 1, n - 1));
	}
	cout << ans << '\n';
	return 0;
}