Related Articles

# Maximum pair sum in the given index ranges of an Array

• Difficulty Level : Medium
• Last Updated : 17 Aug, 2020

Given an array arr containing N positive integers and the number of queries Q, for each query task is to find the maximum pair sum in the given index range [L, R] where L and R are the respective low and high indices.

Examples:

Input: arr = {3, 4, 5, 6, 7, 8}, Q[] = [[0, 3], [3, 5]]
Output:
11
15
Explanation:
For the first query, subarray is [3, 4, 5, 6]
All the pairs are (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)
Hence the maximum pair sum = (5 + 6) = 11
For the second query, subarray is [6, 7, 8]
All the pairs of the subarray are (6, 7), (6, 8), (7, 8)
Hence the maximum pair sum = (7 + 8) = 15

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach: For each query range, do the following

1. Find the maximum and the second maximum in the given query range.
2. Sum of maximum and second maximum will be the maximum pair sum of the given range.

Below is the implementation of the above approach:

## C++

 `// C++ program to find maximum``// pair sum in the given``// index range of an Array``#include ``using` `namespace` `std;`` ` `// Node structure to store a query``struct` `node {``    ``int` `f;``    ``int` `s;``};`` ` `// Function to find the required sum``void` `findSum(``int``* arr, ``int` `n,``             ``int` `Q, node* query)``{`` ` `    ``// Run a loop to iterate``    ``// over query array``    ``for` `(``int` `i = 0; i < Q; i++) {`` ` `        ``// declare first 'f'``        ``// and second 's' variables``        ``int` `f, s;`` ` `        ``// Initialise them with 0``        ``f = s = 0;`` ` `        ``// Iterate over the``        ``// given array from``        ``// range query[i].f to query[i].s``        ``for` `(``int` `j = query[i].f;``             ``j <= query[i].s;``             ``j++) {`` ` `            ``// If the array element``            ``// value is greater than``            ``// current f, store``            ``// current f in s and``            ``// array element value in f``            ``if` `(arr[j] >= f) {``                ``s = f;`` ` `                ``f = arr[j];``            ``}``            ``// else if element``            ``// is greater than s,``            ``// update s with``            ``// array element value``            ``else` `if` `(arr[j] > s)``                ``s = arr[j];``        ``}`` ` `        ``// print the sum of f and s``        ``cout << (f + s) << endl;``    ``}``}`` ` `// Driver code``int` `main()``{``    ``// Given array and number of queries``    ``int` `arr[] = { 3, 4, 5, 6, 7, 8 }, Q = 2;``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);`` ` `    ``// Declare and define queries``    ``node query[Q];``    ``query = { 0, 3 };``    ``query = { 3, 5 };`` ` `    ``findSum(arr, n, Q, query);``}`

## Java

 `// Java program to find maximum``// pair sum in the given``// index range of an Array``class` `GFG{``  ` `// Node structure to store a query``static` `class` `node {``    ``int` `f;``    ``int` `s;``    ``public` `node(``int` `f, ``int` `s) {``        ``this``.f = f;``        ``this``.s = s;``    ``}``     ` `};``  ` `// Function to find the required sum``static` `void` `findSum(``int` `[]arr, ``int` `n,``             ``int` `Q, node []query)``{``  ` `    ``// Run a loop to iterate``    ``// over query array``    ``for` `(``int` `i = ``0``; i < Q; i++) {``  ` `        ``// declare first 'f'``        ``// and second 's' variables``        ``int` `f, s;``  ` `        ``// Initialise them with 0``        ``f = s = ``0``;``  ` `        ``// Iterate over the``        ``// given array from``        ``// range query[i].f to query[i].s``        ``for` `(``int` `j = query[i].f;``             ``j <= query[i].s;``             ``j++) {``  ` `            ``// If the array element``            ``// value is greater than``            ``// current f, store``            ``// current f in s and``            ``// array element value in f``            ``if` `(arr[j] >= f) {``                ``s = f;``  ` `                ``f = arr[j];``            ``}``            ``// else if element``            ``// is greater than s,``            ``// update s with``            ``// array element value``            ``else` `if` `(arr[j] > s)``                ``s = arr[j];``        ``}``  ` `        ``// print the sum of f and s``        ``System.out.print((f + s) +``"\n"``);``    ``}``}``  ` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``// Given array and number of queries``    ``int` `arr[] = { ``3``, ``4``, ``5``, ``6``, ``7``, ``8` `}, Q = ``2``;``    ``int` `n = arr.length;``  ` `    ``// Declare and define queries``    ``node []query = ``new` `node[``2``];``    ``query[``0``] = ``new` `node( ``0``, ``3` `);``    ``query[``1``] =  ``new` `node(``3``, ``5` `);``  ` `    ``findSum(arr, n, Q, query);``}``}`` ` `// This code is contributed by PrinciRaj1992`

