/*
 * sort函数的使用。先把输入的字符串全部转为小写,大写转小写的信息和对应下标信息记录到对应的结构体中。
 * 对结构体采用sort排序,并且下标小的还排到前面。
 * 最后输出时按原先的字符串输出,若原字符串buf1[i]为字符则buf2输出一个字符,否则buf1输出buf1[i]
 */
#include "stdio.h"
#include "algorithm"
#include "string"
using namespace std;
struct NodeChar{
    int value;
    int pos;
    int flag;//为1表明有大写变小写的,为2表明大小写没变
};
int charJudge(char c){
    if (c >= 'a' && c <= 'z')
        return 1;//小写字母
    if (c >= 'A' && c <= 'Z')
        return 2;//大写字母
    return 3;//非字母
}

bool cmp(NodeChar node1,NodeChar node2){
    if (node1.value < node2.value)
        return true;//不交换
    else if (node1.value == node2.value){
        if (node1.pos < node2.pos)
            return true;
        else
            return false;
    }
    return false;
}

int main(){
    char buf1[1000];NodeChar buf2[1000];
    while (fgets(buf1,1000,stdin)!=NULL){
        string str = buf1;
        str.pop_back();int j = 0;
        for (int i = 0; i < str.size(); ++i) {//构造纯字符数组
            if (charJudge(buf1[i]) != 3){
                buf2[j].pos = i;
                if (charJudge(buf1[i]) == 2){//大写字母变成小写的值
                    buf2[j].value = buf1[i] + 32;
                    buf2[j].flag = 1;
                }
                else{
                    buf2[j].value = buf1[i];
                    buf2[j].flag = 2;
                }
                ++j;
            }
        }
        sort(buf2,buf2+j, cmp);
        for (int i = 0,j=0; i < str.size(); ++i) {
            if (charJudge(buf1[i]) == 3){
                printf("%c",buf1[i]);
            } else{
                if (buf2[j].flag == 1){
                    printf("%c",buf2[j].value-32);//再转回大写去
                } else{
                    printf("%c",buf2[j].value);
                }
                ++j;
            }
        }
        printf("\n");
    }
}