diff --git a/src/main/java/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.java b/src/main/java/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.java
index 952e869b3..d74e10d1a 100644
--- a/src/main/java/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.java
+++ b/src/main/java/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.java
@@ -7,7 +7,6 @@ public int minMoves(int sx, int sy, int tx, int ty) {
if (sx == 0 && sy == 0) {
return tx == 0 && ty == 0 ? 0 : -1;
}
-
int res = 0;
while (sx != tx || sy != ty) {
if (sx > tx || sy > ty) {
diff --git a/src/main/java/g3601_3700/s3612_process_string_with_special_operations_i/Solution.java b/src/main/java/g3601_3700/s3612_process_string_with_special_operations_i/Solution.java
new file mode 100644
index 000000000..56d45e07d
--- /dev/null
+++ b/src/main/java/g3601_3700/s3612_process_string_with_special_operations_i/Solution.java
@@ -0,0 +1,23 @@
+package g3601_3700.s3612_process_string_with_special_operations_i;
+
+// #Medium #String #Simulation #2025_07_14_Time_3_ms_(100.00%)_Space_54.53_MB_(100.00%)
+
+public class Solution {
+ public String processStr(String s) {
+ StringBuilder res = new StringBuilder();
+ for (char c : s.toCharArray()) {
+ if (c != '*' && c != '#' && c != '%') {
+ res.append(c);
+ } else if (c == '#') {
+ res.append(res);
+ } else if (c == '%') {
+ res.reverse();
+ } else {
+ if (!res.isEmpty()) {
+ res.deleteCharAt(res.length() - 1);
+ }
+ }
+ }
+ return res.toString();
+ }
+}
diff --git a/src/main/java/g3601_3700/s3612_process_string_with_special_operations_i/readme.md b/src/main/java/g3601_3700/s3612_process_string_with_special_operations_i/readme.md
new file mode 100644
index 000000000..078835f33
--- /dev/null
+++ b/src/main/java/g3601_3700/s3612_process_string_with_special_operations_i/readme.md
@@ -0,0 +1,119 @@
+3612\. Process String with Special Operations I
+
+Medium
+
+You are given a string `s` consisting of lowercase English letters and the special characters: `*`, `#`, and `%`.
+
+Build a new string `result` by processing `s` according to the following rules from left to right:
+
+* If the letter is a **lowercase** English letter append it to `result`.
+* A `'*'` **removes** the last character from `result`, if it exists.
+* A `'#'` **duplicates** the current `result` and **appends** it to itself.
+* A `'%'` **reverses** the current `result`.
+
+Return the final string `result` after processing all characters in `s`.
+
+**Example 1:**
+
+**Input:** s = "a#b%\*"
+
+**Output:** "ba"
+
+**Explanation:**
+
+`i`
+
+`s[i]`
+
+Operation
+
+Current `result`
+
+0
+
+`'a'`
+
+Append `'a'`
+
+`"a"`
+
+1
+
+`'#'`
+
+Duplicate `result`
+
+`"aa"`
+
+2
+
+`'b'`
+
+Append `'b'`
+
+`"aab"`
+
+3
+
+`'%'`
+
+Reverse `result`
+
+`"baa"`
+
+4
+
+`'*'`
+
+Remove the last character
+
+`"ba"`
+
+Thus, the final `result` is `"ba"`.
+
+**Example 2:**
+
+**Input:** s = "z\*#"
+
+**Output:** ""
+
+**Explanation:**
+
+`i`
+
+`s[i]`
+
+Operation
+
+Current `result`
+
+0
+
+`'z'`
+
+Append `'z'`
+
+`"z"`
+
+1
+
+`'*'`
+
+Remove the last character
+
+`""`
+
+2
+
+`'#'`
+
+Duplicate the string
+
+`""`
+
+Thus, the final `result` is `""`.
+
+**Constraints:**
+
+* `1 <= s.length <= 20`
+* `s` consists of only lowercase English letters and special characters `*`, `#`, and `%`.
\ No newline at end of file
diff --git a/src/main/java/g3601_3700/s3613_minimize_maximum_component_cost/Solution.java b/src/main/java/g3601_3700/s3613_minimize_maximum_component_cost/Solution.java
new file mode 100644
index 000000000..005eb1518
--- /dev/null
+++ b/src/main/java/g3601_3700/s3613_minimize_maximum_component_cost/Solution.java
@@ -0,0 +1,58 @@
+package g3601_3700.s3613_minimize_maximum_component_cost;
+
+// #Medium #Binary_Search #Graph #Union_Find #Sort
+// #2025_07_14_Time_37_ms_(100.00%)_Space_88.50_MB_(98.52%)
+
+public class Solution {
+ public int minCost(int ui, int[][] pl, int zx) {
+ int rt = 0;
+ int gh = 0;
+ int i = 0;
+ while (i < pl.length) {
+ gh = Math.max(gh, pl[i][2]);
+ i++;
+ }
+ while (rt < gh) {
+ int ty = rt + (gh - rt) / 2;
+ if (dfgh(ui, pl, ty, zx)) {
+ gh = ty;
+ } else {
+ rt = ty + 1;
+ }
+ }
+ return rt;
+ }
+
+ private boolean dfgh(int ui, int[][] pl, int jk, int zx) {
+ int[] wt = new int[ui];
+ int i = 0;
+ while (i < ui) {
+ wt[i] = i;
+ i++;
+ }
+ int er = ui;
+ i = 0;
+ while (i < pl.length) {
+ int[] df = pl[i];
+ if (df[2] > jk) {
+ i++;
+ continue;
+ }
+ int u = cvb(wt, df[0]);
+ int v = cvb(wt, df[1]);
+ if (u != v) {
+ wt[u] = v;
+ er--;
+ }
+ i++;
+ }
+ return er <= zx;
+ }
+
+ private int cvb(int[] wt, int i) {
+ for (; wt[i] != i; i = wt[i]) {
+ wt[i] = wt[wt[i]];
+ }
+ return i;
+ }
+}
diff --git a/src/main/java/g3601_3700/s3613_minimize_maximum_component_cost/readme.md b/src/main/java/g3601_3700/s3613_minimize_maximum_component_cost/readme.md
new file mode 100644
index 000000000..5d697cdbf
--- /dev/null
+++ b/src/main/java/g3601_3700/s3613_minimize_maximum_component_cost/readme.md
@@ -0,0 +1,47 @@
+3613\. Minimize Maximum Component Cost
+
+Medium
+
+You are given an undirected connected graph with `n` nodes labeled from 0 to `n - 1` and a 2D integer array `edges` where edges[i] = [ui, vi, wi]
denotes an undirected edge between node ui
and node vi
with weight wi
, and an integer `k`.
+
+You are allowed to remove any number of edges from the graph such that the resulting graph has **at most** `k` connected components.
+
+The **cost** of a component is defined as the **maximum** edge weight in that component. If a component has no edges, its cost is 0.
+
+Return the **minimum** possible value of the **maximum** cost among all components **after such removals**.
+
+**Example 1:**
+
+**Input:** n = 5, edges = [[0,1,4],[1,2,3],[1,3,2],[3,4,6]], k = 2
+
+**Output:** 4
+
+**Explanation:**
+
+
+
+* Remove the edge between nodes 3 and 4 (weight 6).
+* The resulting components have costs of 0 and 4, so the overall maximum cost is 4.
+
+**Example 2:**
+
+**Input:** n = 4, edges = [[0,1,5],[1,2,5],[2,3,5]], k = 1
+
+**Output:** 5
+
+**Explanation:**
+
+
+
+* No edge can be removed, since allowing only one component (`k = 1`) requires the graph to stay fully connected.
+* That single component’s cost equals its largest edge weight, which is 5.
+
+**Constraints:**
+
+* 1 <= n <= 5 * 104
+* 0 <= edges.length <= 105
+* `edges[i].length == 3`
+* 0 <= ui, vi < n
+* 1 <= wi <= 106
+* `1 <= k <= n`
+* The input graph is connected.
\ No newline at end of file
diff --git a/src/main/java/g3601_3700/s3614_process_string_with_special_operations_ii/Solution.java b/src/main/java/g3601_3700/s3614_process_string_with_special_operations_ii/Solution.java
new file mode 100644
index 000000000..133a8a221
--- /dev/null
+++ b/src/main/java/g3601_3700/s3614_process_string_with_special_operations_ii/Solution.java
@@ -0,0 +1,40 @@
+package g3601_3700.s3614_process_string_with_special_operations_ii;
+
+// #Hard #String #Simulation #2025_07_14_Time_33_ms_(100.00%)_Space_50.49_MB_(100.00%)
+
+public class Solution {
+ public char processStr(String s, long k) {
+ long len = 0;
+ for (char c : s.toCharArray()) {
+ if (Character.isLowerCase(c)) {
+ len++;
+ } else if (c == '*' && len > 0) {
+ len--;
+ } else if (c == '#') {
+ len *= 2;
+ }
+ }
+ if (k >= len) {
+ return '.';
+ }
+ for (int i = s.length() - 1; i >= 0; i--) {
+ char c = s.charAt(i);
+ if (Character.isLowerCase(c)) {
+ if (k == len - 1) {
+ return c;
+ }
+ len--;
+ } else if (c == '*') {
+ len++;
+ } else if (c == '#') {
+ len /= 2;
+ if (k >= len) {
+ k -= len;
+ }
+ } else if (c == '%') {
+ k = len - 1 - k;
+ }
+ }
+ return '.';
+ }
+}
diff --git a/src/main/java/g3601_3700/s3614_process_string_with_special_operations_ii/readme.md b/src/main/java/g3601_3700/s3614_process_string_with_special_operations_ii/readme.md
new file mode 100644
index 000000000..e2adf61aa
--- /dev/null
+++ b/src/main/java/g3601_3700/s3614_process_string_with_special_operations_ii/readme.md
@@ -0,0 +1,76 @@
+3614\. Process String with Special Operations II
+
+Hard
+
+You are given a string `s` consisting of lowercase English letters and the special characters: `'*'`, `'#'`, and `'%'`.
+
+You are also given an integer `k`.
+
+Build a new string `result` by processing `s` according to the following rules from left to right:
+
+* If the letter is a **lowercase** English letter append it to `result`.
+* A `'*'` **removes** the last character from `result`, if it exists.
+* A `'#'` **duplicates** the current `result` and **appends** it to itself.
+* A `'%'` **reverses** the current `result`.
+
+Return the kth
character of the final string `result`. If `k` is out of the bounds of `result`, return `'.'`.
+
+**Example 1:**
+
+**Input:** s = "a#b%\*", k = 1
+
+**Output:** "a"
+
+**Explanation:**
+
+| i | s[i] | Operation | Current `result` |
+|---|-------|----------------------------|------------------|
+| 0 | `'a'` | Append `'a'` | `"a"` |
+| 1 | `'#'` | Duplicate `result` | `"aa"` |
+| 2 | `'b'` | Append `'b'` | `"aab"` |
+| 3 | `'%'` | Reverse `result` | `"baa"` |
+| 4 | `'*'` | Remove the last character | `"ba"` |
+
+The final `result` is `"ba"`. The character at index `k = 1` is `'a'`.
+
+**Example 2:**
+
+**Input:** s = "cd%#\*#", k = 3
+
+**Output:** "d"
+
+**Explanation:**
+
+| i | s[i] | Operation | Current `result` |
+|---|-------|----------------------------|------------------|
+| 0 | `'c'` | Append `'c'` | `"c"` |
+| 1 | `'d'` | Append `'d'` | `"cd"` |
+| 2 | `'%'` | Reverse `result` | `"dc"` |
+| 3 | `'#'` | Duplicate `result` | `"dcdc"` |
+| 4 | `'*'` | Remove the last character | `"dcd"` |
+| 5 | `'#'` | Duplicate `result` | `"dcddcd"` |
+
+The final `result` is `"dcddcd"`. The character at index `k = 3` is `'d'`.
+
+**Example 3:**
+
+**Input:** s = "z\*#", k = 0
+
+**Output:** "."
+
+**Explanation:**
+
+| i | s[i] | Operation | Current `result` |
+|---|-------|---------------------------|------------------|
+| 0 | `'z'` | Append `'z'` | `"z"` |
+| 1 | `'*'` | Remove the last character | `""` |
+| 2 | `'#'` | Duplicate the string | `""` |
+
+The final `result` is `""`. Since index `k = 0` is out of bounds, the output is `'.'`.
+
+**Constraints:**
+
+* 1 <= s.length <= 105
+* `s` consists of only lowercase English letters and special characters `'*'`, `'#'`, and `'%'`.
+* 0 <= k <= 1015
+* The length of `result` after processing `s` will not exceed 1015
.
\ No newline at end of file
diff --git a/src/main/java/g3601_3700/s3615_longest_palindromic_path_in_graph/Solution.java b/src/main/java/g3601_3700/s3615_longest_palindromic_path_in_graph/Solution.java
new file mode 100644
index 000000000..2b5473fe6
--- /dev/null
+++ b/src/main/java/g3601_3700/s3615_longest_palindromic_path_in_graph/Solution.java
@@ -0,0 +1,87 @@
+package g3601_3700.s3615_longest_palindromic_path_in_graph;
+
+// #Hard #String #Dynamic_Programming #Bit_Manipulation #Graph
+// #2025_07_14_Time_641_ms_(100.00%)_Space_88.48_MB_(100.00%)
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SuppressWarnings("java:S135")
+public class Solution {
+ public int maxLen(int n, int[][] edges, String labelsStr) {
+ char[] labels = labelsStr.toCharArray();
+ // collect lists of adjacent nodes
+ int[][] adj = adj(n, edges);
+ // size of int to store n bits bitmask
+ int bSize = 1 << n;
+ int[][][] cache = new int[n][n][bSize];
+ int maxLength = 0;
+ for (int i = 0; i < n; i++) {
+ // find palindromes of odd length (one node in the middle)
+ int localLength = findPalindrome(adj, labels, i, i, 0, cache);
+ maxLength = Math.max(maxLength, localLength);
+ // find palindromes of even length (two nodes in the middle)
+ for (int j : adj[i]) {
+ if (labels[i] == labels[j]) {
+ int length = findPalindrome(adj, labels, i, j, 0, cache);
+ maxLength = Math.max(maxLength, length);
+ }
+ }
+ }
+ return maxLength;
+ }
+
+ private int findPalindrome(int[][] adj, char[] labels, int i, int j, int b, int[][][] cache) {
+ if (cache[i][j][b] != 0) {
+ return cache[i][j][b];
+ }
+ int b1 = set(b, i);
+ b1 = set(b1, j);
+ int length = i == j ? 1 : 2;
+ int maxExtraLength = 0;
+ for (int i1 : adj[i]) {
+ if (get(b1, i1)) {
+ continue;
+ }
+ for (int j1 : adj[j]) {
+ if (i1 == j1) {
+ continue;
+ }
+ if (labels[i1] != labels[j1]) {
+ continue;
+ }
+ if (get(b1, j1)) {
+ continue;
+ }
+ int extraLength = findPalindrome(adj, labels, i1, j1, b1, cache);
+ maxExtraLength = Math.max(maxExtraLength, extraLength);
+ }
+ }
+ cache[i][j][b] = length + maxExtraLength;
+ return length + maxExtraLength;
+ }
+
+ private boolean get(int b, int i) {
+ return (b & (1 << i)) != 0;
+ }
+
+ private int set(int b, int i) {
+ return b | (1 << i);
+ }
+
+ private int[][] adj(int n, int[][] edges) {
+ List> adjList = new ArrayList<>();
+ for (int i = 0; i < n; i++) {
+ adjList.add(new ArrayList<>());
+ }
+ for (int[] edge : edges) {
+ adjList.get(edge[0]).add(edge[1]);
+ adjList.get(edge[1]).add(edge[0]);
+ }
+ int[][] adj = new int[n][];
+ for (int i = 0; i < n; i++) {
+ adj[i] = adjList.get(i).stream().mapToInt(j -> j).toArray();
+ }
+ return adj;
+ }
+}
diff --git a/src/main/java/g3601_3700/s3615_longest_palindromic_path_in_graph/readme.md b/src/main/java/g3601_3700/s3615_longest_palindromic_path_in_graph/readme.md
new file mode 100644
index 000000000..b97e4d8dd
--- /dev/null
+++ b/src/main/java/g3601_3700/s3615_longest_palindromic_path_in_graph/readme.md
@@ -0,0 +1,61 @@
+3615\. Longest Palindromic Path in Graph
+
+Hard
+
+You are given an integer `n` and an **undirected** graph with `n` nodes labeled from 0 to `n - 1` and a 2D array `edges`, where edges[i] = [ui, vi]
indicates an edge between nodes ui
and vi
.
+
+You are also given a string `label` of length `n`, where `label[i]` is the character associated with node `i`.
+
+You may start at any node and move to any adjacent node, visiting each node **at most** once.
+
+Return the **maximum** possible length of a **palindrome** that can be formed by visiting a set of **unique** nodes along a valid path.
+
+**Example 1:**
+
+**Input:** n = 3, edges = [[0,1],[1,2]], label = "aba"
+
+**Output:** 3
+
+**Exp****lanation:**
+
+
+
+* The longest palindromic path is from node 0 to node 2 via node 1, following the path `0 → 1 → 2` forming string `"aba"`.
+* This is a valid palindrome of length 3.
+
+**Example 2:**
+
+**Input:** n = 3, edges = [[0,1],[0,2]], label = "abc"
+
+**Output:** 1
+
+**Explanation:**
+
+
+
+* No path with more than one node forms a palindrome.
+* The best option is any single node, giving a palindrome of length 1.
+
+**Example 3:**
+
+**Input:** n = 4, edges = [[0,2],[0,3],[3,1]], label = "bbac"
+
+**Output:** 3
+
+**Explanation:**
+
+
+
+* The longest palindromic path is from node 0 to node 1, following the path `0 → 3 → 1`, forming string `"bcb"`.
+* This is a valid palindrome of length 3.
+
+**Constraints:**
+
+* `1 <= n <= 14`
+* `n - 1 <= edges.length <= n * (n - 1) / 2`
+* edges[i] == [ui, vi]
+* 0 <= ui, vi <= n - 1
+* ui != vi
+* `label.length == n`
+* `label` consists of lowercase English letters.
+* There are no duplicate edges.
\ No newline at end of file
diff --git a/src/test/java/g3601_3700/s3612_process_string_with_special_operations_i/SolutionTest.java b/src/test/java/g3601_3700/s3612_process_string_with_special_operations_i/SolutionTest.java
new file mode 100644
index 000000000..80a611dc8
--- /dev/null
+++ b/src/test/java/g3601_3700/s3612_process_string_with_special_operations_i/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3601_3700.s3612_process_string_with_special_operations_i;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void processStr() {
+ assertThat(new Solution().processStr("a#b%*"), equalTo("ba"));
+ }
+
+ @Test
+ void processStr2() {
+ assertThat(new Solution().processStr("z*#"), equalTo(""));
+ }
+}
diff --git a/src/test/java/g3601_3700/s3613_minimize_maximum_component_cost/SolutionTest.java b/src/test/java/g3601_3700/s3613_minimize_maximum_component_cost/SolutionTest.java
new file mode 100644
index 000000000..42d050443
--- /dev/null
+++ b/src/test/java/g3601_3700/s3613_minimize_maximum_component_cost/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3601_3700.s3613_minimize_maximum_component_cost;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minCost() {
+ assertThat(
+ new Solution()
+ .minCost(5, new int[][] {{0, 1, 4}, {1, 2, 3}, {1, 3, 2}, {3, 4, 6}}, 2),
+ equalTo(4));
+ }
+
+ @Test
+ void minCost2() {
+ assertThat(
+ new Solution().minCost(4, new int[][] {{0, 1, 5}, {1, 2, 5}, {2, 3, 5}}, 1),
+ equalTo(5));
+ }
+}
diff --git a/src/test/java/g3601_3700/s3614_process_string_with_special_operations_ii/SolutionTest.java b/src/test/java/g3601_3700/s3614_process_string_with_special_operations_ii/SolutionTest.java
new file mode 100644
index 000000000..c62501833
--- /dev/null
+++ b/src/test/java/g3601_3700/s3614_process_string_with_special_operations_ii/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3601_3700.s3614_process_string_with_special_operations_ii;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void processStr() {
+ assertThat(new Solution().processStr("a#b%*", 1), equalTo('a'));
+ }
+
+ @Test
+ void processStr2() {
+ assertThat(new Solution().processStr("cd%#*#", 3), equalTo('d'));
+ }
+
+ @Test
+ void processStr3() {
+ assertThat(new Solution().processStr("z*#", 0), equalTo('.'));
+ }
+}
diff --git a/src/test/java/g3601_3700/s3615_longest_palindromic_path_in_graph/SolutionTest.java b/src/test/java/g3601_3700/s3615_longest_palindromic_path_in_graph/SolutionTest.java
new file mode 100644
index 000000000..6db82bfe4
--- /dev/null
+++ b/src/test/java/g3601_3700/s3615_longest_palindromic_path_in_graph/SolutionTest.java
@@ -0,0 +1,29 @@
+package g3601_3700.s3615_longest_palindromic_path_in_graph;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxLen() {
+ assertThat(new Solution().maxLen(3, new int[][] {{0, 1}, {1, 2}}, "aba"), equalTo(3));
+ }
+
+ @Test
+ void maxLen2() {
+ assertThat(new Solution().maxLen(3, new int[][] {{0, 1}, {0, 2}}, "abc"), equalTo(1));
+ }
+
+ @Test
+ void maxLen3() {
+ assertThat(
+ new Solution().maxLen(4, new int[][] {{0, 2}, {0, 3}, {3, 1}}, "bbac"), equalTo(3));
+ }
+
+ @Test
+ void maxLen4() {
+ assertThat(new Solution().maxLen(3, new int[][] {{2, 0}, {2, 1}}, "mll"), equalTo(2));
+ }
+}