## C#

 `// C# program to find maximum``// pair sum in the given``// index range of an Array``using` `System;`` ` `class` `GFG{``   ` `// Node structure to store a query``class` `node {``    ``public` `int` `f;``    ``public` `int` `s;``    ``public` `node(``int` `f, ``int` `s) {``        ``this``.f = f;``        ``this``.s = s;``    ``}``      ` `};``   ` `// Function to find the required sum``static` `void` `findSum(``int` `[]arr, ``int` `n,``             ``int` `Q, node []query)``{``   ` `    ``// Run a loop to iterate``    ``// over query array``    ``for` `(``int` `i = 0; i < Q; i++) {``   ` `        ``// declare first 'f'``        ``// and second 's' variables``        ``int` `f, s;``   ` `        ``// Initialise them with 0``        ``f = s = 0;``   ` `        ``// Iterate over the``        ``// given array from``        ``// range query[i].f to query[i].s``        ``for` `(``int` `j = query[i].f;``             ``j <= query[i].s;``             ``j++) {``   ` `            ``// If the array element``            ``// value is greater than``            ``// current f, store``            ``// current f in s and``            ``// array element value in f``            ``if` `(arr[j] >= f) {``                ``s = f;``   ` `                ``f = arr[j];``            ``}``            ``// else if element``            ``// is greater than s,``            ``// update s with``            ``// array element value``            ``else` `if` `(arr[j] > s)``                ``s = arr[j];``        ``}``   ` `        ``// print the sum of f and s``        ``Console.Write((f + s) +``"\n"``);``    ``}``}``   ` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``// Given array and number of queries``    ``int` `[]arr = { 3, 4, 5, 6, 7, 8 };``    ``int` `Q = 2;``    ``int` `n = arr.Length;``   ` `    ``// Declare and define queries``    ``node []query = ``new` `node;``    ``query = ``new` `node( 0, 3 );``    ``query =  ``new` `node(3, 5 );``   ` `    ``findSum(arr, n, Q, query);``}``}``  ` `// This code is contributed by PrinciRaj1992`
Output:
```11
15
```

Performance Analysis:

• Time Complexity: In the above approach, we are looper over the array of length N for each of Q query. Thus the time complexity would be O(N*Q).
• Auxiliary Space: In the above approach there is no extra space used, therefore the Auxiliary Space complexity will be O(1).

Efficient Approach: The idea is to use the segment tree where each node of the segment tree store two values:

• Maximum of the given below subtree
• Second maximum of the given below subtree

Algorithm to build the required segment tree

1. If size of the array is 1, then we simply store first max=arr[start] and second max=0 where start is the index of the array.
2. Else
• Recursively determine the firstMax`(l1)` and the second max`(l2)` for the left half of the array.
• Recursively determine the firstMax`(r1)` and the second max`(r2)` for the right half of the array.
3. Now we will determine the first max and the second max of the present node as
`firstMax=max(l1, r1)` and `secondMax=max(min(l1, r1), max(l2, r2))`

Algorithm for the Query to find maximum pair sum of given range

1. If the range of the node is within l and r then return the value of the present
node
2. else if the range of the node is completely outside l and r then return 0
3. else recursively find `first max(l1)` and `second max(l2)` from
left half and the `firstMax(r1)` and the `secondMax(r2)` from the right
half.

4. return the `max(l1, r1) and max(min(l1, r1), max(l2, r2)).`

Below is the implementation of the above approach:

