import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String originalStr = scan.nextLine();
StringBuffer sb = new StringBuffer("");
int sign = 0;
int start = 0;
char[] chrs = originalStr.toCharArray();
Queue<Character> queue = new LinkedList<>();
for (int i = 0; i < chrs.length; i++) {
char chr = chrs[i];
if ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z')) {
if (sign == 0) {
sign = 1;
start = i;
}
} else {
if (sign == 1) {
sign = 0;
sb.append(originalStr.substring(start, i));
}
queue.add(chr);
}
}
if (sign == 1) {
sb.append(originalStr.substring(start));
}
char[] newchrs = process(new String(sb)).toCharArray();
int index = 0;
StringBuffer ans = new StringBuffer("");
for (int i = 0; i < chrs.length; i++) {
char chr = chrs[i];
if ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z')) {
ans.append(newchrs[index++]);
} else {
ans.append(queue.poll());
}
}
System.out.println(ans);
}
public static String process(String str) {
char[] chrs = str.toCharArray();
// quickSort(chrs); // 快速排序具有不稳定性,所以不能使用
mergeSort(chrs); // 归并排序具有稳定性,因此我们选择它
StringBuffer sb = new StringBuffer("");
for (char chr : chrs) {
sb.append(chr);
}
return new String(sb);
}
/**********************************************************************************/
public static void quickSort(char[] chrs) {
if (null == chrs || chrs.length < 2) {
return;
}
sort(chrs, 0, chrs.length - 1);
}
public static void sort(char[] chrs, int start, int end) {
if (start >= end) {
return;
}
int l = start - 1;
int r = end + 1;
int p = start;
char compareChr = String.valueOf(chrs[end]).toLowerCase().charAt(0);
while (p < r) {
if (String.valueOf(chrs[p]).toLowerCase().charAt(0) < compareChr) {
swap(chrs, p++, ++l);
} else if (String.valueOf(chrs[p]).toLowerCase().charAt(0) > compareChr) {
swap(chrs, p, --r);
} else {
p++;
}
}
sort(chrs, start, l);
sort(chrs, r, end);
}
public static void swap(char[] chrs, int p1, int p2) {
char tmp = chrs[p1];
chrs[p1] = chrs[p2];
chrs[p2] = tmp;
}
/**********************************************************************************/
public static void mergeSort(char[] chrs) {
if (null == chrs || chrs.length < 2) {
return;
}
process1(chrs, 0, chrs.length - 1);
}
public static void process1(char[] chrs, int start, int end) {
if (start >= end) {
return;
}
int mid = start + ((end - start) >> 1);
process1(chrs, start, mid);
process1(chrs, mid + 1, end);
merge(chrs, start, mid, end);
}
public static void merge(char[] chrs, int start, int mid, int end) {
char[] helper = new char[end - start + 1];
int index = 0;
int p1 = start;
int p2 = mid + 1;
while (p1 <= mid && p2 <= end) {
helper[index++] = String.valueOf(chrs[p1]).toLowerCase().charAt(0) <= String.valueOf(chrs[p2]).toLowerCase().charAt(0) ? chrs[p1++] : chrs[p2++];
}
while (p1 <= mid) {
helper[index++] = chrs[p1++];
}
while (p2 <= end) {
helper[index++] = chrs[p2++];
}
for (int i = 0; i < helper.length; i++) {
chrs[start + i] = helper[i];
}
}
}