#include"bits/stdc++.h"
#define rep(i,n) for(ll i=0;i<n;++i)
#define ALL(x) x.begin(),x.end()
#define MOD 1000000007
#define INF INT_MAX
#define FLOAT_ANS setprecision(20)
#define elif else if

using namespace std;
typedef long long ll;
typedef unsigned long long ull;

//最大公約数
template<typename T>
T gcd(T a, T b) {
	if (a % b == 0) {
		return(b);
	}
	else {
		return(gcd(b, a % b));
	}
}

//最小公倍数
template<typename T>
T lcm(T a, T b) {
	return a / gcd(a, b) * b;
}

//Segment Tree(遅延評価)
template<typename T>
class SegTreeLazy {

	//参照：https://algo-logic.info/segment-tree/
public:
	//変数定義
	ll N;  //長さ
	T e; //単位元
	vector<T>seg; //基本
	vector<T>lazy; //遅延用
	function<T(T, T)> f; //比較用


	SegTreeLazy(ll n, ll e_, function<T(T, T)> f_) {
		//サイズ・単位元・比較用の関数
		e = e_;
		f = f_;

		//サイズnのSegTreeに必要な要素数
		ll x = 1;
		while (n > x) {
			x *= 2;
		}
		N = x;

		seg.resize(2 * N - 1, e);
		lazy.resize(2 * N - 1, e);
	}

	T get(ll i){
		return seg[i+N-1];
	}

	void eval(ll k) {
		//lazyから更新情報を取得、segに反映
		if (lazy[k] == e) return; //更新情報がなければ終了
		if (k < N - 1) { //自身が葉でないのなら子にも伝搬させる(zipを解凍)
			lazy[k * 2 + 1] = lazy[k];
			lazy[k * 2 + 2] = lazy[k];
		}

		//最後に、自身を更新
		seg[k] = lazy[k];
		//もう更新情報に用はないので、初期化
		lazy[k] = e;
	}

	void update(ll a, ll b, T x, ll k, ll l, ll r) {
		// a･b:全体の範囲
		// k･l:現在更新するn層目の範囲
		// x:更新する値
		// k:セグ木の配列における位置

		eval(k); //まずは更新(sudo apt update　と同じ感じ?)
		if (a <= l && r <= b) {// 内部にある(端でない)
			//現在の層についてのみ更新させる
			lazy[k] = x;
			eval(k);
		}
		else if (a < r && l < b) {// 一部区間がかぶる
			update(a, b, x, k * 2 + 1, l, (l + r) / 2); //右の子に伝搬
			update(a, b, x, k * 2 + 2, (l + r) / 2, r); //左の子に伝搬
			seg[k] = f(seg[k * 2 + 1], seg[k * 2 + 2]);
		}
	}
	void update(ll a, ll b, T x) {
		//(a)-(b-1)の範囲をxに更新
		update(a, b, x, 0, 0, N);
	}
	void update(ll a, T x) {
		//aをxに更新
		update(a, a + 1, x, 0, 0, N);
	}

	T query_sub(ll a, ll b, ll k, ll l, ll r) {
		eval(k);
		if (r <= a || b <= l) {  //完全に外部
			return e;
		}
		else if (a <= l && r <= b) {  //完全に内部
			return seg[k];
		}
		else {
			T vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
			T vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);

			return f(vl, vr); //右の子と左の子の小さい方
		}
	}
	T query(int a, int b) {
		return query_sub(a, b, 0, 0, N);
	}
};

bool isLarger(string s,string t){
	/*SのほうがTより大きければtrue*/
	rep(i,min(s.length(),t.length())){
		if(s[i]>t[i]){
			return true;
		}
		if(s[i]<t[i]){
			return false;
		}
	}

	if(s.length()>t.length()){
		return true;
	}
	else{
		return false;
	}
}

int main(void) {
  ll n;
  cin>>n;
  vector<ll>ans;
  for(ll i=1;i*i<=n;++i){
    if(n%i==0){
      ans.push_back(i);
      if(i!=n/i){
        ans.push_back(n/i);
      }
    }
  }
  
  sort(ALL(ans));
  for(ll i:ans){
    cout<<i<<endl;
  }
  
}


/*

*/


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;

//約数列挙
vector<ll> diviser_list(ll x){
    vector<ll> res;
    stack<ll> big;
    for(ll i = 2; i*i <= x; i++){
        if(x%i == 0){
            res.push_back(i);
            if(x/i != i)big.push(x/i);
        }
    }
    while(!big.empty()){
        res.push_back(big.top());
        big.pop();
    }
    res.push_back(x);
    return res;
}

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

    ll n;
    cin >> n;
    vector<ll> ans = diviser_list(n);
    if(n != 1) cout << 1 << endl;
    for(auto p:ans) cout << p << endl;
    return 0;
}