## CPP

 `// C++ program to find maximum``// pair sum in the given``// index range of an Array`` ` `#include ``using` `namespace` `std;`` ` `// Node structure to store a query``struct` `node {``    ``int` `f;``    ``int` `s;``};`` ` `// Function to build the tree``void` `build(``    ``int` `arr[], node tree[],``    ``int` `start, ``int` `end,``    ``int` `index)``{``    ``// If there is just one element``    ``// in the array range,``    ``// set maximum as that element,``    ``// and second maximum as zero``    ``if` `(start == end) {``        ``tree[index].f = arr[start];`` ` `        ``tree[index].s = 0;`` ` `        ``return``;``    ``}`` ` `    ``// Calculate the mid value``    ``int` `mid = start + (end - start) / 2;`` ` `    ``// Recursively build the tree``    ``// for the range [start, mid]``    ``// and store the value``    ``// at index (2 * index + 1)``    ``build(``        ``arr, tree, start,``        ``mid, 2 * index + 1);`` ` `    ``// Recursively build the tree``    ``// for the range [mid + 1, end]``    ``// and store the value``    ``// at index (2 * index + 2)``    ``build(``        ``arr, tree, mid + 1,``        ``end, 2 * index + 2);`` ` `    ``// Get the maximum and``    ``// second maximum from``    ``// both left and right subtrees``    ``int` `l1 = tree[2 * index + 1].f;``    ``int` `l2 = tree[2 * index + 1].s;``    ``int` `r1 = tree[2 * index + 2].f;``    ``int` `r2 = tree[2 * index + 2].s;`` ` `    ``// Set the maximum for this node as``    ``// maximum of l1 and r1``    ``tree[index].f = max(l1, r1);`` ` `    ``// Set the second maximum for this``    ``// node as maximum of``    ``// min(l1, r1) & max(l2, r2)``    ``tree[index].s``        ``= max(min(l1, r1),``              ``max(l2, r2));``}`` ` `// Function to execute a``// query on the segment tree``node runQuery(``    ``node tree[], ``int` `start,``    ``int` `end, ``int` `index,``    ``int` `L, ``int` `R)``{``    ``// If the range of``    ``// the node is completely``    ``// outside l and r then return 0``    ``if` `(R < start or L > end) {``        ``return` `{ 0, 0 };``    ``}`` ` `    ``// If the range of the``    ``// node is within l and r``    ``// then return the value``    ``// of the present node``    ``if` `(L <= start and R >= end) {``        ``return` `tree[index];``    ``}`` ` `    ``// calculate mid value``    ``int` `mid = start + (end - start) / 2;`` ` `    ``// Recursively find first``    ``// max and second max from``    ``// the left half``    ``node Left``        ``= runQuery(``            ``tree, start,``            ``mid, 2 * index + 1,``            ``L, R);`` ` `    ``// Recursively find first``    ``// max and second max from``    ``// the right half``    ``node Right``        ``= runQuery(``            ``tree, mid + 1,``            ``end, 2 * index + 2,``            ``L, R);`` ` `    ``// Get the values``    ``// of l1, l2, r1, r2``    ``int` `l1 = Left.f;``    ``int` `l2 = Left.s;``    ``int` `r1 = Right.f;``    ``int` `r2 = Right.s;`` ` `    ``// return the maximum``    ``// as max(l1, r1), and``    ``// second maximum as``    ``// max(min(l1, r1), max(l2, r2))``    ``return` `{ max(l1, r1),``             ``max(min(l1, r1),``                 ``max(l2, r2)) };``}`` ` `// Function to find the required sum``void` `findSum(``int``* arr, ``int` `n,``             ``int` `Q, node* query)``{`` ` `    ``// Declare an array of``    ``// length '4 * n + 1' and``    ``// build the tree``    ``node tree[4 * n + 1];``    ``build(arr, tree, 0, n - 1, 0);`` ` `    ``// Run a loop to iterate``    ``// over each query``    ``for` `(``int` `i = 0; i < Q; i++) {`` ` `        ``// Call the query function``        ``// with given range``        ``node temp``            ``= runQuery(``                ``tree, 0,``                ``n - 1, 0,``                ``query[i].f,``                ``query[i].s);`` ` `        ``// Store maximum and second``        ``// maximum in variables``        ``int` `f = temp.f;``        ``int` `s = temp.s;`` ` `        ``// Return sum of the maximum``        ``// and second maximum``        ``cout << (f + s) << endl;``    ``}``}`` ` `// Driver code``int` `main()``{``    ``// Given array and number of queries``    ``int` `arr[] = { 3, 4, 5, 6, 7, 8 }, Q = 2;`` ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);`` ` `    ``// Declare and define queries``    ``node query[Q];``    ``query = { 0, 3 };``    ``query = { 3, 5 };`` ` `    ``findSum(arr, n, Q, query);``}`

