diff --git a/src/main/java/g0301_0400/s0371_sum_of_two_integers/Solution.java b/src/main/java/g0301_0400/s0371_sum_of_two_integers/Solution.java
new file mode 100644
index 000000000..e9bab6987
--- /dev/null
+++ b/src/main/java/g0301_0400/s0371_sum_of_two_integers/Solution.java
@@ -0,0 +1,43 @@
+package g0301_0400.s0371_sum_of_two_integers;
+
+// #Medium #Top_Interview_Questions #Math #Bit_Manipulation
+
+public class Solution {
+ public int getSum(int a, int b) {
+ int ans = 0;
+ int memo = 0;
+ int exp = 0;
+ int count = 0;
+ while (count < 32) {
+ int val1 = a & 1;
+ int val2 = b & 1;
+ int val = sum(val1, val2, memo);
+ memo = val >> 1;
+ val = val & 1;
+ a = a >> 1;
+ b = b >> 1;
+ ans = ans | (val << exp);
+ exp = plusOne(exp);
+ count = plusOne(count);
+ }
+ return ans;
+ }
+
+ private int sum(int val1, int val2, int val3) {
+ int count = 0;
+ if (val1 == 1) {
+ count = plusOne(count);
+ }
+ if (val2 == 1) {
+ count = plusOne(count);
+ }
+ if (val3 == 1) {
+ count = plusOne(count);
+ }
+ return count;
+ }
+
+ private int plusOne(int val) {
+ return (-(~val));
+ }
+}
diff --git a/src/main/java/g0301_0400/s0371_sum_of_two_integers/readme.md b/src/main/java/g0301_0400/s0371_sum_of_two_integers/readme.md
new file mode 100644
index 000000000..81dab08d5
--- /dev/null
+++ b/src/main/java/g0301_0400/s0371_sum_of_two_integers/readme.md
@@ -0,0 +1,21 @@
+371\. Sum of Two Integers
+
+Medium
+
+Given two integers `a` and `b`, return _the sum of the two integers without using the operators_ `+` _and_ `-`.
+
+**Example 1:**
+
+**Input:** a = 1, b = 2
+
+**Output:** 3
+
+**Example 2:**
+
+**Input:** a = 2, b = 3
+
+**Output:** 5
+
+**Constraints:**
+
+* `-1000 <= a, b <= 1000`
\ No newline at end of file
diff --git a/src/main/java/g0301_0400/s0372_super_pow/Solution.java b/src/main/java/g0301_0400/s0372_super_pow/Solution.java
new file mode 100644
index 000000000..8c0f3a240
--- /dev/null
+++ b/src/main/java/g0301_0400/s0372_super_pow/Solution.java
@@ -0,0 +1,70 @@
+package g0301_0400.s0372_super_pow;
+
+// #Medium #Math #Divide_and_Conquer
+
+public class Solution {
+ private static final int MOD = 1337;
+
+ public int superPow(int a, int[] b) {
+ int phi = phi(MOD);
+ int arrMod = arrMod(b, phi);
+ if (isGreaterOrEqual(b, phi)) {
+ // Cycle has started
+ // cycle starts at phi with length phi
+ return exp(a % MOD, phi + arrMod);
+ }
+ return exp(a % MOD, arrMod);
+ }
+
+ private int phi(int n) {
+ float result = n;
+ for (int p = 2; p * p <= n; p++) {
+ if (n % p > 0) {
+ continue;
+ }
+ while (n % p == 0) {
+ n /= p;
+ }
+ result *= 1.0 - 1.0 / p;
+ }
+ if (n > 1) {
+ // if starting n was also prime (so it was greater than sqrt(n))
+ result *= (1.0 - (1.0 / n));
+ }
+ return (int) result;
+ }
+
+ // Returns true if number in array is greater than integer named phi
+ private boolean isGreaterOrEqual(int[] b, int phi) {
+ int cur = 0;
+ for (int j : b) {
+ cur = cur * 10 + j;
+ if (cur >= phi) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Returns number in array mod phi
+ private int arrMod(int[] b, int phi) {
+ int res = 0;
+ for (int j : b) {
+ res = (res * 10 + j) % phi;
+ }
+ return res;
+ }
+
+ // Binary exponentiation
+ private int exp(int a, int b) {
+ int y = 1;
+ while (b > 0) {
+ if (b % 2 == 1) {
+ y = (y * a) % MOD;
+ }
+ a = (a * a) % MOD;
+ b /= 2;
+ }
+ return y;
+ }
+}
diff --git a/src/main/java/g0301_0400/s0372_super_pow/readme.md b/src/main/java/g0301_0400/s0372_super_pow/readme.md
new file mode 100644
index 000000000..ba238dbb5
--- /dev/null
+++ b/src/main/java/g0301_0400/s0372_super_pow/readme.md
@@ -0,0 +1,36 @@
+372\. Super Pow
+
+Medium
+
+Your task is to calculate ab
mod `1337` where `a` is a positive integer and `b` is an extremely large positive integer given in the form of an array.
+
+**Example 1:**
+
+**Input:** a = 2, b = \[3\]
+
+**Output:** 8
+
+**Example 2:**
+
+**Input:** a = 2, b = \[1,0\]
+
+**Output:** 1024
+
+**Example 3:**
+
+**Input:** a = 1, b = \[4,3,3,8,5,2\]
+
+**Output:** 1
+
+**Example 4:**
+
+**Input:** a = 2147483647, b = \[2,0,0\]
+
+**Output:** 1198
+
+**Constraints:**
+
+* 1 <= a <= 231 - 1
+* `1 <= b.length <= 2000`
+* `0 <= b[i] <= 9`
+* `b` doesn't contain leading zeros.
\ No newline at end of file
diff --git a/src/main/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/Solution.java b/src/main/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/Solution.java
new file mode 100644
index 000000000..41de813e8
--- /dev/null
+++ b/src/main/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/Solution.java
@@ -0,0 +1,41 @@
+package g0301_0400.s0373_find_k_pairs_with_smallest_sums;
+
+// #Medium #Array #Heap_Priority_Queue
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.PriorityQueue;
+
+public class Solution {
+ private static class Node {
+ long sum;
+ List al;
+ int index;
+
+ Node(int index, int num1, int num2) {
+ this.sum = (long) num1 + (long) num2;
+ this.al = new ArrayList<>();
+ this.al.add(num1);
+ this.al.add(num2);
+ this.index = index;
+ }
+ }
+
+ public List> ksmallestPairs(int[] nums1, int[] nums2, int k) {
+ PriorityQueue queue = new PriorityQueue<>((a, b) -> a.sum < b.sum ? -1 : 1);
+ List> res = new ArrayList<>();
+ for (int i = 0; i < nums1.length && i < k; i++) {
+ queue.add(new Node(0, nums1[i], nums2[0]));
+ }
+ for (int i = 1; i <= k && !queue.isEmpty(); i++) {
+ Node cur = queue.poll();
+ res.add(cur.al);
+ int next = cur.index;
+ int lastNum1 = cur.al.get(0);
+ if (next + 1 < nums2.length) {
+ queue.add(new Node(next + 1, lastNum1, nums2[next + 1]));
+ }
+ }
+ return res;
+ }
+}
diff --git a/src/main/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/readme.md b/src/main/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/readme.md
new file mode 100644
index 000000000..5b46a8862
--- /dev/null
+++ b/src/main/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/readme.md
@@ -0,0 +1,40 @@
+373\. Find K Pairs with Smallest Sums
+
+Medium
+
+You are given two integer arrays `nums1` and `nums2` sorted in **ascending order** and an integer `k`.
+
+Define a pair `(u, v)` which consists of one element from the first array and one element from the second array.
+
+Return _the_ `k` _pairs_ (u1, v1), (u2, v2), ..., (uk, vk)
_with the smallest sums_.
+
+**Example 1:**
+
+**Input:** nums1 = \[1,7,11\], nums2 = \[2,4,6\], k = 3
+
+**Output:** \[\[1,2\],\[1,4\],\[1,6\]\]
+
+**Explanation:** The first 3 pairs are returned from the sequence: \[1,2\],\[1,4\],\[1,6\],\[7,2\],\[7,4\],\[11,2\],\[7,6\],\[11,4\],\[11,6\]
+
+**Example 2:**
+
+**Input:** nums1 = \[1,1,2\], nums2 = \[1,2,3\], k = 2
+
+**Output:** \[\[1,1\],\[1,1\]\]
+
+**Explanation:** The first 2 pairs are returned from the sequence: \[1,1\],\[1,1\],\[1,2\],\[2,1\],\[1,2\],\[2,2\],\[1,3\],\[1,3\],\[2,3\]
+
+**Example 3:**
+
+**Input:** nums1 = \[1,2\], nums2 = \[3\], k = 3
+
+**Output:** \[\[1,3\],\[2,3\]\]
+
+**Explanation:** All possible pairs are returned from the sequence: \[1,3\],\[2,3\]
+
+**Constraints:**
+
+* 1 <= nums1.length, nums2.length <= 105
+* -109 <= nums1[i], nums2[i] <= 109
+* `nums1` and `nums2` both are sorted in **ascending order**.
+* `1 <= k <= 1000`
\ No newline at end of file
diff --git a/src/test/java/g0301_0400/s0371_sum_of_two_integers/SolutionTest.java b/src/test/java/g0301_0400/s0371_sum_of_two_integers/SolutionTest.java
new file mode 100644
index 000000000..56873ca7b
--- /dev/null
+++ b/src/test/java/g0301_0400/s0371_sum_of_two_integers/SolutionTest.java
@@ -0,0 +1,18 @@
+package g0301_0400.s0371_sum_of_two_integers;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void getSum() {
+ assertThat(new Solution().getSum(1, 2), equalTo(3));
+ }
+
+ @Test
+ void getSum2() {
+ assertThat(new Solution().getSum(2, 3), equalTo(5));
+ }
+}
diff --git a/src/test/java/g0301_0400/s0372_super_pow/SolutionTest.java b/src/test/java/g0301_0400/s0372_super_pow/SolutionTest.java
new file mode 100644
index 000000000..b075c7e14
--- /dev/null
+++ b/src/test/java/g0301_0400/s0372_super_pow/SolutionTest.java
@@ -0,0 +1,28 @@
+package g0301_0400.s0372_super_pow;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void superPow() {
+ assertThat(new Solution().superPow(2, new int[] {3}), equalTo(8));
+ }
+
+ @Test
+ void superPow2() {
+ assertThat(new Solution().superPow(2, new int[] {1, 0}), equalTo(1024));
+ }
+
+ @Test
+ void superPow3() {
+ assertThat(new Solution().superPow(1, new int[] {4, 3, 3, 8, 5, 2}), equalTo(1));
+ }
+
+ @Test
+ void superPow4() {
+ assertThat(new Solution().superPow(2147483647, new int[] {2, 0, 0}), equalTo(1198));
+ }
+}
diff --git a/src/test/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/SolutionTest.java b/src/test/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/SolutionTest.java
new file mode 100644
index 000000000..8af778707
--- /dev/null
+++ b/src/test/java/g0301_0400/s0373_find_k_pairs_with_smallest_sums/SolutionTest.java
@@ -0,0 +1,36 @@
+package g0301_0400.s0373_find_k_pairs_with_smallest_sums;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void ksmallestPairs() {
+ assertThat(
+ new Solution().ksmallestPairs(new int[] {1, 7, 11}, new int[] {2, 4, 6}, 3),
+ equalTo(
+ new ArrayList<>(
+ Arrays.asList(
+ Arrays.asList(1, 2),
+ Arrays.asList(1, 4),
+ Arrays.asList(1, 6)))));
+ }
+
+ @Test
+ void ksmallestPairs2() {
+ assertThat(
+ new Solution().ksmallestPairs(new int[] {1, 1, 2}, new int[] {1, 2, 3}, 2),
+ equalTo(new ArrayList<>(Arrays.asList(Arrays.asList(1, 1), Arrays.asList(1, 1)))));
+ }
+
+ @Test
+ void ksmallestPairs3() {
+ assertThat(
+ new Solution().ksmallestPairs(new int[] {1, 2}, new int[] {3}, 3),
+ equalTo(new ArrayList<>(Arrays.asList(Arrays.asList(1, 3), Arrays.asList(2, 3)))));
+ }
+}