#include <bits/stdc++.h>
#define ll long long int
#define ld long double
#define ull unsigned long long int
#define forn(i,n)for(ll i=0;i<(n);i++)
#define forn_rev(i,n)for(ll i=(n)-1;i>=0;i--)
#define for1n(i,n) for(ll i=1;i<=(n);i++)
#define ARRAY_SIZE(a) sizeof(a)/sizeof(*a)
#define MOD 1000000007
#define MAXN 100005

using namespace std;



int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);cout.tie(NULL);

    ll T=1;
    //cin>>T;
    while(T)
    {
        ll X;
        cin>>X;
        for(ll i=-1000;i<=1000;i++){
            for(ll j=-1000;j<=1000;j++){
                if(X==(pow(i,5)-pow(j,5)))
                {
                    cout<<i<<" "<<j;
                    return 0;
                }
            }
        }









    }



    return 0;
}



/*


struct data{

    ll count,index;

};

vector<ll> arr(10000);
vector<data> tmax(4*MAXN);



auto combine(data a,data b){
    //ultra based combine function for easier understanding
    data res=0;
    if(a>0) res.count++;
    if(b>0) res.count++
    return res;
}



void build(ll v,ll tl,ll tr)
{
    if(tl==tr)
    {

        tmax[v]=arr[tl];
        //leaf nodes
    }
    else
    {
        //store in array. Thus childs are 2*v and 2*v+1
        ll tm=(tl+tr)/2;//mid point
        build(2*v,tl,tm);//recurse to left sub tree
        build(2*v+1,tm+1,tr);//recurse to right tree
        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);
    }
}

auto getmax(ll v,ll tl,ll tr,ll l,ll r)
{
    if(r<tl || l>tr)
        return -1;//check if outside range
    if(l<=tl && tr<=r)
        return tmax[v];//in range then return that value

    ll tm=(tl+tr)/2;
    //recurse to left and right subtree
    ll left=getmax(2*v,tl,tm,l,r),right=getmax(2*v+1,tm+1,tr,l,r);
    return combine(left,right);
}

ll update(ll v,ll tl,ll tr,ll l,ll tr,ll val){
    if(l>r) return;
    if(l==tl && tr==r){
        if(tmax[v]>=0)
            tmax[v]+=val;//update tree leaves here
        else return -1;

    }
    else{
        ll tm=(tl+tr)/2;
        if(tl>=m)
        ll right=update(2*v+1,tm+1,tr,val);//recurse to right subtree
        if(right==-1) return -1;
        update(2*v,tl,tm,val);//recurse to left subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}
void pointupdate(ll v,ll tl,ll tr,ll pos,ll val){

    if(tl==tr){
        tmax[v]=make_data(val);//update tree leaves here

    }
    else{
        ll tm=(tl+tr)/2;
        if(pos<=tm) update(2*v,tl,tm,val);//recurse to left subtree
        else update(2*v+1,tm+1,tr,val);//recurse to right subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}


*/





/*


struct data{

    ll count,index;

};

vector<ll> arr(10000);
vector<data> tmax(4*MAXN);



auto combine(data a,data b){
    //ultra based combine function for easier understanding
    data res=0;
    if(a>0) res.count++;
    if(b>0) res.count++
    return res;
}



void build(ll v,ll tl,ll tr)
{
    if(tl==tr)
    {

        tmax[v]=arr[tl];
        //leaf nodes
    }
    else
    {
        //store in array. Thus childs are 2*v and 2*v+1
        ll tm=(tl+tr)/2;//mid point
        build(2*v,tl,tm);//recurse to left sub tree
        build(2*v+1,tm+1,tr);//recurse to right tree
        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);
    }
}

auto getmax(ll v,ll tl,ll tr,ll l,ll r)
{
    if(r<tl || l>tr)
        return -1;//check if outside range
    if(l<=tl && tr<=r)
        return tmax[v];//in range then return that value

    ll tm=(tl+tr)/2;
    //recurse to left and right subtree
    ll left=getmax(2*v,tl,tm,l,r),right=getmax(2*v+1,tm+1,tr,l,r);
    return combine(left,right);
}

ll update(ll v,ll tl,ll tr,ll l,ll tr,ll val){
    if(l>r) return;
    if(l==tl && tr==r){
        if(tmax[v]>=0)
            tmax[v]+=val;//update tree leaves here
        else return -1;

    }
    else{
        ll tm=(tl+tr)/2;
        if(tl>=m)
        ll right=update(2*v+1,tm+1,tr,val);//recurse to right subtree
        if(right==-1) return -1;
        update(2*v,tl,tm,val);//recurse to left subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}
void pointupdate(ll v,ll tl,ll tr,ll pos,ll val){

    if(tl==tr){
        tmax[v]=make_data(val);//update tree leaves here

    }
    else{
        ll tm=(tl+tr)/2;
        if(pos<=tm) update(2*v,tl,tm,val);//recurse to left subtree
        else update(2*v+1,tm+1,tr,val);//recurse to right subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}


*/





Measured memory_bytes: 4036