## Java

 `// Java program to find maximum``// pair sum in the given``// index range of an Array``class` `GFG{``  ` `// Node structure to store a query``static` `class` `node {``    ``int` `f;``    ``int` `s;``    ``public` `node(``int` `f, ``int` `s) {``        ``this``.f = f;``        ``this``.s = s;``    ``}``    ``public` `node() {``        ``// TODO Auto-generated constructor stub``    ``}``     ` `};``  ` `// Function to build the tree``static` `void` `build(``    ``int` `arr[], node tree[],``    ``int` `start, ``int` `end,``    ``int` `index)``{``    ``// If there is just one element``    ``// in the array range,``    ``// set maximum as that element,``    ``// and second maximum as zero``    ``if` `(start == end ) {``        ``tree[index].f = arr[start];``  ` `        ``tree[index].s = ``0``;``  ` `        ``return``;``    ``}``  ` `    ``// Calculate the mid value``    ``int` `mid = start + (end - start) / ``2``;``  ` `    ``// Recursively build the tree``    ``// for the range [start, mid]``    ``// and store the value``    ``// at index (2 * index + 1)``    ``build(``        ``arr, tree, start,``        ``mid, ``2` `* index + ``1``);``  ` `    ``// Recursively build the tree``    ``// for the range [mid + 1, end]``    ``// and store the value``    ``// at index (2 * index + 2)``    ``build(``        ``arr, tree, mid + ``1``,``        ``end, ``2` `* index + ``2``);``  ` `    ``// Get the maximum and``    ``// second maximum from``    ``// both left and right subtrees``    ``int` `l1 = tree[``2` `* index + ``1``].f;``    ``int` `l2 = tree[``2` `* index + ``1``].s;``    ``int` `r1 = tree[``2` `* index + ``2``].f;``    ``int` `r2 = tree[``2` `* index + ``2``].s;``  ` `    ``// Set the maximum for this node as``    ``// maximum of l1 and r1``    ``tree[index].f = Math.max(l1, r1);``  ` `    ``// Set the second maximum for this``    ``// node as maximum of``    ``// Math.min(l1, r1) & Math.max(l2, r2)``    ``tree[index].s``        ``= Math.max(Math.min(l1, r1),``              ``Math.max(l2, r2));``}``  ` `// Function to execute a``// query on the segment tree``static` `node runQuery(``    ``node tree[], ``int` `start,``    ``int` `end, ``int` `index,``    ``int` `L, ``int` `R)``{``    ``// If the range of``    ``// the node is completely``    ``// outside l and r then return 0``    ``if` `(R < start || L > end) {``        ``return` `new` `node( ``0``, ``0` `);``    ``}``  ` `    ``// If the range of the``    ``// node is within l and r``    ``// then return the value``    ``// of the present node``    ``if` `(L <= start && R >= end) {``        ``return` `tree[index];``    ``}``  ` `    ``// calculate mid value``    ``int` `mid = start + (end - start) / ``2``;``  ` `    ``// Recursively find first``    ``// max and second max from``    ``// the left half``    ``node Left``        ``= runQuery(``            ``tree, start,``            ``mid, ``2` `* index + ``1``,``            ``L, R);``  ` `    ``// Recursively find first``    ``// max and second max from``    ``// the right half``    ``node Right``        ``= runQuery(``            ``tree, mid + ``1``,``            ``end, ``2` `* index + ``2``,``            ``L, R);``  ` `    ``// Get the values``    ``// of l1, l2, r1, r2``    ``int` `l1 = Left.f;``    ``int` `l2 = Left.s;``    ``int` `r1 = Right.f;``    ``int` `r2 = Right.s;``  ` `    ``// return the maximum``    ``// as Math.max(l1, r1), and``    ``// second maximum as``    ``// Math.max(Math.min(l1, r1), Math.max(l2, r2))``    ``return` `new` `node( Math.max(l1, r1),``             ``Math.max(Math.min(l1, r1),``                 ``Math.max(l2, r2)) );``}``  ` `// Function to find the required sum``static` `void` `findSum(``int` `[]arr, ``int` `n,``             ``int` `Q, node []query)``{``  ` `    ``// Declare an array of``    ``// length '4 * n + 1' and``    ``// build the tree``    ``node []tree = ``new` `node[``4` `* n + ``1``];``    ``for``(``int` `i=``0``;i<``4` `* n + ``1``;i++) {``        ``tree[i] = ``new` `node();``    ``}``    ``build(arr, tree, ``0``, n - ``1``, ``0``);``  ` `    ``// Run a loop to iterate``    ``// over each query``    ``for` `(``int` `i = ``0``; i < Q; i++) {``  ` `        ``// Call the query function``        ``// with given range``        ``node temp``            ``= runQuery(``                ``tree, ``0``,``                ``n - ``1``, ``0``,``                ``query[i].f,``                ``query[i].s);``  ` `        ``// Store maximum and second``        ``// maximum in variables``        ``int` `f = temp.f;``        ``int` `s = temp.s;``  ` `        ``// Return sum of the maximum``        ``// and second maximum``        ``System.out.print((f + s) +``"\n"``);``    ``}``}``  ` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``// Given array and number of queries``    ``int` `arr[] = { ``3``, ``4``, ``5``, ``6``, ``7``, ``8` `}, Q = ``2``;``  ` `    ``int` `n = arr.length;``  ` `    ``// Declare and define queries``    ``node []query = ``new` `node[Q];``    ``query[``0``] = ``new` `node( ``0``, ``3` `);``    ``query[``1``] = ``new` `node( ``3``, ``5` `);``  ` `    ``findSum(arr, n, Q, query);``}``}`` ` `// This code is contributed by Princi Singh`

