#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#define popcount __builtin_popcountll
#define itmax(x) *max_element(x.begin(), x.end())
#define itmin(x) *min_element(x.begin(), x.end())
#define imax numeric_limits<int>::max()
#define ilowest numeric_limits<int>::lowest()
#define imin numeric_limits<int>::min()
#define dmax numeric_limits<double>::max()
#define dlowest numeric_limits<double>::lowest()
#define dmin numeric_limits<double>::min()
#define lmax numeric_limits<long long>::max()
#define llowest numeric_limits<long long>::lowest()
#define lmin numeric_limits<long long>::min()
#define hash __gnu_pbds::gp_hash_table
#define cast static_cast
#define endl '\n'
#define MAX 1001
using namespace std;
using namespace __gnu_pbds;
using iset=tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;
using lset=tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update>;
using sset=tree<string, null_type, less<string>, rb_tree_tag, tree_order_statistics_node_update>;
using iimap=__gnu_pbds::gp_hash_table<int, int>;
using llmap=__gnu_pbds::gp_hash_table<long long, long long>;
using ssmap=__gnu_pbds::gp_hash_table<string, string>;
using lsmap=__gnu_pbds::gp_hash_table<long long, string>;
using slmap=__gnu_pbds::gp_hash_table<string, long long>;
using dsmap=__gnu_pbds::gp_hash_table<double, string>;
using sdmap=__gnu_pbds::gp_hash_table<string, double>;
using stree=__gnu_pbds::trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update>;
using iip=pair<int, int>;
using llllp=pair<long long, long long>;
using sip=pair<string, int>;
using isp=pair<int, string>;
using sllp=pair<string, long long>;
using llsp=pair<long long, string>;
typedef long long ll;

template< typename Monoid >
struct SegmentTree {
  using F = function< Monoid(Monoid, Monoid) >;

  int sz;
  vector< Monoid > seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) {
    seg[k + sz] = x;
  }

  void build() {
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) L = f(L, seg[a++]);
      if(b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const {
    return seg[k + sz];
  }

  template< typename C >
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while(a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if(check(nxt)) a = 2 * a + type;
      else M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }


  template< typename C >
  int find_first(int a, const C &check) {
    Monoid L = M1;
    if(a <= 0) {
      if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) {
        Monoid nxt = f(L, seg[a]);
        if(check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template< typename C >
  int find_last(int b, const C &check) {
    Monoid R = M1;
    if(b >= sz) {
      if(check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for(b += sz; a < b; a >>= 1, b >>= 1) {
      if(b & 1) {
        Monoid nxt = f(seg[--b], R);
        if(check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};
set<vector<int>> CombiGenerate(const int base, const int digits)
{
    set<vector<int>> tmpSet;
    long long totalCases(pow(base, digits));
    for (long long i = 0; i < totalCases; i++)
    {
        vector<int> tmpVec;
        long long tmpValue = i;
        for (long long j = digits - 1; j >= 0; j--)
        {
            long long tmpCase = tmpValue / static_cast<long long>(pow(base, j));
            tmpVec.push_back(tmpCase);
            tmpValue -= static_cast<long long>(pow(base, j)) * tmpCase;
        }
        tmpSet.insert(tmpVec);
    }
    return tmpSet;
};

ll gcd(ll a, ll b)
{
    while (b != 0)
    {
        ll r = a%b;
        a = b;
        b = r;
    }
    return a;
}


array<array<int, MAX>, MAX> graph;
vector<bool> visited(MAX * MAX);

int main(int args, const char* argv[])
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    ll a, b;
    cin >> a >> b;
    cout << gcd(a, b) << endl;

    return 0;
}




Measured memory_bytes: 3332