## C#

 `// C# program to find maximum``// pair sum in the given``// index range of an Array``using` `System;`` ` `class` `GFG{``   ` `// Node structure to store a query``class` `node {``    ``public` `int` `f;``    ``public` `int` `s;``    ``public` `node(``int` `f, ``int` `s) {``        ``this``.f = f;``        ``this``.s = s;``    ``}``    ``public` `node() {``        ``// TODO Auto-generated constructor stub``    ``}``      ` `};``   ` `// Function to build the tree``static` `void` `build(``    ``int` `[]arr, node []tree,``    ``int` `start, ``int` `end,``    ``int` `index)``{``    ``// If there is just one element``    ``// in the array range,``    ``// set maximum as that element,``    ``// and second maximum as zero``    ``if` `(start == end ) {``        ``tree[index].f = arr[start];``   ` `        ``tree[index].s = 0;``   ` `        ``return``;``    ``}``   ` `    ``// Calculate the mid value``    ``int` `mid = start + (end - start) / 2;``   ` `    ``// Recursively build the tree``    ``// for the range [start, mid]``    ``// and store the value``    ``// at index (2 * index + 1)``    ``build(``        ``arr, tree, start,``        ``mid, 2 * index + 1);``   ` `    ``// Recursively build the tree``    ``// for the range [mid + 1, end]``    ``// and store the value``    ``// at index (2 * index + 2)``    ``build(``        ``arr, tree, mid + 1,``        ``end, 2 * index + 2);``   ` `    ``// Get the maximum and``    ``// second maximum from``    ``// both left and right subtrees``    ``int` `l1 = tree[2 * index + 1].f;``    ``int` `l2 = tree[2 * index + 1].s;``    ``int` `r1 = tree[2 * index + 2].f;``    ``int` `r2 = tree[2 * index + 2].s;``   ` `    ``// Set the maximum for this node as``    ``// maximum of l1 and r1``    ``tree[index].f = Math.Max(l1, r1);``   ` `    ``// Set the second maximum for this``    ``// node as maximum of``    ``// Math.Min(l1, r1) & Math.Max(l2, r2)``    ``tree[index].s``        ``= Math.Max(Math.Min(l1, r1),``              ``Math.Max(l2, r2));``}``   ` `// Function to execute a``// query on the segment tree``static` `node runQuery(``    ``node []tree, ``int` `start,``    ``int` `end, ``int` `index,``    ``int` `L, ``int` `R)``{``    ``// If the range of``    ``// the node is completely``    ``// outside l and r then return 0``    ``if` `(R < start || L > end) {``        ``return` `new` `node( 0, 0 );``    ``}``   ` `    ``// If the range of the``    ``// node is within l and r``    ``// then return the value``    ``// of the present node``    ``if` `(L <= start && R >= end) {``        ``return` `tree[index];``    ``}``   ` `    ``// calculate mid value``    ``int` `mid = start + (end - start) / 2;``   ` `    ``// Recursively find first``    ``// max and second max from``    ``// the left half``    ``node Left``        ``= runQuery(``            ``tree, start,``            ``mid, 2 * index + 1,``            ``L, R);``   ` `    ``// Recursively find first``    ``// max and second max from``    ``// the right half``    ``node Right``        ``= runQuery(``            ``tree, mid + 1,``            ``end, 2 * index + 2,``            ``L, R);``   ` `    ``// Get the values``    ``// of l1, l2, r1, r2``    ``int` `l1 = Left.f;``    ``int` `l2 = Left.s;``    ``int` `r1 = Right.f;``    ``int` `r2 = Right.s;``   ` `    ``// return the maximum``    ``// as Math.Max(l1, r1), and``    ``// second maximum as``    ``// Math.Max(Math.Min(l1, r1), Math.Max(l2, r2))``    ``return` `new` `node( Math.Max(l1, r1),``             ``Math.Max(Math.Min(l1, r1),``                 ``Math.Max(l2, r2)) );``}``   ` `// Function to find the required sum``static` `void` `findSum(``int` `[]arr, ``int` `n,``             ``int` `Q, node []query)``{``   ` `    ``// Declare an array of``    ``// length '4 * n + 1' and``    ``// build the tree``    ``node []tree = ``new` `node[4 * n + 1];``    ``for``(``int` `i=0;i<4 * n + 1;i++) {``        ``tree[i] = ``new` `node();``    ``}``    ``build(arr, tree, 0, n - 1, 0);``   ` `    ``// Run a loop to iterate``    ``// over each query``    ``for` `(``int` `i = 0; i < Q; i++) {``   ` `        ``// Call the query function``        ``// with given range``        ``node temp``            ``= runQuery(``                ``tree, 0,``                ``n - 1, 0,``                ``query[i].f,``                ``query[i].s);``   ` `        ``// Store maximum and second``        ``// maximum in variables``        ``int` `f = temp.f;``        ``int` `s = temp.s;``   ` `        ``// Return sum of the maximum``        ``// and second maximum``        ``Console.Write((f + s) +``"\n"``);``    ``}``}``   ` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``// Given array and number of queries``    ``int` `[]arr = { 3, 4, 5, 6, 7, 8 };``    ``int` `Q = 2;``   ` `    ``int` `n = arr.Length;``   ` `    ``// Declare and define queries``    ``node []query = ``new` `node[Q];``    ``query = ``new` `node( 0, 3 );``    ``query = ``new` `node( 3, 5 );``   ` `    ``findSum(arr, n, Q, query);``}``}`` ` `// This code is contributed by Rajput-Ji`
Output:
```11
15
```

Performance Analysis:

• Time Complexity: In the above approach, we are building a segment tree which is of time complexity O(N) Then for each of Q queries, we find the solution in O(logN) time. So overall time complexity is O(N+Q*logN)
• Auxiliary Space Complexity: In the above approach, we are using extra space for storing the segment tree which is taking (4 * N + 1) space. So Auxiliary space complexity is O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up